Nmap – Auditing Web Servers

Hypertext Transfer Protocol (HTTP) is arguably one of the most popular protocols in use today. Web servers have moved from serving static pages to handling complex web applications with actual user interaction. This has opened the doors to tainted user input that could change an application’s logic to perform unintended actions. Modern web development frameworks allow almost anyone with a knowledge of programming to produce web applications within minutes, but this has also caused an increase of vulnerable applications on the Internet.
The number of available HTTP scripts for the Nmap Scripting Engine grew rapidly, and Nmap turned into an invaluable web scanner that helps penetration testers perform a lot of the tedious manual checks in an automated manner. Not only can it be used to find vulnerable web applications or detect faulty configuration settings, but thanks to the new spidering library, Nmap can even crawl web servers, looking for all sorts of interesting information.

Listing supported HTTP methods:

Web servers support different HTTP methods according to their configuration and software, and some of them could be dangerous under certain conditions. Pentesters need a way of quickly listing the available methods. The NSE script http-methods allows them not only to list these potentially-dangerous methods but also to test them.
#nmap -p80,443 –script http-methods google.com
The argument -p80,443 –script http-methods makes Nmap launch the httpmethods script if a web server is found ports 80 or 443 (-p80,443). The NSE script httpmethods was submitted by Bernd Stroessenreuther, and it uses the HTTP method OPTIONS to try to list all of the supported methods by a web server.
To individually check the status code response of the methods returned by OPTIONS, use the script argument http-methods.retest:
# nmap -p80,443 –script http-methods –script-args http-methods.retest insecure.org
By default, the script http-methods uses the root folder as the base path ( / ). If you wish to set a different base path, set the argument http-methods.url-path:
# nmap -p80,443 –script http-methods –script-args http-methods.urlpath=/mypath/ <Target>
Interesting HTTP methods:
The HTTP methods TRACE, CONNECT, PUT, and DELETE might present a security risk,
and they need to be tested thoroughly if supported by a web server or application.
TRACE makes applications susceptible to Cross Site Tracing (XST) attacks and could lead to attackers accessing cookies marked as httpOnly.
The CONNECT method might allow the web server to be used as an unauthorized web proxy.
The methods PUT and DELETE have the ability to change the contents of a folder, and this could obviously be abused if the permissions are not set properly.
HTTP User Agent
There are some packet filtering products that block requests that use Nmap’s default HTTP User Agent. You can use a different HTTP User Agent by setting the argument http.useragent:
#nmap -p80 –script http-methods –script-args http.useragent=”Mozilla 42″ <target>
HTTP pipelining
Some web servers allow the encapsulation of more than one HTTP request in a single packet. This may speed up the execution of an NSE HTTP script, and it is recommended that it is used, if the web server supports it. The HTTP library, by default, tries to pipeline 40 requests and auto adjusts the number of requests according to the traffic conditions, based on the Keep-Alive header.
#nmap -p80 –script http-methods –script-args http.pipeline=25 <target>
Additionally, you can use the argument http.max-pipeline to set the maximum number of HTTP requests to be added to the pipeline. If the script parameter http.pipeline is set, this argument will be ignored:
#nmap -p80 –script http-methods –script-args http.max-pipeline=10 <target>

Checking if an HTTP proxy is open:

HTTP proxies are used to make requests through their addresses, therefore hiding our real IP address from the target. Detecting them is important if you are a system administrator who needs to keep the network secure, or an attacker who spoofs his real origin.
#nmap –script http-open-proxy -p8080 google.com
 
We use the argument –script http-open-proxy -p8080 to launch the NSE script http-open-proxy if a web server is found running on port 8080, a common port for HTTP proxies.
You may request a different URL and specify the pattern that will be returned if the connection is successful by using the script parameters http-open-proxy.url and http-open-proxy.pattern:
#nmap –script http-open-proxy –script-args http-open-proxy.url=http://whatsmyip.org,http-open-proxy.pattern=”Your IP address is” -p8080<target>
HTTP User Agent:
There are some packet filtering products that block requests that use Nmap’s default HTTP user agent. You can use a different HTTP User Agent by setting the argument http.useragent:
#nmap -p80 –script http-trace –script-args http.useragent=”Mozilla 42″ <target>

Discovering interesting files and directories on various web servers:

