SQL Injection, CSRF, Cookie Stealing and Other Web Attacks in a Virtual Network
OWASP is an organisation that provides lots of material about attacks against web sites, and how to avoid them. They maintain a Top 10 list of web application security risks, which currently includes SQL injection, Cross-Site Scripting (XSS) and Cross-Site Request Forgery (CSRF). In my IT security course I used this list to explain several attacks. The lecture slides are available, as are YouTube screencasts: part 1, part 2. To illustrate selected attacks, I created a demo web site and performed the attacks on the site. In this article I explain how to setup the demo web site and perform the attacks yourself.
This article does not attempt to explain the attacks in detail (see the OWASP Top 10 for descriptions). The focus is on setting up the demo websites, and providing some hints for performing four attacks: cookie stealing, unvalidated redirect, SQL injection and CSRF. To understand how the demo attacks work, it is best to attempt them and then look in the supplied PHP code on the web servers. I assume you have basic knowledge of PHP and HTML and you can setup a virtnet virtual network.
The demo HTML/PHP code for the web sites is quite basic, and the attacks rather limited. There are many others that have created more elaborate demos if you want to see details, including Mutillidae and Damn Vulnerable Web App and others.
We will use a virtual network for the web site, normal browser and attacking nodes. I assume you have installed virtnet, a set of scripts and files that allow for automatic creation of virtual Linux nodes. virtnet also includes the files needed to quickly create the demo websites. The are included in the virtnet release 37 (12 Feb 2014). If you have an earlier version, then either download the most recent version of virtnet, or update SVN on the your host and base.
Create a topology 7, which contains 5 nodes as in the figure below, by running the following commands on your host (assuming virtnet SVN repository is in the svn directory in your home):
$ cd svn/virtnet/bin/host $ bash vn-createtopology 7
Node 1 can act as a client running a web browser. Node 2 can act as another client, also running a web browser. The user will be malicious in some cases. Node 3 is a router. It can be used to view traffic between browser and server (e.g. using tcpdump). Node 4 acts as the web server for the grading system. Node 5 acts as another web server for a site controlled by a malicious user.
If topology 7, which contains 5 nodes, does not perform well on your computer, then you may use a topology with fewer nodes (e.g. topology 5, running the browsers on node 1, and both servers on node 3). The following instructions assumes you have created topology 7 and are running nodes.
I have created some simply dummy web sites using PHP and MySQL for a database. One will be used as the main web site under attack, while two others will be used by the malicious user during selected attacks. The files are included with virtnet - they are in the directory virtnet/data/webdemos/. There is a README.txt file in the grades sub-directory that includes most of the instructions on this page.
Setup Grading System Web Site on Node 4
Start the MySQL and Apache web server:
network@node4:~$ sudo service mysql start network@node4:~$ sudo apache2ctl start
Change into the directory that contains these instructions. You are most likely already in it. If your svn base directory is in /home/network/svn then to change directory run:
network@node4:~$ cd /home/network/virtnet/data/webdemos/grades
Create the grades directory in /var/www (using sudo, and then change ownership):
network@node4:~virtnet/data/webdemos/grades$ sudo mkdir /var/www/grades network@node4:~virtnet/data/webdemos/grades$ sudo chown network.network /var/www/grades
Copy the web source to the above created directory:
network@node4:~virtnet/data/webdemos/grades$ cp www/* /var/www/grades/
As the root MySQL user, create a database and user (if not already created). You will be prompted for the password of the root MySQL user, which is by default network:
network@node4:~virtnet/data/webdemos/grades$ mysql -u root -p < grades-users.sql
As the newly created MySQL webdemo_grades user (which has password network), update the tables:
network@node4:~virtnet/data/webdemos/grades$ mysql -u webdemo_grades -p webdemo_grades < grades-tables.sql
Setup Malicious Web Sites on Node 5
Start the MySQL and Apache web server on node 5:
network@node5:~$ sudo service mysql start network@node5:~$ sudo apache2ctl start
Change into the directory that contains these instructions. Install both the "freestuff" and "ades" web sites on node 5. These are needed for a CSRF attack and unvalidated redirect attacks, respectively.
network@node5:~$ cd /home/network/virtnet/data/webdemos network@node5:~$ sudo mkdir /var/www/ades network@node5:~$ sudo chown network.network /var/www/ades network@node5:~$ sudo mkdir /var/www/freestuff network@node5:~$ sudo chown network.network /var/www/freestuff network@node5:~$ cp ades/www/* /var/www/ades/ network@node5:~$ cp freestuff/www/* /var/www/freestuff/
Setup Fake Domain Names
Rather than using the IP address of nodes in URLs, we will setup some fake domain names just for this virtual network. We will edit the /etc/hosts in each node so they are aware of the domains and their corresponding IP addresses. On all nodes edit the /etc/hosts by running the command sudo nano /etc/hosts. Add the following lines to the file:
192.168.2.21 www.myuni.edu 192.168.2.22 www.freestuff.com 192.168.2.22 www.myuni.edu.gr
If you are using a topology other than topology 7, than you need to modify the IP addresses above (to the IP address of the nodes running the web server for the grades website and the freestuff website, respectively).
Node 1 will be the normal user using a web browser to access the web sites. Node 2 may be another (malicious) user using a browser. As the nodes do not have a GUI, there are two approaches to using a web browser:
- Using a text-only browser such as lynx.
- Use SSH tunnelling to allow a browser in the host to access virtual nodes.
I suggest you setup both: by using Lynx it is easy to quickly manuipulate cookies, however some attacks (CSRF) make use of images, and therefore a GUI browser on the host is needed.
Lynx is a text-based web browser, allowing you to view websites via the terminal. You can start Lynx by typing lynx or passing a URL that you want to visit as a parameter, e.g. lynx http://sandilands.info/.
By default, Lynx does not save cookies when you close and restart, i.e. you will always be prompted about accepting cookies. To temporarily change so that cookies are saved, you can create your own configuration file called lynx.cfg with the following:
SET_COOKIES:TRUE ACCEPT_ALL_COOKIES:TRUE PERSISTENT_COOKIES:TRUE COOKIE_FILE:/home/network/.lynx_cookies COOKIE_SAVE_FILE:/home/network/.lynx_cookies PREFERRED_ENCODING:None
Or simply copy the configuration file in SVN:
network@node1:~$ cp /home/network/virtnet/data/webdemos/grades/lynx.cfg /home/network/
Now start lynx by:
network@node1:~$ lynx -cfg=lynx.cfg http://www.myuni.edu/grades/
Now Lynx will save cookies in the file /home/network/.lynx_cookies when it closes, and read from that file when you start Lynx again.
A quick guide to using Lynx:
- Scroll the page using PgUp and PgDown
- Traverse through links using Up arrow and Down arrow
- Follow a selected/highlighted link by using Right arrow or Enter
- Go back using the Left arrow
- Visit a new URL by pressing 'g' and then typing the URL
- To get help, press 'h'
- To see cookies, press Ctrl-k
- To toggle between viewing the web page and the source, press '\'
- To quit Lynx, press 'q'
You can use your normal web browser (e.g. Firefox, Safari, Chrome, IE) on your host computer to connect to the virtual nodes using SOCKS tunnelling. Once setup, your host browser will send requests to node 1, which then forwards them to destination node. I have instructions for setting up SOCKs tunnelling, using Firefox as an example. A web search for "putty socks tunnelling" will return many pages for specific instructions for other operating systems and browsers, e.g. 1, 2.
On node 1, visit http://www.myuni.edu/grades/. First get familiar with the basic grading system, then try some attacks.
First, a set of users and passwords are stored in a MySQL database. The passwords are stored in the clear (not hashed). This is insecure but sufficient for this demo. The values are:
- Faculty member that can view grades of all students and also edit grades: username - steve; password - mysecret.
- Students that can view only their own grades:
- username - 5000000000; password - student
- username - 5012345678; password - student
When a user visits the login page they enter a username and password in a form. The values are submitted to the web server that then compares them with the values in the database. If the values match, then the user is logged in.
Of course once logged in, the user should not have to login for subsequent accesses. Therefore upon login, the web server creates a cookie and sends back to the web browser. On each subsequent access, the browser sends the cookie and the server checks that the values are correct for this user (without accessing the database). The cookie contains two values:
- Hash of username and a secret value
The secret value is common for the website. When the cookie is sent to the web server, the server checks if the hash value submitted is the same as the hash of the username and secret value. The idea is that if an attacker wanted to pretend to be a logged in user, although they could guess/find the username, they must also have the correct hash value, and for that, they need to know the secret value. But they don't know the secret value because it is secret! (known only to the web server, not to any users). This implementation means that the server only needs to check the credentials in the database upon login, not upon each page access. It's quite fast.
Desired Security Policy
The grading system allows viewing/editing of scores according to the following policy:
- A user that is authenticated (logged in) can see the scores for either a selected course (by entering the course code) or for all of their courses (by leaving the course code blank).
- Non-authenticated users cannot see any scores.
- Authenticated users cannot see scores of other users, with the exception of (4).
- User steve (a faculty member) can see the scores of any users. He is the special user that can enter the student ID of another user and see their scores.
Lets now see several simple attacks agains the grading system.
If using Lynx as the browser (on node 1), press 'Ctrl-k' to view cookies. Alternatively, when you exit Lynx ('q'), the cookies are saved in the file /home/network/.lynx_cookies. Look in the file to see the values. Try copying the file to node 2 and then start Lynx on node 2. You should be logged in as the user who was logged in on node 1.
How does one user learn the cookie of another user? One simple method (which however may not be practical in some environments) is to capture packets on the network between the browser and server. In our virtual network, if you use tcpdump on node 3 (the router) while node 1 is browsing to the grading system web site, you should capture the HTTP request/response that contains the cookie. You can capture using the command:
network@node3:~$ sudo tcpdump -i eth1 -w file.cap
This will save the packets in file.cap, which you can then copy to your host computer and view in Wireshark. Alternatively, if you want to see the packets as they are captured (rather than using Wireshark), use tcpdump to show only HTTP packets:
network@node3:~$ sudo tcpdump -i eth1 -A -n 'tcp port 80 and (((ip[2:2] - ((ip&0xf)<<2)) - ((tcp&0xf0)>>2)) != 0)'
Some web sites have a "redirect" page, that redirects (or forwards) the user to another page or site. An example usage of a redirect maybe to prevent a warning before following links to external websites. For example, a government website may link to some commercial website. Rather than having a direct link link:
the user may instead be redirected to a warning page via the link:
The warning page may then display a message like We are not responsible for content on external sites and then (with another link or automatically after some time) forward the user to www.example.com.
There are different ways a malicious use could take advantage of a poorly implemented redirect page. One is a phishing attack. The malicious user creates an email or other web page that a normal user sees. Inside is a link like:
The user checks the domain in the link and notices it is a trusted domain: www.ministry.gov. But they don't look closely at the rest of the URL (in fact even if they do, they may not understand what it means). Therefore the click on the link.
The user expects to be taken to a page at the trusted domain www.ministry.gov, but the end result is they are redirected to another domain, presumably under control of the malicious user. The malicious user has several ways of taking advantage of this redirection ...
You can try the redirection attack on the grades web site, as there is a page called redirect.php that takes a parameter called url. Try redirecting to a malicious site, e.g. http://www.myuni.edu/grades/redirect.php?url=http://www.myuni.edu.gr/ades/login.php. Many users that see this link would identify the domain, www.myuni.edu as trusted, but in fact following the link takes them to an untrusted site (which as it turns out, has a similar domain, although it does not need to be).
What does http://www.myuni.edu.gr/ades/login.php do? Visit it and see. On node 4 (under control of the malicious user), after you visit that URL, look in the file /tmp/stolenlogins.txt.
An SQL injection attack involves injecting untrusted data into a system to perform unauthorised operations; this is done by taking advantage of SQL queries that many websites use to extract data. (Note that it doesn't necessarily mean injected data into an SQL database).
An SQL injection attack is possible due to poor programming by the web application developer; it is generally not due to bugs in the web server, processing language (e.g. PHP) or database (e.g. MySQL). Good programming techniques can help avoid SQL injection attacks.
This demo grading system is setup to allow an SQL injection attack. In particular, when logged in as one student, you can perform an SQL injection attack to view the scores of all other students (which according to the requirements, should not be allowed). How? When logged in as one student, try to view that students grades but set the course code to something like:
its335' OR '1'='1
You should see the grades of both students. To understand why this attack works, look at the SQL query created inside view.php.
This demo shows an example of a Cross Site Request Forgery. Note that it doesn't work in Lynx; you need to use Firefox or similar on your host, and then a proxy to the virtual node.
When a user is accessing the grade system, once logged in a cookie is stored by the users browser so that each subsequent request is remembered. The cookie is sent by the browser to the server in each request to identify that this browser is a logged in user.
Now lets say a logged in user has permissions to perform some operations that other (non-logged in) users cannot. For example, on the grades system, user "steve" is allowed to edit grades of students; other users (whether logged in or not). In the grade system, the editing of grades is implemented by steve selecting a new grade, that new grade being sent via a URL parameter and the database updating the grade. The URL is structured as follows:
where STUDENTID, CODE and GRADE are set to appropriate values.
The page updategrade.php also includes PHP code to check that the logged in user is "steve". Therefore if another user tries to visit this page (in attempt to change a grade), an error will be returned and the grade will not be changed. How does the server know that the request is from the user "steve"? Based on the cookie sent.
Try it. Login as user "5012345678" and visit:
You should find that the grade cannot be upgraded (if it can, then there is a serious error in the PHP code at the server).
Then how does a user (other than "steve") can a grade to change? By tricking steve, while logged in to the grade system, to visit some other website under the control of the malicious user, that contains a link to the updategrade.php page. A common way to do this is to create some normal website which has a hidden link. A hidden link can be created with an image of no size or iframe in HTML.
In this demo, there is a website on another server at:
If you look close at the source of that website you will see an image included of 0 size. It is not actually an image however, but a link to the grades system to update a grade. If user "steve" is logged into the grade system, and then visits this other FreeStuff website, his browser will automatically send a request to the updategrade.php page on the grades system. The browser will include his cookie for 192.168.2.21, and so the server knows he is logged in and accordingly updates the grade. The results is that the malicious user has caused steve to update a grade with him knowing.
I've provided instructions for setting up the virtual network and some fake websites on which common attacks can be performed. What to do next?
- Try the attacks, looking in the PHP/HTML source on the server and make sure you understand how they work
- Develop your own attacks on the demo web sites. See the OWASP Top 10 for suggestions for other attacks.
- Read the OWASP Top 10 and the many cheat sheets provided by OWASP to learn techniques for preventing these attacks.
The purpose of performing these web application attacks is to understand how they work so you can implement your web application to prevent such attacks. OWASP is an excellent source for further information on how to secure your web applications.
Created on Sun, 23 Feb 2014, 6:45pm
Last changed on Tue, 28 Apr 2015, 2:52pm