Scan websites for LFI vulnerabilities and path traversals.
The speed of multithreading, with all the precision you'll need
Alfie is used in three steps:
filter
mode: Determine your HTTP status code (-fc
), response word count (-fw
), and response size (-fs
) filtersscan
mode: Attempt to find one valid path traversal (+/- encoding, +/- bypasses) to one of the test files. Success is determined by the filters from the first step.enum
mode: Given the example LFI from a successful run ofscan
mode, try to find as many files as possible
I'll use the HackTheBox lab Download as an example in the following sections. Spoiler alert!
⚠️
Run Alfie in filter mode to have it try to determine the best filters to use. It fires a bunch of random test payloads at the target (not actual filepaths, just random data) and reads the responses, building a simple statistical model of how the server responded.
☝️ Alfie attempts to find filter values that will eliminate responses within two standard deviations of the mean.
The filters that Alfie calculates can be used for the subsequent scan
and enum
modes.
python3 alfie.py -u "http://download.htb/files/download/" --threads 50 filter
You should be able to just copy-paste the green text for scan
and enum
mode 🙂
The filters we determined in filter
mode become the metric for "success" in scan
and enum
mode.
Any combination of HTTP status codes (
-fs
), word counts (-fw
), and response sizes (-fs
) can be used as filters.If it's convenient, you can even uses ranges and comma-separated lists, like
-fw 12-14,166
❤️
If you already know a little about your target, it's helpful to specify tags for it. In the next example, we already know that the target is a Linux server running NodeJS. We also know that it's likely we'll find relative filepaths:
💡 Knowing a bit about your target will vastly improve your scan speeds!
python3 alfie.py -u "http://download.htb/files/download/" --max 1 --target_system 'linux,node' --threads 50 -fc '404' -fw '12,13,14,166' scan -rel
If successful, scan
mode will report the first success it achieves. Copy the green, bold text in the output for use in enum
mode.
Enumeration mode is when we get a list of files accessible on the target. All you need to do is provide the -ex
or --example-lfi
parameter to scan mode.
⚠️ Since the--example-lfi
argument is required for enum mode, you must specify it after the positional argument "enum"
python3 alfie.py -u "http://download.htb/files/download/" --max 1 --target_system 'linux,node' --threads 50 -fc '404' -fw '12,13,14,166' enum --example-lfi '..%2fapp.js'
For logging of your results, use the -o
or --output
argument. The output is a text file with one positive result per line, and can be easily read by other scripts or programs. Here is a sample:
http://download.htb/files/download/%2e%2e%2fpackage.json
http://download.htb/files/download/%2e%2e%2fapp.js
http://download.htb/files/download/..%2fapp.js
http://download.htb/files/download/..%2fpackage.json
By default, Alfie will output any non-default options you provide as arguments:
You can suppress this behavior and hide the banner with the -q
or --quiet
flag (in case you want to pipe the output to another program).
Argument | Description |
---|---|
{filter,scan,enum,batch} |
Mode of operation. |
filter |
Attempt to establish a baseline of which responses should be filtered. The most likely filters will be suggested. |
scan |
Find a valid path traversal. The program will make requests using various traversals until at least one non-relative filepath is found. |
enum |
Use a known path traversal, and try to enumerate files on the target system. If possible, attempts will be made to gain RCE. |
batch |
Automatically run "filter" mode, then "scan" mode, then "enum" mode. |
Argument | Description |
---|---|
-h, --help |
Show this help message and exit. |
-u URL, --url URL |
Base URL of the target. Ex. "http://mywebsite.tld/index.php?page=". |
Affect the way that Alfie looks.
Argument | Description |
---|---|
--version |
Show program's version number and exit. |
-v, --verbose |
Show extra output to console. Does not affect log file verbosity. |
--no-color |
Don't ANSI color escapes in console output. |
--quiet |
Don't print the banner or options. |
-o OUTPUT, --output OUTPUT |
File to log positive results. |
Affect the bounds and method of traversal.
Argument | Description |
---|---|
--min MIN |
Minimum number of steps "back" to traverse. |
--max MAX |
Maximum number of steps "back" to traverse. |
Affect how requests are sent to the target.
Argument | Description |
---|---|
--target_system TARGET_SYSTEM |
List of attributes of the target system, to help choose what files to check for. No spaces. Ex "linux,php". Choose attributes from this list: any, windows, ruby, rails, xampp, apache, python, js, node, nginx, php, linux. |
-t THREADS, --threads THREADS |
Number of threads to use for processing. |
--timeout TIMEOUT |
Timeout for each request (in seconds). |
-X REQUEST_TYPE, --request-type REQUEST_TYPE |
Type of HTTP request to use. Ex "POST". |
-b COOKIES, --cookies COOKIES |
Cookies to include in each request. Ex "key1=value1; key2=value2" (Tip: use document.cookie in browser console). |
-H HEADERS, --headers HEADERS |
Extra headers to include in each request. Use semicolons as a separator. Ex "Host: 4wayhandshake.test.tld; Authorization: Bearer 23456.hgfds.234567890". |
-d DATA, --data DATA |
Data to include in each request. Only applies if using a POST request (see -X option). Ex "key1=value1; key2=value2". |
Affect how responses are received and processed.
Argument | Description |
---|---|
-fs FILTER_SIZES, --filter-sizes FILTER_SIZES |
Comma-separated list of sizes (in bytes) to filter from the results. |
-fw FILTER_WORDS, --filter-words FILTER_WORDS |
Comma-separated list of word counts to filter from the results. |
-fc FILTER_CODES, --filter-codes FILTER_CODES |
Comma-separated list of HTTP status codes to filter from the results. |
Argument | Description |
---|---|
-rel, --relative-only |
Only use relative paths in scan mode. Great for finding files like package.json (Defaults to false when not specified). |
Argument | Description |
---|---|
-ex EXAMPLE_LFI, --example-lfi EXAMPLE_LFI |
Example of a traversal that successfully discloses a local file (the bold part of the output of "scan" mode). Ex. /../../../etc/passwd . |
-nx, --no-extra-tests |
Don't run the extra LFI tests (only useful for WAF evasion). |
- 1.0.0:
- Runs successfully. Mimics behaviour of my LFI-Enumerator bash script.
- 1.1.0:
- Add a
-o
switch to output results to a file. - Include a banner with all non-default options shown
- Add a
- 1.2.0:
- Improve parsing of arguments
--cookie
and--data
so that it uses browser-like formatting.
- Improve parsing of arguments
- 1.3.0:
- Added "extra checks" mechanism to automate tests for things like insecure PHP modules
- Started using semantic versioning
- Updated README and
--help
to include--no-extra-checks
and--version
- 1.3.1:
- Added additional "extra checks" for other types of LFIs
- Replaced
--ending
option with--no-ending-checks
: it now checks for null-byte termination by default.
- 2.0.0:
- Huge rewrite. Split everything into
filter
,scan
andenum
mode. Left a stub forbatch
mode where all three other modes are completed sequentially. - Overhauled the way that path traversals are generated, making the whole process a lot more hands-off by default.
- Greatly improved the degree of control over requests, and how things get scanned.
- Hueristic-based filter suggestion during
filter
mode means you no longer need to run it in verbose initially - Early exit during
scan
mode, so that we only attempt to find one successful LFI, then use that pattern to enumerate - Added an accompanying
file-list.json
that controls which files are used for scanning vs enumeration - Added the ability to include regex-powered variables within the filepaths listed in
file-list.json
- Huge rewrite. Split everything into
- 2.1.0:
- Added progress spinner
- Included the ability to specify custom request headers (not just cookies)
- You can now
scan
for only the relative-filepath targets (good for finding stuff likepackage.json
instead of/etc/passwd
) - Amended this README to show new options/args
- 2.2.0:
- Enum mode now dumps files into ./output directory
- After enum mode is finished, user may manually check for files using a console-style prompt
- Figure out why extra tests aren't working
- Log errors to a log file instead of the screen
- Separate out the PHP-only tests.
- Encoding mutations should apply to the whole payload, not just the traversal
- Add
batch
mode: wherefilter
leads intoscan
which leads intoenum
. - Add interactive
enum
mode, that allows you to just drop into a prompt where you can request specific files if you'd rather. - Allow dumping all file contents acquired in
enum
mode into some kind of output directory. - Make the whole view a little wider (nobody's using this on their phone 😅)
Please ⭐ this repo if you found it useful!
Enjoy,
🤝🤝🤝🤝 @4wayhandshake