One of the common tasks during penetration tests that cannot be done manually is file and directory discovery. There are several tools made for this task, but Nmap really shines with its robust database that covers interesting files, such as READMEs, database dumps, and forgotten configuration backups; common directories, such as administration panels or unprotected file uploaders; and even attack payloads to exploit directory traversals in common, vulnerable web applications.
#nmap –script http-enum -p80 <target>

The argument -p80 –script http-enum tells Nmap to initiate the script http-enum if a web server is found on port 80. The script http-enum was originally submitted by Ron Bowes and its main purpose was directory discovery, but the community has been adding new fingerprints to include other interesting files, such as version files, READMEs, and forgotten database backups. I’ve also added over 150 entries that identify vulnerable web applications from the last two years, and new entries are added constantly.

The fingerprints are stored in the file http-fingerprints.lua in /nselib/data/, and they are actually LUA tables. An entry looks like something like following:

You may add your own entries to this file or use a different fingerprint file by using the argument http-enum.fingerprintfile:
#nmap –script http-enum –script-args http-enum.fingerprintfile=./myfingerprints.txt -p80 <target>

By default, http-enum uses the root directory as the base path. To set a different base path, use the script argument http-enum.basepath:
#nmap –script http-enum http-enum.basepath=/web/ -p80 <target>

To display all the entries that returned a status code that could possibly indicate a page exists, use the script argument http-enum.displayall:
#nmap –script http-enum http-enum.displayall -p80 <target>

HTTP User Agent:
There are some packet filtering products that block requests made using Nmap’s default HTTP User Agent. You can use a different HTTP User Agent by setting the argument http. useragent:
#nmap -p80 –script http-enum –script-args http.useragent=”Mozilla 42″<target>

HTTP pipelining:
Some web servers allow the encapsulation of more than one HTTP request in a single packet. This may speed up the execution of an NSE HTTP script, and it is recommended that it is used if the web server supports it. The HTTP library, by default, tries to pipeline 40 requests and automatically adjusts that number according to the traffic conditions, based on the Keep-Alive header.
#nmap -p80 –script http-enum –script-args http.pipeline=25 <target>

Additionally, you can use the argument http.max-pipeline to set the maximum number of HTTP requests to be added to the pipeline. If the script parameter http.pipeline is set, this argument will be ignored:
#nmap -p80 –script http-methods –script-args http.max-pipeline=10<target>

Abusing mod_userdir to enumerate user accounts:

Apache’s module UserDir provides access to the user directories by using URIs with the syntax /~username/. With Nmap we can perform dictionary attacks and determine a list of valid usernames on the web server. This recipe shows you how to make Nmap perform brute force attacks to enumerate user accounts in Apache web servers, with mod_userdir enabled.

To try to enumerate valid users in a web server with mod_userdir; use Nmap with these arguments:
#nmap -p80 –script http-userdir-enum google.com

The argument -p80 –script http-userdir-enum launches the NSE script httpuserdir-enum if a web server is found on port 80 (-p80). Apache web servers with mod_userdir allow access to user directories by using URIs such as http://domain.com/~root/, and this script helps us to perform dictionary attacks to enumerate valid users.

The script http-userdir-enum uses, by default, the word list usernames.lst located at /nselib/data/, but you can use a different file by setting the argument userdir.users, as shown in the following command:
#nmap -p80 –script http-userdir-enum –script-args userdir.users=./users.lst <target>

HTTP User Agent
There are some packet filtering products that block requests made using Nmap’s default HTTP User Agent. You can use a different User Agent value by setting the argument http.useragent:
$ nmap -p80 –script http-brute –script-args http.useragent=”Mozilla 42″<target>

HTTP pipelining
Some web servers allow the encapsulation of more than one HTTP request in a single packet. This may speed up the execution of an NSE HTTP script, and it is recommended that it is used if the web server supports it. The HTTP library, by default, tries to pipeline 40 requests and auto adjusts that number according to the traffic conditions, based on the Keep-Alive header.
#nmap -p80 –script http-methods –script-args http.pipeline=25 <target>

Additionally, you can use the argument http.max-pipeline to set the maximum number of HTTP requests to be added to the pipeline. If the script parameter http.pipeline is set,this argument will be ignored:
#nmap -p80 –script http-methods –script-args http.max-pipeline=10<target>

Brute-force password auditing WordPress installations:

