- Critical Thinking - Bug Bounty Podcast
- Posts
- [HackerNotes Ep.100] 8 Fav Bugs of 2024, Farewell Joel, Hello Shift - Cursor of Hacking
[HackerNotes Ep.100] 8 Fav Bugs of 2024, Farewell Joel, Hello Shift - Cursor of Hacking
It's the 100th episode! We've got some of the top hunters together to discuss their top bugs of 2024. We've also got a big CTBB pod announcement and a new (game-changer) plugin for Caido; Shift.
Hacker TLDR;
CTBB Announcement: Joel is officially leaving the pod. Fortunately, we’ve got plans to lure him back in as a guest on future episodes, so it’s not all bad 💔
Top Bugs of 2024: We’ve got some pretty impressive bugs of 2024 from a whole BUNCH of hunters. The writeups are pretty insane, so here’s a taste of what to expect:
Nagli’s Chain: Used deep recon and cloud asset enumeration to find a hidden Azure DevOps JWT, pivoted into Azure AD, compromised internal services, and ultimately gained admin-level access and sensitive data at scale. Bug bounty meets red team style.
Shub’s 6-Step RCE: Chained obscure headers and endpoints for SSRF, file writes, and DuckDB-based SQL injection to break out of a sandboxed environment and achieve pre-auth remote code execution.
Matt Brown’s NTP Trick: Exploited trust in NTP (Network Time Protocol) to manipulate device time checks, bypassing parental controls and potentially undermining time-based security logic in IoT devices.
MatanBer’s Client-side Sorcery: Crafted a clever client-side chain using sandbox escapes, frame hijacking, path traversal bypasses, and stolen CSRF tokens to perform full account takeover from a seemingly locked-down sandboxed Markdown environment.
Douglas Day’s Third-Party Pivot: Leveraged a third-party service to pivot into the main scope, starting with a strange-looking event calendar and turning it into a complete massacre of bugs on the service, ranging from arbitrary events appearing in the calendar to full-blown 0-click ATO in the third party.
Alex Chapman’s Headless Browser RCE: Turned a PDF export feature using a headless browser into a full-blown RCE by combining XSS tricks and a last-minute exploit rewrite for a time-limited 3x bounty multiplier.
NahamSec’s MVH Domination: Pursued tough-to-access-scope at a live hacking event, uncovered SSRF, multiple RCEs, and deep pivots - proving that expanding scope, going the extra mile and persistence pays dividends.
Shift Announcement: Shift, a new AI plugin for Caido. Think of it like Cursor, but built specifically for hacking. That’s exactly what Shift promises to deliver! Check it out here: https://shiftwaitlist.com/
CTBB Announcement
Well, it kinda feels like a breakup but Joel is stepping back from the pod. It’s sad to see him go but ultimately, it’s the best decision for him and we all respect that.
We’re planning on having Joel on future episodes as a guest, so hopefully we still get our dose of Joel v Justin (program manager v hunter) shenanigans, but it’s time to say goodbye.
Thank you, Joel!
Top Bugs of 2024
It’s our 100th episode, and we’re celebrating in style! This time around, we’ve invited some of the top hunters from the community to showcase their most impactful bugs of the year.
I’m gonna be honest, keeping up with some of these bugs was pretty tough. We’ve got RCEs, SSRFs, 0 interaction ATO.. the lot.
First up, we had Nagli. This one is a masterclass in creative thinking and next-level recon.
Nagli’s Top Bug of 2024
Recon Like a Pro
Starting with a wider target, Nagli hits the recon game hard. Using techniques to enumerate all domains, go through all the permutations of domains, content discovery and so on. One thing with targets which heavily depend on cloud technologies (most of them now) there isn’t a target-specific naming convention for the cloud resources.
Think about cloud platforms like Google Storage, Azure Blobs, or S3. The naming schemes can be totally random. You can’t just assume everything will be in the format company.service.com
. So, Nagli turned to reliable methods like analyzing JavaScript and scraping historical data via Wayback Machine to track down assets.
The Lucky Redirect
During cloud resource enumeration, one interesting resource stood out. It didn’t have the company’s name anywhere in its identifier, but it redirected to one of their domains. The catch? That domain didn’t resolve. It was a 302 client-side redirect, which might not seem like much at first glance.
Enter urlscan.io, the ultimate tool for mapping domain redirections. By running a scan on the non-resolving domain, Nagli discovered an Azure asset redirecting to it, effectively tying the resource back to the target company.
Jackpot in JavaScript
Digging deeper, one of the associated JavaScript files revealed an Azure DevOps JWT token. Collaborating with another researcher, they used this token to invite themselves as a guest account to the target’s Azure tenant. As a guest account, they gained access to the Azure AD infrastructure, which is already a critical finding. But the impact didn’t stop there.
Escalation
Trying to privesc this further, they pulled over 200,000 accounts from the Azure AD, including usernames, permissions, and email addresses. The goal? To find any email domains available for purchase. After stripping out the company’s primary domain (@target.com
), they were left with 50 unique email domains, tied to 100 different accounts, that were up for grabs.
Among these, they identified a suitable candidate - an account with permissions to other parts of the environment. Now the fun really began.
Pivoting to Internal Apps
Using earlier recon data, Nagli found some internal Azure-hosted sites and authenticated to one application, a CRM-like platform. Inside the app, they uncovered three separate vulnerabilities to escalate further:
SSRF (Server-Side Request Forgery)
RCE (Remote Code Execution)
LFI (Local File Inclusion)
Using each of these primitives, they managed to get admin access to the Azure Cloud instance, achieve mass PII & sensitive data exposure, and gain access to the internal ServiceNow instance.
Not bad for impact!
Here’s a visual breakdown of the full attack chain:
Shubs’s Top Bug of 2024
If you’ve followed any of Shub’s previous discoveries, you’ll know there’s a recurring pattern of pre-auth attack chains, often leading straight to RCE. This time, during a Live Hacking Event (LHE) on a well-trodden target that most hunters had already poked at, Shubs managed to string together a pre-auth exploit chain with six different steps to achieve RCE.
Diving In
When Shubs begins, he fires up tools like Process Explorer and Procmon to understand what’s running, gather context, and get a feel for the application. Among the usual suspects - Java, Apache - one service stood out: a small Node.js webserver. Many developers compile Node.js code into V8 bytecode, making it a serious pain to reverse-engineer. Because this is so tricky, a lot of hunters tend to skip it and focus on easier targets.
After deciding it warrants at least some effort on the target, he started trying to peel back what he could. The good news was the component was accessible in a way that required no authentication.
Hitting the endpoint also returned an error along the lines of “The URL is missing
.” If you see something like that, you probably have a feeling that there’s more beneath the surface.
After digging into the source code surrounding the component and reading the little documentation available, Shubs discovered it was used as an extension for add-ons to use in the software.
After digging around on NPM and identifying a similar package, downloading the package revealed that all server-side source code was within the package!
There was a caveat here. The code was minified, but that’s way easier to handle than V8 bytecode. Being able to dive into the source code even more, it turns out that it was essentially an SDK with an entire ecosystem. used to support different parts of the application.
There were also a few headers you could provide to a specific endpoint endpoint which, when used, loaded a file from the disk (as specified in the header) and loaded it into the SDK sandbox environment.
Pretty interesting lead so far, right?
OS-Specific Paths and Formats
What was interesting is the underlying host OS massively changed the attack vectors here. If it’s Windows, you can simply place a network path in the header to reach out whereas for Linux, you need the file to be local. More on this shortly.
Equally, the file format the endpoint was looking for was a glorified zip file; it contained some JS files and a manifest file which dictated what the plugin would do, kind of like a Chrome Extension file.
The next question: How does the app execute this file? Turns out it was run in an isolated VM sandbox. Shub’s first target was SSRF. The initial hurdle? Smuggling a local zip file onto the system and knowing its exact path. On Windows, not a big deal - just provide a network share. On Linux, authentication was needed, slightly tweaking the approach.
Although SSRF was possible, Shubs really wanted RCE. Examining the available attack surface in the sandbox, several default modules were accessible within it, including one for DuckDB that handled something called “parquet files”.
Enter DuckDB
Collaborating with Ryotak, they supplied a parquet file which, when loaded, triggered SQL injection (SQLi) in DuckDB. DuckDB has some inherently risky features. From here, the plan was:
Construct a ZIP containing a parquetfile.
Load the parquet file from a URL.
Embed an SQLi in the file, and trigger an SQLi in DuckDB.
Use SQLi to perform a file write.
Unfortunately, they weren't able to get Duckdb to load the SQL for whatever reason. Although they could load the file with the exploit in, it wasn’t actually executing the SQLi. This is where it gets pretty crazy.
They used the prior SSRF they found to communicate with a different port on the server which was responsible for managing DuckDb. Using this, triggers a refresh/load of the table inside DuckDb which would process the SQLi, and lead to the file write.
Insane attack chain so far, and I had no idea DuckDb even existed before this!
Finding the Perfect Spot for File Write
Now, where to write the file? In Tomcat setups, web.xml
sometimes references specific handlers for exceptions. For example, if exceptions occur use this specific handler to handle that. They found a handler for 500 errors pointing to a JSP file. Perfect.
They used the SQLi with a file write to replace the JSP file used for handling HTTP 500 exceptions with a shell, then triggered a 500 error. This caused the server to execute their shell, and voilà - RCE.
WHAT. A. CHAIN.
The TL;DR summarising this up is a bit nuts:
Find compiled JS binary mapped to a specific route
Hit that unauthenticated and upload a zip file
Zip file will run JS code in an isolated VM
From there, load a parquet file from a URL
Load this into DuckDB and get a SQLi
SQLi performs a file write in DuckDb
SSRF is used to hit a separate port to refresh DuckDb to trigger the file write
Use the file write to overwrite a JSP file acting as a handler for HTTP 500 errors
Trigger an HTTP 500 response
RCE!
Matt Brown’s Top Bug of 2024
Matt Brown recently shared a tonne of tips and tricks for hacking IOT devices on the pod, and this feature on the pod is no different.
Diving into NTP (network time protocol) on one target which was an IOT device allowing users to configure parental controls. A parent could give a device to a child and they could browse a limited set of media in a safe environment.
Parents could also set a bedtime on the device which would disable all of the media for that time. Using Douglas Days reference of ‘finding the no’s’ in an application, one of the ways an application can implement a no is by knowing what the current time is.
This raises the question: if an IoT device or mobile app enforces restrictions based on the current time, where does it get that time data from? Often, it’s from NTP servers, which are commonly used and inherently trusting-meaning they don’t perform many checks on incoming time data.
Enter Delorean (https://github.com/jselvi/Delorean), a MiTM NTP tool that Matt used to spin up a spoofed NTP server. By supplying any arbitrary time value, he tricked the IoT device into thinking it was midday, effectively bypassing all time-based restrictions. With the device convinced it was a different time altogether, the parental controls simply stopped working.
Now this threat model might not appear evident at first, but Matt mentioned this same threat model across different devices can be a lot more impactful. Smartlocks for example have configurations to set pins for certain times or certain people, and they can only use that lock at a certain time.
In other words, if a device’s security hinges on what it believes the current time to be, controlling its time source can lead to some seriously game-changing exploits.
MatanBer’s Top Bug of 2024
And of course, we’ve got some clientside sorcery with MatanBer.
Matan encountered a scenario where an attacker could make the site render malicious Markdown in the victim’s browser context. The site wanted to let Markdown load images from certain sources that would normally be off-limits, so it used a series of iframes to control this process.
The Frame Stack
Main Frame: The primary window hosting most of the content.
Bridge Frame: Nested inside the main frame, on a different origin.
Sandbox Frame: Inside the bridge frame and on the same origin as the bridge frame. This is where the sandboxed (and potentially malicious) HTML was rendered.
The bridge frame acted as a communication channel between the sandbox frame and the main frame. Even though any JavaScript could run inside the sandbox frame, a standard XSS in the subdomain didn’t mean much on its own due to the restrictions in place. However, the sandbox frame had a special feature: it could load images from the actual site (redacted.com) instead of just the sandbox subdomain.
Thankfully, Matan is an illustrator as well as a clientside hacker and whipped this up to help us understand the sorcery:
The Image Loading Flow
When the sandbox frame tried to load an image, it sent an HTTP request that a service worker intercepted. The service worker would then message the bridge frame, saying something like, “Hey, the sandbox frame wants this image.”
The bridge frame would pass that message to the main frame, which would validate the URL. If it pointed to redacted.com/images
, the main frame would fetch the image and send the data back down the chain-main frame → bridge frame → sandbox frame. Essentially, the frames acted like a proxy.
The browser normalized most path traversal attempts before they ever reached the main frame’s validation. But here’s the catch: since the sandbox and bridge frames shared the same origin, Matan could escape the sandbox frame and start executing JS directly in the bridge frame.
In the sandbox frame, they overrode window.parent
to be null
- so no parent.eval
could be used, but instead you could use parent.frames
to traverse and bypass the restriction.
Taking Over the Message Port
Matan’s next move was to hijack communication between the bridge frame and the main frame. The main frame sent a message port to the bridge frame, and they communicated via postMessage
.
Once Matan had JS execution in the bridge frame, he overrode MessagePort.prototype.postMessage
. By doing this, whenever the bridge frame tried to send a message through the message port, Matan’s malicious function would run instead. This gave him full visibility into, and control over, the communication channel.
With access to the message port, Matan tried to path traversal. As there were root paths that were allowed in the validation of the main frame on the URL, and surprisingly, the target implemented checks on the paths to see if they had ../
sequences.
However, they didn’t consider \\
- this meant Matan could send a request to target.com/images/whitelistedpath\\..\\target\\..\\path
With access to the message port, Matan tried to perform path traversal. The main frame had validation checks for ../
, but it didn’t consider the \
character. Using \
sequences, Matan crafted a URL like target.com/images/whitelistedpath\..\target\..\path
, bypassing the filter.
From there, Matan sent a GET request to an endpoint to retrieve the user’s CSRF token, then performed a POST request with that token to make changes to the user’s account, achieving full account takeover (ATO).
In summary, this chain was pure wizardry:
Inject malicious Markdown in a sandboxed frame.
Escape the sandbox by jumping to the bridge frame (same origin).
Hijack the message port communication channel by overriding the prototype.
Abuse path traversal using backslashes to bypass validation.
Steal a CSRF token and perform an account takeover.
Douglas Day’s Top Bug of 2024
Douglas’s idea of ‘no’s’ from this talk already had a feature earlier on, but the man himself is back with a super cool bug.
This one started on a target Douglas was hitting, and he found an interesting piece of functionality on a subdomain the company was using to broadcast and advertise upcoming events and product happenings.
At the bottom, there was a calendar for future events that they will be streaming and broadcasting. This tickled Douglas’s spidey senses and this led down the road of ‘What would happen if I could make my own event and put it on their calendar?’
Douglas started peeling back the functionality. Looking in Caido, a request was made to a third party that's an online streaming service that a company can use to host their services.
This third-party service had a free self-signup, so Douglas created an account on the streaming service and made his own events and content.
Looking at how the functionality around events was implemented, he initially discovered that organisations are assigned UUIDs. However, when pulling the calendar as a client, all of these UUIDs are actually embedded in the calendar itself, so that wasn’t much of a problem.
Next up: the classic IDOR test. Douglas tried changing some parameters in the requests to see if he could modify or create events. Sure enough, it worked. He uncovered multiple IDORs and even some XSS vulnerabilities. Although he wasn’t sure if the third-party service was in scope, he took a gamble and reported them anyway.
Going for ATO, he studied the user management functionality of the application. There were some restrictions here, but he noted there were two ways to add someone to an organisation.
You can email them or provide them with a link to go through the auth flow, and the link is linked to the email address invited. With this user in an invited state, he attempted to walk the signup flow.
This is where things got interesting. The user now existed on Douglas’s tenant within the streaming service. With admin rights, he could modify the victim’s email address. After changing the victim’s email to one he controlled, he went through the password reset flow and set a new password for the victim’s account.
Just like that, Douglas pivoted into the target’s tenant as the victim (admin) user -achieving a zero-click ATO!
Green hat Tip: If you find vulnerable endpoints affecting multiple actions (read/write/delete), report them as separate bugs to maximize your bounty potential!
Alex Chapman’s Top Bug of 2024
Alex Chapman’s brand is exploiting server-side headless browsers, and this bug is no different.
Spotting a target running a limited-time promotion offering a 3x multiplier on critical bugs and realizing there were only two days left, Alex decided to go all-in on this target.
The target had the functionality to export dashboards as PDFs. If you check the creator or producer within PDF metadata, it will tell you what it’s using and the precise versions in use of the PDF exporter. Sure enough, it was in fact a headless browser.
Unfortunately, there was a catch: there wasn’t any user data directly injected into the PDF, so Alex needed another primitive - an XSS.
Looking for an XSS vector, Alex noticed the dashboard creation feature included a rich text element, which seemed like a great avenue. Unfortunately, it was secured by a recent version of DOMPurify, killing that option.
However, when adding URLs as text, the app automatically turned them into clickable links with <a href="yoururl.com">
, and this happened after DOMPurify did its thing. That meant he could potentially sneak something in.
Side note - if your target is modifying your input after validation or sanitisation, it probably warrants an additional look.
One thing to note with server-side headless browsers, you can’t rely on events like onclick
because there’s no interaction. The payload has to be executed immediately.
Armed with PortSwigger’s XSS cheatsheet and some weird HREF behaviour, Alex managed to craft a working XSS payload using a malformed ontoggle
event which would trigger without user interaction.
Linking his XSS and his shell together, he fired the payload off and exported the dashboard as a PDF. Waiting for the shell back and… nothing happened. Panic time.
After panic debugging he managed to figure out that the browser had web assembly disabled, and the CVE he was using required web assembly to work.
Digging around for an alternative, he stumbled upon a Taiwanese blog detailing a similar exploit which didn’t require web assembly, he managed to write an entirely new exploit with 1 hour to spare. Running the exploit initially didn’t yield any results, running it 4 or 5 times produced a shell!
The exploit was shaky, but it worked. He submitted the report just in time, beating the deadline and cashing in on that sweet 3x multiplier!
NahamSec’s Top Bug of 2024
This one came out of H1-702 in Vegas. The targets this year were TikTok and Epic Games-two programs that, to be honest, weren’t exactly at the top of NahamSec’s favourites list before the event.
In a collab with Andre (https://x.com/0xacb) , they spent the first day focusing on one target and managed to land an SSRF. But NahamSec had his eyes on the MVH (Most Valuable Hacker) title, which meant he needed to make sure both targets took a hit. For those who don’t know, MVH basically requires you to crush every target at a Live Hacking Event.
NahamSec took a gamble, attempting inline RCE payloads across the second target until he got the faintest hint of a vulnerable endpoint. With Andre by his side, they dug deeper into that lead and struck gold.
By the end, they’d pulled off 3 RCEs on TikTok and 2 RCEs on Epic Games, plus a handful of high-severity bugs. That’s a seriously wild performance.
Part of their success came from going all-in and expanding their scope. NahamSec even signed up his own business as a legitimate customer to access functionality most hunters would’ve avoided.
One takeaway here which always pays dividends is: TAKE THE PLUNGE TO UNLOCK THAT ATTACK SURFACE!
Shift Announcement
We’ve got a big one to share: Shift, a new AI plugin for Caido. Think of it like Cursor, but built specifically for hacking. That’s exactly what Shift promises to deliver!
Check it out here: https://shiftwaitlist.com/
The product is still in Beta, but does contain some pretty useful features. Caido will have a dedicated command shortcut which opens up the Shift window and it will have dynamic content and actions depending on the tab you’re in.
Naturally, Shfit can only extend requests based on Caidos SDK, but it’s pretty darn impressive. If you’re looking for a tool to reduce friction and increase productivity when hacking this is basically it.
A sneak peek at some features from the pod and prelaunch site:
Copilot-style Hacking: Get real-time suggestions and automated assistance while you hack, just like having a senior penetration tester by your side.
Natural Language Control: Control Caido with simple English commands. No more memorizing complex syntax or digging through documentation.
Customizability: Customize Shift to your needs with custom memory, instructions, and tab-naming logic for a personalized hacking experience.
Some use cases:
Wordlist Generation: Generate context-aware wordlists tailored to your target application, improving your discovery of hidden endpoints and parameters.
Mach & Replace: Effortlessly (and quickly) create match & replace rules to modify requests on the fly.
Request Editing: Rapidly modify HTTP requests with AI assistance, from formatting fixes to generating payloads.
I’m gonna be honest, I’ve been using Burp up until now but this has pushed me to try Caido. I’ll keep y’all posted ;)
Aaand that’s a wrap. Awesome 100th episode this time around, some really cool war stories from the hunters and a very much welcomed tool.
As always, keep hacking!