In this assignment, we provide an insecure website, and your job is to attack it by exploiting three common classes of vulnerabilities: SQL injection, cross-site request forgery (CSRF), and cross-site scripting (XSS). You are also asked to exploit these problems with various flawed defenses in place. Understanding how these attacks work will help you better defend your own web applications.
This is a group assignment, and must be done in groups of 2 or 3 only.
This project asks you to perform attacks, with our permission, against a target website that we are providing for this purpose. Attempting the same kinds of attacks against other websites without authorization is prohibited by law and university policies. You must not attack any website without authorization! Per course policy, you are required to respect the privacy and property rights of others at all times. See “Right, Rules, and Responsibilities” on the Princeton University website for more details.
A startup named BUNGLE! is about to launch its first product — a web search engine — but their investors are nervous about security problems. Unlike the Bunglers who developed the site, you took COS 432, so the investors have hired you to perform a security evaluation before it goes live.
BUNGLE! is available for you to test at https://elecos432.org.
The site is written in Python using the Bottle web framework. Although Bottle has built-in mechanisms that help guard against some common vulnerabilities, the Bunglers have circumvented or ignored these mechanisms in several places.
In addition to providing search results, the site accepts logins and tracks users’ search histories. It stores usernames, passwords, and search history in a MySQL database. Before being granted access to the source code, you reverse engineered the site and determined that it replies to five main URLs:
/
/search
/login
/logout
/create
/
) The main page accepts GET
requests and displays a search form. When submitted,this form issues a GET
request to /search
, sending the search string as the parameter “q”.
POST
requests to /login and /create.
/search
) The search results page accepts GET requests and prints the search string, supplied in the “q” query parameter, along with the search results. If the user is logged in, the page also displays the user’s recent search history in a sidebar.
/login
) The login handler accepts POST
requests and takes plaintext “username” and “password” query parameters. It checks the user database to see if a user with those credentials exists. If so, it sets a login cookie and redirects the browser to the main page. The cookie tracks which user is logged in; manipulating or forging it is not part of this project.
/logout
) The logout handler accepts POST
requests. It deletes the login cookie,if set, and redirects the browser to the main page.
/create
) The create account handler accepts POST
requests and receives plaintext “username” and “password” query parameters. It inserts the username and password into the database of users, unless a user with that username already exists. It then logs the user in and redirects the browser to the main page.
Virtual Machine: For this project, we’d like you to do all your testing within the VM that you used for Assignment 4. This VM provides Firefox (the browser we will use for grading is the same version) and a method for hosting a local HTTP server (necessary for Part 3). Browser versions have slight variations in their behavior that may affect your XSS and CSRF attacks, so we highly recommend that you develop and test your solutions within the VM.
Defense Levels: The Bunglers have been experimenting with some naïve defenses, so you also need to demonstrate that these provide insufficient protection. In Parts 2 and 3, the site includes drop-down menus at the top of each page that let you change the CSRF and XSS defenses that are in use. The solutions you submit must override these selections by including the csrfdefense=n
or xssdefense=n
parameter in the target URL, as specified in each task below. You may not attempt to subvert the mechanism for changing the level of defense in your attacks. Be sure to test your solutions with the appropriate defense levels!
In all parts, you should implement the simplest attack you can think of that defeats the given set of defenses. In other words, do not simply attack the highest level of defense and submit that attack as your solution for all defenses. You do not need to combine the vulnerabilities, unless explicitly stated.
Resources: The Firefox web developer tools will be very helpful for this project, particularly the JavaScript console and debugger, DOM inspector, and network monitor. To open these tools, click the Developer button in the Firefox menu. See https://developer.mozilla.org/en-US/docs/Tools. Note that there is also a special version of the browser called Firefox Developer Edition; you’re welcome to use it to develop and test, but we will be grading with the normal edition of Firefox.
Your solutions will involve manipulating SQL statements and writing web code using HTML, JavaScript, and the jQuery library. You should search the web for answers to basic how-to questions. There are many fine online resources for learning these tools. Here are a few that we recommend:
To learn more about SQL Injection, XSS, and CSRF attacks, and for tips on exploiting them, see:
Download the directory template here. You should be using this to organize your answers. For most of the questions, you can simply type up the answer in the text/html files we've created for you. However, for 1.2, make sure you replace the placeholder zip archive with your own zip file that contains all the source code.
Your first goal is to demonstrate SQL injection attacks that log you in as an arbitrary user without knowing the password. In order to protect other students’ accounts, we’ve made a series of separate login forms for you to attack that aren’t part of the main BUNGLE! site. For each of the following defenses, provide inputs to the target login form that successfully log you in as the user “victim”:
if (isset($_POST['username']) and isset($_POST['password'])) {
$username = mysql_real_escape_string($_POST['username']);
$password = md5($_POST['password'], true);
$sql_s = "SELECT * FROM users WHERE username='$username' and pw='$password'";
$rs = mysql_query($sql_s);
if (mysql_num_rows($rs) > 0) {
echo "Login successful!";
} else {
echo "Incorrect username or password";
}
}
This is more difficult than the previous two defenses. You will need to write a program to
produce a working exploit. You can use any language you like, but we recommend Python for its ease in library linking.
URL
URL
URL
...
Name: DB name
Version: DB version string
Tables: comma separated names
Secret: secret string
What to submit For 1.0, 1.1, and 1.2, when you successfully log in as victim, the server will provide a URL-encoded version of your form inputs. Submit a text file with the specified filename containing only this line. For 1.2, also submit the source code for the program you wrote, as a zip file (sql_2_src.zip). For 1.3, submit a text file as specified.
Your next task is to demonstrate CSRF vulnerabilities against the login form, and BUNGLE! has
provided two variations of their implementation for you to test. Your goal is to construct attacks that
surreptitiously cause the victim to log in to an account you control, thus allowing you to monitor
the victim’s search queries by viewing the search history for this account. For each of the defenses
below, create an HTML file that, when opened by a victim, logs their browser into BUNGLE! under
the account attacker
and password l33th4x
.
csrf_token
to a random 16-byte value and also includes this value as a hidden field in the login form. When the form is submitted, the server verifies that the client’s cookie matches the value in the form. You are allowed to exploit the XSS
vulnerability from Part 3 to accomplish your goal.
http://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js
https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js
Test your solutions by opening them as local files in the browser in the Linux VM. Note: Since you’re sharing the attacker account with other students, we’ve hard-coded it so the search history won’t actually update. You can test with a different account you create to see the history change.
Your final goal is to demonstrate XSS attacks against the BUNGLE! search box, which does not
properly filter search terms before echoing them to the results page. For each of the defenses
below, your goal is to construct a URL that, when loaded in the victim’s browser, correctly executes
the specified payload. We recommend that you begin by testing with a simple payload (e.g.,
alert(0);
), then move on to the full payload. Note that you should be able to implement the
payload once, then use different means of encoding it to bypass the different defenses.
Payload The payload (the code that the attack tries to execute) will be to steal the username and the most recent search the real user has performed on the BUNGLE! site. When a victim visits the URL you create, these stolen items should be sent to the attacker’s server for collection.
For purposes of grading, your attack should report these events by loading the URL:
http://localhost:31337/stolen?user=username&last_search=last_search
You can test receiving this data within the provided VM by downloading
and running these commands in terminal:$ cd /Downloads; python log_listener.py
and observing the HTTP GET request that your payload generates. To further test that your HTTP server is running, try navigating to:
http://localhost:31337
Defenses There are five levels of defense. In each case, you should submit the simplest attack you can find that works against that defense; you should not simply attack the highest level and submit your solution for that level for every level. Try to use a different technique for each defense. The Python code that implements each defense is shown below, along with the target URL and the filename you should submit.
filtered = re.sub(r"(?i)script", "", input)
filtered = re.sub(r"(?i)script|<img|<body|<style|<meta|<embed|<object","", input)
filtered = re.sub(r"[;'\"]", "", input)
filtered = input.replace("<", "<").replace(">", ">")
What to submit Your submission for each level of defense will be a text file with the specified filename that contains a single line consisting of a URL. When this URL is loaded in a victim’s browser, it should execute the specified payload against the specified target. Please remember to correctly specify the XSS defense levels in your URLs (if you have nested URLs, specify the levels in the nestes ones too!). The payload encoded in your URLs may embed inline JavaScript and load jQuery from the URL:
http://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js
https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js
For each of the three kinds of attacks (SQL injection, CSRF, and XSS), write a paragraph of advice for the BUNGLE! developers recommending what techniques they should use to defend themselves.
What to submit A text file named writeup.txt
containing your security recommendations.
Where applicable, your solutions may contain embedded JavaScript. They are allowed to load only the exact Javascript libraries specified above, and must be otherwise self-contained. Test your solutions with the browser provided in the VM.
The solutions you submit for Part 2 (CSRF) and Part 3 (XSS) must include the csrfdefense=n
or xssdefense=n
parameter in the target URL, as specified in each task. You may not attempt to subvert the mechanism for changing the level of defense in your attacks. Submit your files as a single zip file on Gradescope. Your zip file should have the following structure:
part1
sql_0.txt
- 1.0 No defenses
sql_1.txt
- 1.1 Simple escaping
sql_2.txt
- 1.2 Escaping and Hashing
sql_2_src.zip
- 1.2 Escaping and Hashing source code
sql_3.txt
- 1.3 The SQL [Extra credit]
part2
csrf_0.html
- 2.0 No defenses
csrf_1.html
- 2.1 Token validation
csrf_2.html
- 2.2 Token validation, without XSS [Extra credit]
part3
xss_payload.html
- 3.0 No defenses
xss_0.txt
- 3.0 No defenses
xss_1.txt
- 3.1 Remove "script"
xss_2.txt
- 3.2 Remove several tags
xss_3.txt
- 3.3 Remove some punctuation
xss_4.txt
- 3.4 Encode < and > [Extra credit]
part4
writeup.txt
- 4.0 security recommendations