Hacking web applications can sometimes be challenging due to the sheer amount of moving parts they possess. At the core of these apps are HTTP requests and parameters, but these things are often concealed from the user, due to security reasons, convenience, or both. However, a tool called Arjun can be used to discover hidden HTTP parameters in web apps.
HTTP parameters, sometimes called query strings, are the part of a URL that takes user input and relays it to the web app. A typical example will look something like:
http://example.com/name?id=1
When the server receives the request, it will process the query and return a name with the ID of 1. Sometimes, such as in web forms, multiple fields will be submitted as the query string. Typically, it will look something like:
http://example.com/form?field1=v1&field2=v2
In certain cases, some of these parameters might be hidden from view. For example, if a hidden parameter of admin was set to True, there might be different functionality than that of a regular user.
Arjun is a command-line tool that finds hidden HTTP parameters using a wordlist of parameter names. It features multi-threading, rate limit handling, and allows custom headers to be added to requests. It also supports GET, POST, and JSON methods, making it a valuable resource for probing web applications.
Download & Setup
We will use Metasploitable 2 as the target and Kali Linux as our local machine, but you can use whatever you're comfortable with when following along.
The first thing we need to do is download Arjun from GitHub. We can easily clone a copy of the repository using the git clone command:
~# git clone https://github.com/s0md3v/Arjun
Cloning into 'Arjun'...
remote: Enumerating objects: 226, done.
remote: Total 226 (delta 0), reused 0 (delta 0), pack-reused 226
Receiving objects: 100% (226/226), 159.03 KiB | 1024.00 KiB/s, done.
Resolving deltas: 100% (104/104), done.
Now just change into the new directory using cd:
~# cd Arjun/
And we can list the contents with the ls command:
~/Arjun# ls
arjun.py CHANGELOG.md core db LICENSE README.md
Arjun needs Python version 3.4 or higher to work properly, and we can see if it's installed on our system using the which command:
~/Arjun# which python3
/usr/bin/python3
And we can check the version number with the -V switch:
~/Arjun# python3 -V
Python 3.7.5rc1
If Python 3.4 or above isn't on our system, we can install it through the package manager:
~/Arjun# apt-get install python3
That should be all we need to get started.
Arjun in Action
It's always a good idea to check the help menu when confronted with a new tool. Use the -h flag to view Arjun's help and optional arguments:
~/Arjun# python3 arjun.py -h
_
/_| _ '
( |/ /(//) v1.6
_/
usage: arjun.py [-h] [-u URL] [-o OUTPUT_FILE] [-d DELAY] [-t THREADS]
[-f WORDLIST] [--urls URL_FILE] [--get] [--post]
[--headers [HEADERS]] [--json] [--stable] [--include INCLUDE]
optional arguments:
-h, --help show this help message and exit
-u URL target url
-o OUTPUT_FILE path for the output file
-d DELAY request delay
-t THREADS number of threads
-f WORDLIST wordlist path
--urls URL_FILE file containing target urls
--get use get method
--post use post method
--headers [HEADERS] add headers
--json treat post data as json
--stable prefer stability over speed
--include INCLUDE include this data in every request
The most basic way to run the tool is by supplying a valid URL — use the -u flag to do so:
~/Arjun# python3 arjun.py -u http://10.10.0.50/phpMyAdmin/
_
/_| _ '
( |/ /(//) v1.6
_/
[~] Analysing the content of the webpage
[~] Analysing behaviour for a non-existent parameter
[!] Reflections: 0
[!] Response Code: 200
[!] Content Length: 4145
[!] Plain-text Length: 474
[~] Parsing webpage for potential parameters
[+] Heuristic found a potential post parameter: phpMyAdmin
[!] Prioritizing it
[+] Heuristic found a potential post parameter: db
[!] Prioritizing it
[+] Heuristic found a potential post parameter: table
[!] Prioritizing it
[+] Heuristic found a potential post parameter: lang
[!] Prioritizing it
[+] Heuristic found a potential post parameter: convcharset
[!] Prioritizing it
[+] Heuristic found a potential post parameter: token
[!] Prioritizing it
[+] Heuristic found a potential post parameter: pma_username
[!] Prioritizing it
[+] Heuristic found a potential post parameter: pma_password
[!] Prioritizing it
[+] Heuristic found a potential post parameter: server
[!] Prioritizing it
[~] Performing heuristic level checks
[!] Scan Completed
[+] Valid parameter found: db
[+] Valid parameter found: phpMyAdmin
[+] Valid parameter found: table
[+] Valid parameter found: target
[+] Valid parameter found: GLOBALS
[+] Valid parameter found: pma_username
We can see it starts analyzing the page, looking for any potential HTTP parameters that might be hidden. It finds a few valid ones and gives us the results at the bottom.
We can also specify which type of request data to use. For example, to search for GET parameters, simply add the --get option:
~/Arjun# python3 arjun.py -u http://10.10.0.50/phpMyAdmin/ --get
_
/_| _ '
( |/ /(//) v1.6
_/
[~] Analysing the content of the webpage
[~] Analysing behaviour for a non-existent parameter
[!] Reflections: 0
[!] Response Code: 200
[!] Content Length: 4145
[!] Plain-text Length: 474
[~] Parsing webpage for potential parameters
...
To search for POST parameters, use the --post option:
~/Arjun# python3 arjun.py -u http://10.10.0.50/phpMyAdmin/ --post
_
/_| _ '
( |/ /(//) v1.6
_/
[~] Analysing the content of the webpage
[~] Analysing behaviour for a non-existent parameter
[!] Reflections: 0
[!] Response Code: 200
[!] Content Length: 4145
[!] Plain-text Length: 474
[~] Parsing webpage for potential parameters
...
And to search for JSON parameters, use the --json option:
~/Arjun# python3 arjun.py -u http://10.10.0.50/phpMyAdmin/ --json
_
/_| _ '
( |/ /(//) v1.6
_/
[~] Analysing the content of the webpage
[~] Analysing behaviour for a non-existent parameter
[!] Reflections: 0
[!] Response Code: 200
[!] Content Length: 4145
[!] Plain-text Length: 474
[~] Parsing webpage for potential parameters
...
We can also supply Arjun with a list of multiple URLs to use instead of just a single one. Use the --urls flag followed by the name of the file containing the list of URLs:
~/Arjun# python3 arjun.py --urls urls.txt
_
/_| _ '
( |/ /(//) v1.6
_/
[~] Scanning: http://10.10.0.50/phpMyAdmin/
[~] Analysing the content of the webpage
[~] Analysing behaviour for a non-existent parameter
[!] Reflections: 0
[!] Response Code: 200
[!] Content Length: 4145
[!] Plain-text Length: 474
[~] Parsing webpage for potential parameters
...
In the same vein, we can use our own wordlist containing custom parameter names instead of the default one Arjun uses. Use the -f flag followed by the name of the custom wordlist:
~/Arjun# python3 arjun.py -u http://10.10.0.50/phpMyAdmin/ -f parameters.txt
_
/_| _ '
( |/ /(//) v1.6
_/
[~] Analysing the content of the webpage
[~] Analysing behaviour for a non-existent parameter
[!] Reflections: 0
[!] Response Code: 200
[!] Content Length: 4145
[!] Plain-text Length: 474
[~] Parsing webpage for potential parameters
...
Arjun allows us to set the number of threads to use as well, the default being two. Use the -t switch followed by the number of desired threads:
~/Arjun# python3 arjun.py -u http://10.10.0.50/phpMyAdmin/ -t 16
_
/_| _ '
( |/ /(//) v1.6
_/
[~] Analysing the content of the webpage
[~] Analysing behaviour for a non-existent parameter
[!] Reflections: 0
[!] Response Code: 200
[!] Content Length: 4145
[!] Plain-text Length: 474
[~] Parsing webpage for potential parameters
...
We can also set the delay between requests with the -d flag:
~/Arjun# python3 arjun.py -u http://10.10.0.50/phpMyAdmin/ -d 5
_
/_| _ '
( |/ /(//) v1.6
_/
[~] Analysing the content of the webpage
[~] Analysing behaviour for a non-existent parameter
[!] Reflections: 0
[!] Response Code: 200
[!] Content Length: 4145
[!] Plain-text Length: 474
[~] Parsing webpage for potential parameters
...
For particularly tricky targets, we can use the --stable option, which will set the number of threads to 1 and the delay to a random number of seconds between 6 and 12:
~/Arjun# python3 arjun.py -u http://10.10.0.50/phpMyAdmin/ --stable
_
/_| _ '
( |/ /(//) v1.6
_/
[~] Analysing the content of the webpage
[~] Analysing behaviour for a non-existent parameter
[!] Reflections: 0
[!] Response Code: 200
[!] Content Length: 4145
[!] Plain-text Length: 474
[~] Parsing webpage for potential parameters
...
Arjun makes it easy to save the results in JSON format — just use the -o switch followed by the name of the output file:
~/Arjun# python3 arjun.py -u http://10.10.0.50/phpMyAdmin/ -o results.json
_
/_| _ '
( |/ /(//) v1.6
_/
[~] Analysing the content of the webpage
[~] Analysing behaviour for a non-existent parameter
[!] Reflections: 0
[!] Response Code: 200
[!] Content Length: 4145
[!] Plain-text Length: 474
[~] Parsing webpage for potential parameters
[+] Heuristic found a potential post parameter: phpMyAdmin
[!] Prioritizing it
[+] Heuristic found a potential post parameter: db
[!] Prioritizing it
[+] Heuristic found a potential post parameter: table
[!] Prioritizing it
[+] Heuristic found a potential post parameter: lang
[!] Prioritizing it
[+] Heuristic found a potential post parameter: convcharset
[!] Prioritizing it
[+] Heuristic found a potential post parameter: token
[!] Prioritizing it
[+] Heuristic found a potential post parameter: pma_username
[!] Prioritizing it
[+] Heuristic found a potential post parameter: pma_password
[!] Prioritizing it
[+] Heuristic found a potential post parameter: server
[!] Prioritizing it
[~] Performing heuristic level checks
[!] Scan Completed
[+] Valid parameter found: GLOBALS
[+] Valid parameter found: db
[+] Valid parameter found: phpMyAdmin
[+] Valid parameter found: table
[+] Valid parameter found: target
[+] Valid parameter found: pma_username
[!] Saving output to JSON file in results.json
Another handy feature is the ability to include specific data to be sent with every request. Use the --include option with the data string to be sent in quotes:
~/Arjun# python3 arjun.py -u http://10.10.0.50/phpMyAdmin/ --include 'data=test'
_
/_| _ '
( |/ /(//) v1.6
_/
[~] Analysing the content of the webpage
[~] Analysing behaviour for a non-existent parameter
[!] Reflections: 0
[!] Response Code: 200
[!] Content Length: 4145
[!] Plain-text Length: 474
[~] Parsing webpage for potential parameters
...
We can also use the --headers option, which will allow us to send header information with the request:
~/Arjun# python3 arjun.py -u http://10.10.0.50/phpMyAdmin/ --headers
That will open up a text editor (nano by default), allowing us to paste any headers right in:
GNU nano 4.5 /tmp/tmptvwpv4kd
Host: EXAMPLE
Accept: TEST
Referer: https://www.google.com
The default editor can be changed in /core/prompt.py to an editor of choice.
Wrapping Up
Today, we learned a bit about HTTP parameters and how sometimes they can be hidden from plain view. Arjun is a tool that can be used to expose these hidden parameters, leading to increased visibility of a web app's attack surface. We explored the tool and some of its options, including the ability to use different request methods, custom threading and delay, persistent request data, and more. Arjun is a nice little tool that anyone serious about attacking web applications can benefit from.
Just updated your iPhone to iOS 18? You'll find a ton of hot new features for some of your most-used Apple apps. Dive in and see for yourself:
Be the First to Comment
Share Your Thoughts