WordPress is a widely known CMS (Content Management System) that is used in many industries. Nmap now includes its own NSE script to help pentesters launch dictionary attacks and find accounts using weak passwords that could compromise the application’s integrity.

To find accounts with weak passwords in WordPress installations, use the following Nmap command:
#nmap -p80 –script http-wordpress-brute <target> 

The argument -p80 –script http-wordpress-brute initiates the NSE script httpwordpress-brute if a web server is found on port 80 (-p80).

This script uses the following default variables:

  • uri: /wp-login.php
  • uservar: log
  • passvar: pwd

To set the number of threads, use the script argument http-wordpress-brute.threads:
#nmap -p80 –script http-wordpress-brute –script-args http-wordpressbrute.threads=5 <target>

If the server has virtual hosting, set the host field by using the argument http-wordpressbrute. hostname:
#nmap -p80 –script http-wordpress-brute –script-args http-wordpressbrute.hostname=”ahostname.wordpress.com” <target>
To set a different login URI, use the argument http-wordpress-brute.uri:
#nmap -p80 –script http-wordpress-brute –script-args http-wordpressbrute.uri=”/hidden-wp-login.php” <target>
To change the name of the POST variable that stores the usernames and passwords, set the arguments http-wordpress-brute.uservar and http-wordpress-brute.passvar:
#nmap -p80 –script http-wordpress-brute –script-args http-wordpressbrute.uservar=usuario,http-wordpress-brute.passvar=pasguord <target>
HTTP User Agent:
There are some packet filtering products that block requests made using Nmap’s default HTTP User Agent. You can use a different User Agent value by setting the argument http.useragent:
#nmap -p80 –script http-wordpress-brute –script-args http.useragent=”Mozilla 42″ <target>
Brute modes:
The Brute library supports different modes that alter the combinations used in the attack.The available modes are:
  • user: In this mode, for each user listed in userdb, every password in passdb will be tried

# nmap –script http-wordpress-brute –script-args brute.mode=user <target>

  • pass: In this mode, for each password listed in passdb, every user in usedb will be tried

#nmap –script http-wordpress-brute –script-args brute.mode=pass <target>

  • creds: This mode requires the additional argument brute.credfile

#nmap –script http-wordpress-brute –script-args brute. mode=creds,brute.credfile=./creds.txt  <target>

Brute-force password auditing Joomla! installations:

Joomla! is a very popular CMS that is used for many different purposes, including e-commerce. Detecting user accounts with weak passwords is a common task for penetration testers, and Nmap helps with that by using the NSE script http-joomla-brute.

Open your terminal and enter the following command:
#nmap -p80 –script http-joomla-brute <target> 

The argument -p80 –script http-joomla-brute launches the NSE script http-joomla-brute if a web server is found on port 80 (-p80).

The script http-joomla-brute uses the following default variables:

  • uri: /administrator/index.php
  • uservar: username
  • passvar: passwd

Set the thread number with the argument http-joomla-brute.threads by using the following command:
#nmap -p80 –script http-joomla-brute –script-args http-joomla-brute.threads=5 <target>

To set the Host field in the HTTP requests, use the script argument http-joomla-brute.hostname, by using the following command:
#nmap -p80 –script http-joomla-brute –script-args http-joomla-brute.hostname=”hostname.com” <target>
Set a different login URI by specifying the argument http-joomla-brute.uri using the following command:
#nmap -p80 –script http-joomla-brute –script-args http-joomla-brute.uri=”/joomla/admin/login.php” <target>
To change the name of the POST variable that stores the usernames and passwords, set the arguments http-joomla-brute.uservar and http-joomla-brute.passvar by using the following command:
#nmap -p80 –script http-joomla-brute –script-args http-joomla-brute.uservar=usuario,http-joomla-brute.passvar=pasguord <target>
HTTP User AgentThere are some packet filtering products that block requests made using Nmap’s default HTTP User Agent. You can use a different User Agent value by setting the argument http.useragent:
#nmap -p80 –script http-wordpress-brute –script-args http.useragent=”Mozilla 42″ <target>
Brute modes
The Brute library supports different modes that alter the combinations used in the attack.The available modes are:

  • user: In this mode, for each user listed in userdb, every password in passdb will be tried

#nmap –script http-wordpress-brute –script-args brute.mode=user<target>

  • pass: In this mode, for each password listed in passdb, every user in usedb will be tried

