Sunday, September 29, 2013

Inline API Hooking using DLL Injection

In this post I'm going to share one simple example of user more inline API hooking technique using DLL injection. This type of API hooking techniques are widely used for many good and evil purposes. Many user mode or Kernel mode malwares use this inline hooking technique to do bad many bad stuffs.

Please remember this information is for Educational Purpose only and should not be used for malicious purpose.I will not assume any liability or responsibility to any person or entity with respect to loss or damages incurred from information contained in this article.

Inline hooking is implemented by overwriting first bytes codes of any API in order to redirect code execution flow. This type of technique can also be implemented in Kernel land.

So when an inline hook is implemented first instruction of target API is overwritten with a JMP instruction. One example is given below where User32!MessageBoxW is hooked.


First I will write a Hooking dll, and when the dll is injected into any remote process it will hook the function MessageBoxW using inline hooking technique. 

int WINAPI MessageBox(
  _In_opt_  HWND hWnd,
  _In_opt_  LPCTSTR lpText,
  _In_opt_  LPCTSTR lpCaption,
  _In_      UINT uType
);

And it will simply modify the 3rd argument (MessageBox Title ) of the MessageBox API with an another text message (MessageBox Owned!). 

The DLL code is given below:


Run time Analysis:

So now lets attach the hooked process with Immunity Debugger and see how this code works. In this case we know that Notepad.exe uses User32!MessageBoxW API to show alert messages when you try to find any word in any text file. So we will inject the compiled DLL into Notepad process.

First we get the PID of Notepad.EXE from Process Hacker Tool.


Then we inject the hooking DLL into Notepad.EXE process. And when we trigger the MessageBoxW call, we can see the Title of the Alert box is overwritten with the text "MessageBox Owned!".


This is the normal stack structure when MessageBoxW is called.


In below screenshot we can see, when the dll is injected, first instruction of MessageBoxW is overwritten with a JMP instruction and the JMP points to somewhere inside the injected dll (inline.dll)


Below screenshot shows the evil code, inside inline.dll file.


And W00t!!


Detection of Inline Hooking:

There are many free rootkit detection available on the internet.Almost all of them can detect this type of inline hooks(Both user mode and Kernel mode).

Reference:

https://www.htbridge.com/publication/inline_hooking_in_windows.pdf

Thursday, September 26, 2013

Hacking Twitter for Fun - XSRF in Account Settings Change

Though for last few months i'm not much into web application security, But still I feel Web App Sec. is fun. For a special requirement I had to develop a web application security assessment tool ( I think it will be better if I call it Fuzzer) and it was time to give it a real life challenge. I named this tool Burpy. because this tool is totally dependent on very famous application security assessment tool Burp.

Using this tool you can easily write your own web application specific plugins to automate various test cases.  You have to feed this tool a Burp suite traffic log (XML dump of http request & response). And depending on the module you write, this tool performs various test cases on the raw http request present in burp suite log.

You can find the details of this tool on my Git Hub Page.

I decided to test it on twitter.com first and unexpectedly I found a very simple yet critical Cross Site request Forgery vulnerability in twitter application.

I started surfing twitter randomly and at the same time burp proxy was enabled and it was logging all request response(twitter traffic). If you've ever played with twitter application before, you may aware of this issue that, if you send any request without CSRF token, twitter application throws a generic error message. And csrf token parameter name is also fixed.

So after that I quickly wrote a tiny Burpy plugin which simply automate below points:


  1. Check if CSRF token present in raw request.
  2. If csrf token present , then it will simply remove the token from request and resend the crafted request.
  3. If the generic error message is present in response body, It means server side check of csrf token is properly implemented hence it will return FALSE else it will return positive response and burpy will write that crafted request and response to final HTML report.


After that I quickly exported the traffic from burp suite (Twitter traffic) and quickly ran the tool on the dump.



It took nearly 5-6 minutes to test all(~~140) request present in the burp log, When its over I opened up the HTML report generated by it and found total 7-8 suspicious/interesting server response. Out of those I found 2 request which was looking interesting. Most critical one is covered in this post .The vulnerability was present in account settings change module. If you've ever played with twitter application you should know that, all profile information changes are handled by this url at server side.

https://twitter.com//settings/accounts/update

Base Request found from Burpy report:


POST /settings/accounts/update HTTP/1.1
Host: twitter.com
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:20.0) Gecko/20100101 Firefox/20.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
Referer: https://twitter.com/settings/account
Cookie: <removed>
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 670

