- Critical Thinking - Bug Bounty Podcast
- Posts
- [HackerNotes Ep. 65] Motivation and Methodology with Sam Curry (Zlz)
[HackerNotes Ep. 65] Motivation and Methodology with Sam Curry (Zlz)
The guys sit down with Sam Curry to discuss the ethical boundaries of research, his methdology and approach to his research, and a bunch of other cool bugs he's found.
Hacker TLDR;
Secondary Context Bugs: The TL;DR is modern applications usually need to integrate with other APIs but need that integration to happen on the same origin. Instead of sending requests all from the client they instead use a route (or directory) https://example.com/api to communicate with an API. Problems arise when unexpected user input is sent via the route to hit the backend API - full writeup below.
Tips for finding secondary context bugs:
Lots of times secondary context is blind, meaning you can’t see the full HTTP response from the request
Building out a map and understanding of how control characters modify the response. Ie a & does this behaviour and a # result in this behaviour, helps identify where your input is being placed in a request
Using special characters to cause stack traces can reveal verbose information about the underlying request, or even cause backend API keys to leak
A good wordlist to brute force paths in a blind secondary context scenario is the Serverside variable names list in burp
When looking at directory structure think about the following: Are they using camelcase? Any separators between words? Any unique naming conventions I can use to try and enumerate more paths?
Try normal path traversals to determine any differences in behaviour or responses
Do different endpoints return different sets of headers or different content types?
Iterate through the hex range %00 - %ff when fuzzing to uncover any characters which may not be handled properly
Unicode characters can be used to bypass filters
A good tool to help generate fuzz lists to use for traversals: https://github.com/0xacb/recollapse
Dont force yourself to become a bug bounty hunter: If you’re struggling to get stuck into bounties or feel overwhelmed with the number of things you think you should be doing, maybe trying to spin the perspective of hacking things you find fun, and out of curiosity instead of financial motivation when approaching hacking will help. Full link to post here.
Sam Currys Research: Sam’s research on how he pwned ISPs, Tesla, airlines, JS frameworks and a bunch more is detailed below. It was too much to fit into a bullet or two!
Sam Currys Research
If you haven’t heard of Sam Curry directly, you probably have heard about some of his research indirectly. He’s hacked Tesla, pretty much the whole car industry, airlines, Starbucks, gambling sites - you name it, he’s probably published research on it.
A lot of the hacking he does is based around fun and curiosity now instead of bug bounties. Starting out, however, the motivation was initially financially driven from bounties.
If you haven’t seen some of his work, be sure to check it out here: https://samcurry.net/blog/
Some of this research seems to blur the line as technically there is no authorization to research initially. As Sam is researching out of good faith and now has a bit of a brand from his research and is trusted, it’s usually perceived quite well by security teams.
In one instance this didn’t go smoothly with one gambling company. Sam identified a vuln which allowed him to generate an unlimited balance in the application, with a POC generating over $3m balance in total.
When reporting this to the company, Sam was greeted with the warm words ‘..so you’re the one who committing fraud on our slot machines’- something no ethical researcher ever wants to hear - fortunately, after further communication and explanation of his research this was smoothed over.
The reason Sam was greeted with that response is because of how these companies are operated. Some game providers are sub-companies which sell their products (in this instance slot machines) to gambling websites.
What ended up happening in the background was the gambling website saw a certain slot machine had generated $3m in payouts and cut ties with the company associated with that game because of it.
Luckily, as this research was in good faith there was understanding from all sides - you’d rather a white hat find the problem than it be exploited for malicious intent right?
Dont force yourself to become a bug bounty hunter
Sam released an interesting blog about trying to foster the passion for hacking instead of forcing yourself to do bug bounty, if you haven’t seen the post check it out here: https://samcurry.net/dont-force-yourself-to-become-a-bug-bounty-hunter/
The premise of the blog is to use your passion for hacking as a motivator instead of financial, as you’ll get a lot further by doing the former.
When Sam wrote the blog it was at a time when lots of people were reaching out to him asking for mentoring, tips, where to get started etc. Not everyone does the military style of learning by doing courses, training, and a strict study schedule.
Equally, Sam didn’t approach bounties like this. Instead of reading books and doing courses he’d instead try to figure out how a game he was playing accounted for balances or in-game money. This fostered his passion a lot more naturally and took his interest a lot further than the route of reading or doing a course for example.
If you’re struggling to get stuck into bounties or feel overwhelmed with the number of things you think you should be doing, maybe trying to spin this perspective when approaching hacking will help.
Secondary Context Bugs
Sam Curry originally coined the term ‘secondary context’ related bugs in his research and presentation here: https://www.youtube.com/watch?v=hWmXEAi9z5w&ab_channel=Kernelcon
What originally started this research was hacking Yahoo’s Luminate application; a small business platform for deploying small businesses.
He originally found it strange behaviour and thought it was a file path traversal bug. After hunting around on other targets and recognizing the architectural pattern of serving static images from a single path such as /cdn
on the same origin (even though it was hitting their external CDN) and researching how this was implemented, he realized certain routes are being proxied to other hosts entirely.
The TL;DR is modern applications that need to integrate with other APIs but need that integration to happen on the same origin - https://example.com for example.
Instead of sending requests all from the client side and opening up a whole other bunch of problems, they instead would use a route (or directory) https://example.com/api to communicate with an API.
On the backend, this route, /api
, is actually hitting https://internalapi.example.com/. In order to pass in user IDs or other parameters to facilitate responses from the API, they are often grabbed from the POST body or URL of the initial request to /api
.
This would result in https://example.com/api?userID=5 on the front end making a call to https://internalapi.example.com/api/user/5 for example.
Let’s jump into some cool writeups from Sam exploiting this behaviour.
Hacking Starbucks
Back in 2020, Sam and Justin teamed up on a bug and ended up hitting Starbucks hard. Sam was searching for endpoints to target with secondary context-esque payloads, and ended up finding some interesting behaviour on an endpoint GET /bff/proxy/stream/v1/users/me/streamItems/
After some traversal payloads and studying different behaviours from each, they teamed up to enumerate each endpoint on the backend. This ended up in the below payload:
GET /bff/proxy/stream/v1/users/me/streamItems/web\\..\\.\\..\\.\\..\\.\\..\\.\\..\\.\\..\\.\\search\\v1\\Accounts\\
Which leaked over 100 MILLION user records.
To dive into the methodology a bit more and the behaviour which led them to that, check out the full writeup here: https://samcurry.net/hacking-starbucks/
Hacking ISPs
Sam also dived into some ISP hacking after his interest peaked when an engineer remotely changed his router password as part of some troubleshooting for problems he was having.
After researching the ISP and how this was done, it turns out an application called Sail was used on the back end. This allowed remote administration of routers and modems by both users and customer support agents.
This allowed support to be able to perform steps such as updating firmware, resetting passwords, and DNS settings - essentially complete remote administration of the router without being in the LAN.
After investigating the business management version of the application, the business version offered more functionality which presented a bigger attack surface. In the business version, there was a secondary context bug which allowed him to traverse down and access swagger files for the underlying APIs the Sail application used.
Further digging on the site's APIs revealed an endpoint that allowed the execution of Sail commands. Crucially, Sam also discovered a vulnerability that leaked the secret used to encrypt the router serial number within this API flow.
This allowed him to encrypt or decrypt any router serial number passed in the flow, and the router serial number was the only thing needed to administer one of the devices remotely. This meant he could completely compromise remote devices with their serial number.
Cool bugs, but how do we find them? Here are some tips and questions for finding secondary context bugs:
Do different endpoints return different sets of headers or different content types?
Lots of times secondary context is blind, meaning you can’t see the full HTTP response from the request
Building out a map and understanding of how control characters modify the response. Ie a & does this behaviour and a # result in this behaviour, it helps identify where your input is being placed in a request
Using special characters to cause stack traces can reveal verbose information about the underlying request, or even cause backend API keys to leak
A good wordlist to brute force paths in a blind secondary context is the Serverside variable names list in burp
When looking at directory structure think about the following: Are they using camelcase? Any separators between words? Any unique naming conventions I can use to try and enumerate more paths?
Try normal path traversals to determine any differences in behaviour or responses
Iterate through the hex range %00 - %ff when fuzzing to uncover any characters which may not be handled properly
Unicode characters can be used to bypass filters
A good tool to help generate fuzz lists to use for path traversals https://github.com/0xacb/recollapse
Hacking Tesla
A bug in Tesla's system had a similar starting point to the others. Sam, a Tesla owner, was fascinated by the Tesla API. The API offers rich functionality for Tesla owners to perform a wide range of actions on their cars; when a car has an API, there's undoubtedly a lot of cool stuff you can do with it.
A common implementation with JWTs (JSON Web Tokens) is to use a signed JWT with a value in a claim such as [email protected], and then use this value to compare a provided value within the request, such as in the URL, to see if they match. If they do match, it's authorised. If they don’t match, it's unauthorised.
In Tesla's case, they did this but used a vehicle ID instead of an email. They were using a particular integer parsing mechanism, which meant that if you added 1234/abc
, parseInt
would be run on the string and it would only return the number 1234
.
In the logic check, it would pull out the parseInt
input, check if it's valid, and if it is, take the value provided and use it to send a second request.
This means you could provide yourid%2f..%2fvictimid
, which would bypass the authorization check, but actually take the victim ID and hand that to the second request. This resulted in an authorization bypass, allowing you to gain access to the victim's vehicle.
This works because parseInt
behaviour in JavaScript - if you pass a string of 1234/test
, it will only return 1234
.
Although not necessarily directly related, if you are looking at a PHP target, you can provide an attacker ID in a URL query parameter and a victim ID in the post body to potentially bypass checks in some cases and to hit the victim ID, or vice versa.
Next JS Research
If you aren’t familiar with NextJS, it is a framework which does both front and backend in JS with lots of companies it, especially in the crypto world.
The thinking was if you can pop an XSS on the framework most of the crypto exchanges use, nextJS, then there’s a big integrity issue across all exchanges which could be catastrophic to the crypto ecosystem.
Sam teamed up with Shubs to go deep into the source code. An interesting piece of functionality cropped up during the review which was for the image optimization functionality within the library.
This research resulted in a header being discovered which could override the external URL the framework reaches out to and subsequently caches it. It also supported SVG files, so you could specify an SVG file called %2ftest.html
and it would cache the payload, which could then be sent to anyone else.
On hardened targets that take their security seriously like Crypto exchanges more often than not third-party integrations, JS imports and sometimes frameworks themselves will likely be the downfall as they aren’t as heavily scrutinized as much as the source they write in-house.
The full writeup for this one can be found here: https://samcurry.net/universal-xss-on-netlifys-next-js-library/
It’s worth adding that not all research yields results though. Sam recalled his interest being peaked in an airport by a robot coffee-making arm; Tesla also had one in their office and dived into the rabbit hole trying to pop the arm.
The security was locked down and he didn’t uncover any bugs, but in contrast, when hacking on an airline company such as Delta for a few hours, he uncovered a crit. Sometimes, targets are hardened but you won’t know till you give them a go.
Now this guy has so much good research you should probably go and read it all if you can. You can find it all on Samcurry.net and hackcompute.com
As always, keep hacking!