#nmap –script http-wordpress-brute –script-args brute.mode=pass<target>

  • creds: This mode requires the additional argument brute.credfile

#nmap –script http-wordpress-brute –script-args brute.mode=creds,brute.credfile=./creds.txt <target>

Detecting web application firewalls:

Web servers are often protected by packet filtering systems that drop or redirect suspected malicious packets. Web penetration testers benefit from knowing that there is a traffic filtering system between them and the target application. If that is the case, they can try more rare or stealthy techniques to try to bypass the Web Application Firewall (WAF) or Intrusion Prevention System (IPS). It also helps them to determine if a vulnerability is actually exploitable in the current environment.

To detect a Web Application Firewall or Intrusion Prevention System:
#nmap -p80 –script http-waf-detect <target>

The argument -p80 –script http-waf-detect initiates the NSE script http-wafdetect if a web server is found running on port 80.The script works by saving the status code, and optionally the page body, of a safe HTTP GET request and comparing it with requests containing attack payloads for the most common web application vulnerabilities. Because each malicious payload is stored in an odd variable name, it is really unlikely that it is used by the web application, and only packet filtering systems would react and alter any of the returned status codes, to maybe receive an HTTP status code 403 (Forbidden) or the page content.

To detect changes in the response body, use the argument http-waf-detect. detectBodyChanges. I recommend that you enable it when dealing with pages with little dynamic content:
#nmap -p80 –script http-waf-detect –script-args=”http-waf-detect.detectBodyChanges” <target> 

To set a different URI for the probes, set the argument http-waf-detect.uri:
#nmap -p80 –script http-waf-detect –script-args http-waf-detect.uri=/webapp/ <target>

HTTP User Agent:
There are some packet filtering products that block requests made using Nmap’s default HTTP User Agent. You can use a different User Agent value by setting the argument http.useragent:
#nmap -p80 –script http-waf-detect –script-args http.useragent=”Mozilla 42″ <target>

HTTP pipelining:
Some web servers allow the encapsulation of more than one HTTP request in a single packet. This may speed up the execution of an NSE HTTP script, and it is recommended that it is used if the web server supports it. The HTTP library, by default, tries to pipeline 40 requests and automatically adjusts that number according to the traffic conditions, based on the Keep- Alive header.
#nmap -p80 –script http-methods –script-args http.pipeline=25 <target>

Additionally, you can use the argument http.max-pipeline to set the maximum number of HTTP requests to be added to the pipeline. If the script parameter http.pipeline is set, this argument will be ignored:
#nmap -p80 –script http-methods –script-args http.max-pipeline=10 <target>

Finding SQL injection vulnerabilities in web applications:

SQL injection vulnerabilities are caused by the lack of sanitation of user input, and they allow attackers to execute DBMS queries that could compromise the entire system. This type of web vulnerability is very common, and because each script variable must be tested, checking for such vulnerabilities can be a very tedious task. Fortunately, we can use Nmap to quickly scan a web server looking for vulnerable files for SQL injection.

To scan a web server looking for files vulnerable to SQL injection by using Nmap, use the following command:
#nmap -p80 –script http-sql-injection <target> 

The script http-sql-injection.nse was written by Eddie Bell and Piotr Olma. It crawls a web server looking for forms and URIs with parameters, and attempts to find SQL injection vulnerabilities. The script determines if the server is vulnerable by inserting SQL queries that are likely to cause an error in the application. This means that the script will not detect any blind SQL injection vulnerabilities.

The httpspider library behavior can be configured via library arguments. By default it uses pretty conservative values to save resources, but during a comprehensive test, we need to tweak several of them to achieve optimum results. For example, the library will only crawl 20 pages by default, but we can set the argument httpspider.maxpagecount accordingly for bigger sites, as shown in the following command:
#nmap -p80 –script http-sql-injection –script-args httpspider.maxpagecount=200 <target>

Another interesting argument is httpspider.withinhost, which limits the web crawler to a given host. This is turned on by default, but if you need to test a collection of web applications linked to each other, you could use the following command:
#nmap -p80 –script http-sql-injection –script-args httpspider.withinhost=false <target>

We can also set the maximum depth of directories we want to cover. By default this value is only 3, so if you notice that the web server has deeply nested files, especially when “pretty urls” such as /blog/5/news/comment/ are implemented, I recommend that you update this library argument:
#nmap -p80 –script http-sql-injection –script-args httpspider.maxdepth=10 <target>

