0

How I got access to many PIIs through a source code leak

Hi everyone !

My blog has been unpublished for almost a year now, so I needed a new post … Here is an write-up from a recent P1 found and exploited on an external bug bounty program which led to a leak of many PII (Personally Identifiable Information).

Recon time

It all starts with a Slack notification that a new subdomain has popped up.

Browsing on it and thanks to Wappalyzer, I quickly identify the technologies of the site: PHP, Apache2 and probably MySQL database. A classic web stack !

 

Content discovery

With ffuf and my custom wordlists, I decide to do some content discovery looking for juicy files and hidden directories.

ffuf allows via its -e flag to fuzz specific extensions. No need to put them all (asp, aspx, jsp etc) knowing that our application is written in PHP.

ffuf -mc all -c -H "User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:72.0) Gecko/20100101 Firefox/72.0" -u "https://crm.mytarget.com/FUZZ" -w ./my/wordlist -D -e js,php,bak,txt,html,zip,sql,old,gz,log,swp,yaml,yml,config,save,rsa,ppk -ac

After a few minutes, I came across a pretty juicy result :

Look at the size of the zip … time to download and analyze !

Analyze time

After unzipping our dev.zip, I find no less than 14000 directory and 65000 files. Just this ! 🥲

Being a lazy sysadmin, it is out of the question to manually search each file for « suspicious » information. Before automating, I need to know what I want to look for :

  • Harcoded credentials
  • API key, token
  • Any other necessary information that could increase the impact

I chose two tools to complete these tasks : DumpsterDiver and EarlyBird.

DumpsterDiver

DumpsterDiver is a fantastic tool written in Python that will allow us to analyze large volumes of data in search of secrets, API keys and other « possible » leaks. It has an incredible number of features and customization possible depending on what you want. In my case, I don’t have time to spend 3 hours on the documentation, it’s bounty fever, so let’s make it simple.

To install it :

$ git clone https://github.com/securing/DumpsterDiver.git
$ cd DumpsterDiver && pip3 install -r requirements.txt

Time to launch it :

$ python3 DumpsterDiver.py -p /my/directory/dev --exclude-files .png .jpeg .jpg >> ./dumpsterdiver-output.txt

And after a few hours of scanning (I cleaned the output) :

[...]

FOUND HIGH ENTROPY!!!
The following string: <API_KEY> has been found in /my/directory/dev/anotherdirectory/class/fixtures.sql

FOUND HIGH ENTROPY!!!
The following string: <TOKEN> has been found in /my/directory/dev/anotherdirectory/class/fixtures.sql

[...]

EarlyBird

EarlyBird is an another fantastic tool written in go that deserves to be known. As indicated on their page, « EarlyBird is a sensitive data detection tool capable of scanning source code repositories for clear text password violations, PII, outdated cryptography methods, key files and more. It can be used to scan remote git repositories, local files or directories or as a pre-commit step. »

To install it, nothing could be easier.

$ git clone https://github.com/americanexpress/earlybird.git
$ cd early bird && ./build.sh && ./install.sh

A binary is then generated in /usr/local/bin.

$ which go-earlybird
/usr/local/bin/go-earlybird

In my case, EarlyBird will be used to detect potentially hardcoded passwords in the source code. I will only load one module for this :

$ go-earlybird --path=/my/directory/dev -enable password-secret | tee earlybird-output.txt

Manual analysis

While the scans were running, I was able to do a manual analysis of the application to learn more about this web app.

It was also necessary, as soon as the DumpsterDiver and EarlyBird scans were finished, to concatenate the results and sort out any false positives.

After a few more hours of work, here is what I had in my possession :

  • The web application is based on SugarCRM, a customer relationship management software.
  • I have an uploads folder, containing various product photos, customer invoices, delivery notes, shipping notes etc.
  • I have the credentials of the SQL database
  • I have administrator credentials for back-office access
  • I have many API keys, secret, token in my possession (spoiler: we will use them for the rest of the article)

So I have a nice P1 in my possession, but why stop there ?

Playing with APIs

Validity

By manually analyzing the application, I realized that the SugarCRM and everything around it (stock management, shops, customers, orders etc) is linked to the APIs of Capillary Anywhere Commerce, provided by Capillary Technologies which publishes itself … SugarCRM.

To play with the APIs in question, you need three things :

  • Merchant ID
  • Public key
  • Secret

Following the official documentation, you can test the validity of a public key with the following call :

$ curl https://www.martjack.com/developerapi/OAuth/Token/<PUBLIC_KEY>

If a JWT is returned, then the key is valid.

Headcache

My credentials are valid, yay.

But that’s where the problem starts … Apart from the API call seen above, I can’t interact with the APIs despite everything that is asked.

I can’t find any way to authenticate to the server : all I get is a 401 Unauthorized.

  • Pass the headers manually with curl
  • Using Postman
  • Analysis of the source code and APIs calls harcoded but my nulity in PHP caught up with me very quickly (No judgments: I can make a phpinfo appear)

 

Collab for win

I let a few days go by to see if I had any other ideas while re-re-re-re-reading the APIs documentation.

And … I was still stuck.

Determined not to give up, I needed the help of someone better than me. Knowing his hacking skills, and having already discuss with him some time before on a private H1 program, I contacted Shubs.

After exchanging about my problem, and after some source code analysis, he generated a few hours later a PHP script able to communicate with the Capillary APIs. While I spent several days on it … Collaboration is key, right ? 😏

PII’s time

Now that we can interact in an authenticated way with the APIs, we can hit them to retrieve confidential information.

No need to list them all, only some are of interest to us.

Retrieve the list of all customers

https://www.martjack.com/DeveloperAPI/Customer/<MERCHANT_ID>/All

Detailed information about a specific customer

https://www.martjack.com/developerapi/Customer/<MERCHANT_ID>/<CUSTOMER_ID>

We can also :

Get order history

https://www.martjack.com/developerapi/Order/History/<MERCHANT_ID>/

Get store informations

https://www.martjack.com/developerapi/Store/Information/<MERCHANT_ID>/

Disable user account

https://www.martjack.com/developerapi/Customer/DeActivation/<MERCHANT_ID>/<USER_ID>

And many more …

All of this allowed me to prove the impact and recover PIIs, which is what I wanted by playing the APIs

For thoses who are interested, the script used to interact with the APIs can be found here. The output is in XML, it must then be parsed ( grep -oPm1 « (?<=ValueYouWanted>)[^<]+ » for example)

To conclude

This was a really cool bug to exploit even though I swore a lot while working on it. Thanks to Shubs for his collaboration and Hisxo for reading the article before publication ! 🙃

If you liked it, don’t hesitate to share!

Supras

S’abonner
Notification pour
guest

0 Commentaires
Le plus ancien
Le plus récent Le plus populaire
Commentaires en ligne
Afficher tous les commentaires