_method=PUT&authenticity_token=88ab8ef7388e544f1c8f22d58xxxxxxxxxxxxxx&user[screen_name]=debasishm89&user[email]=myemail@gmail.com&user[discoverable_by_email]=1&user[discoverable_by_email]=0&user[lang]=en&user[time_zone]=New+Delhi&user[geo_enabled]=1&user[geo_enabled]=0&user[nsfw_view]=1&user[nsfw_view]=0&user[nsfw_user]=0&user[protected]=0&user[use_cookie_personalization]=1&user[use_cookie_personalization]=0&asked_cookie_personalization_setting=1&user[allow_ads_personalization]=1&user[no_username_only_password_reset]=0&user[login_verification_type]=off&user[country]=xx&auth_password=



Crafted Request found from Burpy report:


POST /settings/accounts/update HTTP/1.1
Host: twitter.com
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:20.0) Gecko/20100101 Firefox/20.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
Referer: https://twitter.com/settings/account
Cookie: <removed>
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 670

_method=PUT&&user[screen_name]=debasishm89&user[email]=myemail@gmail.com&user[discoverable_by_email]=1&user[discoverable_by_email]=0&user[lang]=en&user[time_zone]=New+Delhi&user[geo_enabled]=1&user[geo_enabled]=0&user[nsfw_view]=1&user[nsfw_view]=0&user[nsfw_user]=0&user[protected]=0&user[use_cookie_personalization]=1&user[use_cookie_personalization]=0&asked_cookie_personalization_setting=1&user[allow_ads_personalization]=1&user[no_username_only_password_reset]=0&user[login_verification_type]=off&user[country]=xx&auth_password=


The BUG:

As you can see,an anti CSRF token is present in this base request which is "authenticity_token". At glance which was looking fine and quite secure. But the interesting part was, when Burpy removed the CSRF token from the http request and replayed the request, It did not get the generic error message in response body. After manually repeating the step I found that, the server side logic was actually getting failed to validate the token and it was accepting the request.

Now when I went back to my settings page I found all changes I have made are getting reflected. BINGO!!

Another interesting thing you many notices in twiiter that, to change any profile settings if you go to "https://twitter.com/settings/account" page and make any changes, you will find the twitter application will ask you to re-enter your password. In this case even it was not required.

Its time to reproduce the BUG from Twitter:


So from Burpy report I got the crafted request/response but I had really hard time to reproduce this issue because, it was clear that I had to remove csrf token from the POST request but I was unable to find out above mentioned POST parameter combination in any request that twitter sends. I went to settings page made some chnages and when I was clicking save I found that POST parameter combination was not same which were reported by burpy. Spend a whole day to solve that mystery. But finally I found that it was actually one regular expression bug in Burpy which was polluting few POST parameters. And the best part was without that this bad things wont workout.






I hope I don't have to explain much about the criticality of this bug.

Another similar issue I've found on twitter : Here

On 31st August I reported this & this issue to twitter security team using their online form.
Received response from one engineer at Twitter Security Team on 3rd September'2013 saying they have received the report and not to twit or blog about this issue as they are working on a fix.



Twitter fixed this issue pretty fast. On 4th of September I've received one email from Twitter Security Team saying, that the issue is fixed and they need confirmation from my side.



And the last but not the least - The Ultimate CV Builder :D

Twitter doesn't pay security researchers for bugs but they do have a Hall of Fame Page for White Hat Security Researches. So they have added me in that White Hat page. :)





Twitter XSRF Vulnerability - Thanks to Miley Cyrus.. ;)

If you are following Miley Cyrus on Twitter, you may notice that for last few months her maximum twits are getting censored by twitter's automatic explicit/18+ content filter.


When twitter automatically hides any explicit or 18+ content , it also shows a notification like below by which you can permanently disable that filter for your twitter account.


So when you click on that Always Display media like this hyper link, client side code sends below raw request to server.


POST /i/expanded/update_view_possibly_sensitive HTTP/1.1
Host: twitter.com
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:20.0) Gecko/20100101 Firefox/20.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: https://twitter.com/MileyCyrus
Content-Length: 107
Cookie: <removed>
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

authenticity_token=88ab8ef7388e544f1c8f22d58bd0d6XXXXXXXXXX&do_show=true&scribeContext[component]=tweet


Where the CSRF token parameter name is "authenticity_token".At glance which was looking fine and quite secure. Now the interesting part was, when I removed the CSRF token from the POST request and replayed the above request, I noticed that server was accepting the request and saving changes.

BINGO!!!

This issue is fixed on 4th of September after I reported this issue to Twitter Security Team. 

Also they have added me in Twitter Security Hall of Fame : https://twitter.com/about/security

This issue was also identified when I was testing Burpy. And the module I wrote for twitter application is available here.