Skip to content

Add find_writable_directories to Msf::Post::File#21232

Open
bcoles wants to merge 1 commit intorapid7:masterfrom
bcoles:file-find_writable_directories
Open

Add find_writable_directories to Msf::Post::File#21232
bcoles wants to merge 1 commit intorapid7:masterfrom
bcoles:file-find_writable_directories

Conversation

@bcoles
Copy link
Copy Markdown
Contributor

@bcoles bcoles commented Apr 4, 2026

Add a method to discover writable directories on Unix targets using the find command. This is useful in post-exploitation scenarios where a module needs to locate a writable staging path.

Parameters:

  • path: base directory to search (default: /)
  • max_depth: find -maxdepth limit (default: 2)
  • timeout: seconds before killing the remote process (default: 15)
  • user/group: filter by owner and/or group with -perm checks

The method uses a three-tier strategy to prevent a long-running find from tying up the session's shell channel:

  1. GNU coreutils timeout - wraps the find command directly
  2. perl alarm() - fallback for BSD, macOS, and Solaris targets
  3. When neither is available, max_depth is capped at 1 and a warning is emitted to alert the operator

The remote timeout deadline is set 5 seconds shorter than the cmd_exec deadline so the server-side kill fires first and partial results are still collected.

Raises on Windows sessions. Returns an array of absolute paths, or nil on failure. Non-absolute lines (e.g. find error messages) are filtered from the output.

Add a method to discover writable directories on Unix targets using the
`find` command. This is useful in post-exploitation scenarios where a
module needs to locate a writable staging path.

Parameters:
- path: base directory to search (default: /)
- max_depth: find -maxdepth limit (default: 2)
- timeout: seconds before killing the remote process (default: 15)
- user/group: filter by owner and/or group with -perm checks

The method uses a three-tier strategy to prevent a long-running find
from tying up the session's shell channel:

1. GNU coreutils `timeout` - wraps the find command directly
2. `perl` alarm() - fallback for BSD, macOS, and Solaris targets
3. When neither is available, max_depth is capped at 1 and a warning
   is emitted to alert the operator

The remote timeout deadline is set 5 seconds shorter than the cmd_exec
deadline so the server-side kill fires first and partial results are
still collected.

Raises on Windows sessions. Returns an array of absolute paths, or nil
on failure. Non-absolute lines (e.g. find error messages) are filtered
from the output.
@bcoles
Copy link
Copy Markdown
Contributor Author

bcoles commented Apr 4, 2026

Broken tests are not my fault.

if timeout > 0
if command_exists?('timeout')
# GNU coreutils timeout - common on Linux
cmd = "timeout #{timeout} #{find_cmd}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Busybox' timeout is using timeout [-t SECS] [-s SIG] PROG ARGS :/

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than over-complicate it by trying to figure out which version of timeout is available, it may simply be better to strip out all the timeout/perl handling, pass the timeout argument to cmd_exec and print a warning if the depth is > 2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

3 participants