HTTP User Agent:There are some packet filtering products that block requests made using Nmap’s default HTTP User Agent. You can use a different User Agent value by setting the argument http.useragent:
#nmap -p80 –script http-sql-injection –script-args http.useragent=”Mozilla 42″ <target>

HTTP pipelining:
Some web servers allow the encapsulation of more than one HTTP request in a single packet. This may speed up the execution of an NSE HTTP script, and it is recommended that this is used if the web server supports it. The HTTP library, by default, tries to pipeline 40 requests and automatically adjusts that number according to the traffic conditions, based on the Keep-Alive header.
#nmap -p80 –script http-sql-injection –script-args http.pipeline=25<target> 

Additionally, you can use the argument http.max-pipeline to set the maximum number of HTTP requests to be added to the pipeline. If the script parameter http.pipeline is set, this argument will be ignored:
#nmap -p80 –script http-methods –script-args http.max-pipeline=10<target>

Detecting Cross Site Scripting vulnerabilities in web applications:

Cross Site Scripting vulnerabilities allow attackers to spoof content, steal user cookies, and even execute malicious code on the user’s browsers. There are even advanced exploitation frameworks such as Beef that allow attackers to perform complex attacks through JavaScript hooks. Web pentesters can use Nmap to discover these vulnerabilities in web servers in an automated manner.

To scan a web server looking for files vulnerable to Cross Site Scripting (XSS), we use the following command:
#nmap -p80 –script http-unsafe-output-escaping <target>

The script output will also include the vulnerable parameter and which characters were returned without being filtered or encoded.

If you are working with a PHP server, run the following Nmap command instead:
#nmap -p80 –script http-phpself-xss,http-unsafe-output-escaping <target>

The script http-unsafe-output-escaping was written by Martin Holst Swende, and it spiders a web server to detect the possible problems with the way web applications return output based on user input. The script inserts the following payload into all the parameters it finds:
ghz%3Ehzx%22zxc%27xcv

The payload shown above is designed to detect the characters > ” ‘, which could cause Cross Site Scripting vulnerabilities.

The script will crawl a web server to find all of the files with a .php extension, and append the following payload to each URI:
/%27%22/%3E%3Cscript%3Ealert(1)%3C/script%3E

If the same pattern is reflected on the website, it means that a page is using the variable $_SERVER[“PHP_SELF”] unsafely.

The scripts http-unsafe-output-escaping and http-phpself-xss depend on the library httpspider. This library can be configured to increase its coverage and overall behavior.

For example, the library will only crawl 20 pages by default, but we can set the argument httpspider.maxpagecount accordingly for bigger sites:
#nmap -p80 –script http-phpself-xss –script-args httpspider.maxpagecount=200 <target>

Another interesting argument is httpspider.withinhost, which limits the web crawler to a given host. This is turned on by default, but if you need to test a collection of web applications linked to each other, you could use the following command:
#nmap -p80 –script http-phpself-xss –script-args httpspider.withinhost=false <target>

We can also set the maximum depth of directories we want to cover. By default this value is only 3, so if you notice that the web server has deeply nested files, especially when “pretty urls” such as /blog/5/news/comment/ are implemented, I recommend that you update this library argument by using the following command:
#nmap -p80 –script http-phpself-xss –script-args httpspider.maxdepth=10 <target>

The official documentation for the library can be found at http://nmap.org/nsedoc/lib/
httpspider.html.

HTTP User Agent:
There are some packet filtering products that block requests made using Nmap’s default HTTP User Agent. You can use a different User Agent value by setting the argument http.useragent:
$ nmap -p80 –script http-sql-injection –script-args http.useragent=”Mozilla 42″ <target>

HTTP pipelining:
Some web servers allow the encapsulation of more than one HTTP request in a single packet. This may speed up the execution of an NSE HTTP script, and it is recommended that it is used if the web server supports it. The HTTP library, by default, tries to pipeline 40 requests, and automatically adjusts that number according to the traffic conditions, based on the Keep-Alive header.
#nmap -p80 –script http-sql-injection –script-args http.pipeline=25 <target>

Additionally, you can use the argument http.max-pipeline to set the maximum number of HTTP requests to be added to the pipeline. If the script parameter http.pipeline is set, this argument will be ignored:
#nmap -p80 –script http-methods –script-args http.max-pipeline=10 <target>

Leave a comment