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!

How I made $64k from deleted files — a bug bounty story- 1639

Sharon Brizinov    Reference →Posted 10 Months Ago
  • git is a distributed version control system used everywhere. Under the hood, the entire history of the repository is tracked. Git has blobs for the files, trees for the directory structure, and comments for snapshot information. A blob is a large binary object that is saved based upon the sha256 hash of the contents and is zlib compressed. Many of these are compressed into a single file called a pack when they are no longer referenced by other objects (dangling).
  • The commit history represents a snapshot of the repository at a point in time. They store a reference to a ree object, pointers to parent commits and metadata.
  • When a file is removed via git rm, they can still be accessed because the history is immutable. The data of a commit is stored forever in the .git/objects folder. Additionally, the pack files contain information that is no longer referenceable by normal means.
  • The author wanted to target all dangling objects by traversing commits with their parent commits. If a file was dangled and deleted, they dumped it to disk. More there, they would run the tool TruffleHog to check for secrets on the repo. TruffleHog supports over 800 different secret formats! They also have a verify-only flag that will check if the secret is valid or not.
  • My main question, which they cover, is why not just use TruffleHog from the beginning? It will often skip .pack files if they were too big. By uncompressing these ourselves with the mechanism from above, TruffleHog can do its magic like normal.
  • They scanned a crazy number of projects doing this. They found the organization names by looking at various GitHub repos with names, using the GitHub search and directly with repos over 5000 stars. All in all, they made 64K off of this research. This goes to show that novel research pays. There were a large number of false positives. In particular, dummy users for testing and canaries were very common.
  • Why does this happen so much? The author claims that many developers just don't understand how git works with regard to deleting files. Additionally, bad .gitignores including .env and binary files were common as well. Overall, great research!

Hacking the Xbox 360 Hypervisor Part 2: The Bad Update Exploit- 1638

Grimdoomer    Reference →Posted 10 Months Ago
  • The author of this post was hunting for vulnerabilities in the XBox 360 hypervisor. While doing this, they noticed the system call HvxKeysExecute that allowed running small pieces of ad-hoc code in hypervisor mode with code signed from Microsoft. They pulled down 25 of these payloads and found a vulnerability in one of them: Bad Update.
  • The Bootloader Update Payload for the HvxKeysExecute instruction is the one being attacked. It reads data from kernel mode and performs LZX decompression on it. This requires a scratch buffer on store the data structure with lots of interesting pointers to jump tables and such. This buffer is relocated to encrypted memory but NOT protected mode. The idea is to overwrite this pointer to hijack the control flow later on.
  • Encrypted memory is a section of memory on the XBox that is in the Hypervisor but modifiable by the kernel. Because of this, it's typically only used in a write-only fashion. In the vulnerability above, we want to modify pointers that are encrypted and used by the Hypervisor. The encryption of this memory uses a per-boot key and a 10-bit whitening value that is unique to the address and cache line. This prevents simple oracles or reuse across resets/reboots.
  • There's still wiggle room for an encryption oracle here: we need an encryption oracle with a specific whitening value and just find an encryption oracle. Luckily, the encryption oracle is built into the Hypervisor with the HvxEncrypted set of APIs. For the whitening value, we need a known value for those that we can compare against for part of the contents. This means we have a complete oracle!
  • Encrypting arbitrary data with the whitening value matching allows one to edit the encrypted memory. First, they tried editing the malloc and free pointers - this didn't work because of cache-line issues. Instead, they overwrote the dec_output_buffer (output of the decompression process) pointer to get a controlled write to another unintended location. This gives a 0x8000 write primitive with uncontrolled data into the HyperVisor.
  • To turn this into code execution, they had to win a race condition and be able to execute it multiple times - the second of these made it much more difficult to do in practice, since it removed many interesting targets. From within one of the writable bootloader code segments, they found a stb/blr pair that gave them an arbitrary write primitive that could be written at the end of a system call within the Hypervisor.
  • This is inherently racy and wasn't very consistent. When the race condition is combined with the brute force of the whitening value, the exploit takes too long. To make this more consistent, they experimented with thread prioritization and monitoring of the code. With their current payload, the attack thread got the malicious ciphertext flushed to RAM the XKE payload was already done running. To fix this, they put the attack on hw thread 0 and the payload thread on hw thread 1 and put both of these on core 0. There are more details on winning the race but it's over my head.
  • This exploit is still inconsistent and time-consuming. However, the means of winning the race more often and modifying encrypted memory are still good insights into complex exploit development. The testing strategies used was also interesting to me. Good work!

Choosing an Audit Competition: How to Spot Snake Oil- 1637

Zellic    Reference →Posted 10 Months Ago
  • Contest platforms in web3 are an alternative to standard security reviews. The auditing firm Zellic bought the contest platform CodeArena last year and has decided to write a report on metrics for audit contest information. Naturally, the platform wants to look better, but you've got to know when things are snake-oily. Imo, some of this just feels like a competitor bash (especially the screenshots that are obvious to know who they're calling out), but there are some good points.
  • The true benefit of audit competitions is the number of eyes and skills your code gets. A traditional audit is a low-hanging-fruit audit with known entities. In a contest, the participants are incentivized to find unique and high-impact issues. So, the coverage is better theoretically.
  • The first metric is finding count. Many of the findings reports include invalid issues or don't de-duplicate the issues to inflate the numbers. Teams only care about the high and medium severity bugs.
  • The next metric is participant numbers. There's a difference between participants and useful participants. Using a number with "participants who submitted a valid finding" would be much better. It's also hard to know how much time was actually spent on the code for those participants. However, this final point is true on all platforms.
  • The third one is "Claims about exclusivity". A general issue with contests is how you know good researchers are looking at your code. At Cantina, they have pre-paid folks to work on audits. On Sherlock, they have a Lead Watson who gets an automatic part of the prize pool.
  • Having full-time people on your platform is better than not having it at all. There's a concern if these folks are actually spending the time on your project. If they weren't, they would probably lose their contract with the contest platform. Their concerns are valid (are they on it the entire time, who is managing this, etc) but some it better than the none of C4.
  • Comparisons between audit contests and traditional audits are usually somewhat confusing. Severity scales are different, "fake" vulnerabilities are sometimes presented in both cases, and asymmetric comparisons are made on codebases that are either different projects or audited at different points. This is a fair call out.
  • It's good to consider the differences between the platforms to decide where to host competitions and participate as a hacker. This article has some good points but also has a very skewed perspective with A) being an auditing firm and B) owning C4. So, take the content with a grain of salt.

unsound transmute in bpf_loader::syscalls- 1636

WorkingJubilee Agave    Reference →Posted 11 Months Ago
  • transmute converts between types in unsafe code by reinterpretting the bytes in Rust and forgets the original reference. It effectively disables Rusts built-in type checker by design. While as converts to things smartly, such as float to int, transmute is very dumb about it.
  • Because transmute bypasses built-in type checks, it must be sound. Otherwise, major security issues can occur. Violating soundness can lead to undefined behavior. It has a special section about "transmutation between pointers and integers". In particular, special care must be taken when transmutting between pointers and integers.
  • Agave, the original Solana validator written in Rust, uses transmute in an insecure way. It converts between an integer to a &mut T. This causes the reference to obtain the provenance(space) of an integer, which is none. If T isn't zero-sized, this instantly incurs undefined behavior as a result.
  • Overall, I learned something new about Rust type-safety. Good issue!

SAML roulette: the hacker always wins- 1635

Portswigger - Gareth Heyes    Reference →Posted 11 Months Ago
  • SAML libraries often parse an XML document, store it as a string and later er-parse it. For secure authorization, the document must be parsed and serialized consistently. Otherwise, these differences could result in serious issues. Round trip attacks can be used break the parsing logic of programs.
  • In Ruby-SAML, this process involved two different parsers: REXML to parse/verify and Nokogiri to access the fields. This vulnerability had a collision with the researcher in the post. They decided to investigate notation declarations, based on previous research, to see if parsing issues could be found. While doing this, they found that mutations could be introduced using the SYSTEM identifier.
  • When parsing SYSTEM, a comment with a single quote in the attribute is initially fine. When it's reparsed, the comment is not properly escaped and the single quote is made into a double quote. This modifies the syntax of the document, causing an XML comment to be processed and adding data in another comment to be part of the node instead. Using this method, it's possible to smuggle in data on the second parse to falsify the fields, such as the necessary assertions for users.
  • In Ruby-SAML, the library verifies that the SAML response contains a valid certificate in the document. Here's how it works:
    1. On the first parse of the document, get the certificate to take a hash of it. This is used for signature validation later.
    2. Certificate is extracted from the SAMLResponse.
    3. The document is converted from XML back to its in-memory representation. This is the round-trip issue.
    4. The library ignores the attackers assertion when doing the processing on the original element.
    5. Accessing the data will now use the modified data added in by the attacker. Neat! We have a winner!
  • They wanted to see how far they could take this though. There is some XML scheme validation that prevents doing some trickery. This works by validating define elements, attributes, data types and number of elements. Although you could find an XML document on a developer forum, they went for a namespace confusion attack.
  • They use a discrepancy between the two parsers to bypass the signature verification. The XPath query on the signature uses the ds namespace, which would prevent element conflict. Normally, an included ATTLIST inclusion declaration with the same namespace would be rejected. However, REXML ignores this restriction in doctype declarations!
  • REXML will use the attacker defined namespace collisioned document. However, the other parser will use the original! This means that the verification will be done on a Digest that's real while the usage will be done on one that is fake.
  • To exploit this, a single valid signed XML document is necessary. WS-Federation is used by default on most IdPs though. Since this provides signed metadata, these signatures are accessible publicly from any user! The namespace confusion attack only requires a valid signature - it doesn't matter what it's for! By using this document, GitLab SAML authentication can be bypassed to login as any user.
  • Any time you see two different parsers, or data being parsed more than once, you hacker senses should start to tingle. This vulnerability was exploited in two different ways in this article and an entirely separate way in another post. This is awesome research - I will be looking for similar things in the future!

Meet DAVE: Discord’s New End-to-End Encryption for Audio & Video- 1634

Discord - Stephen Birarda    Reference →Posted 11 Months Ago
  • Discord created a new end to end encryption protocol they call DAVE. This will be used on DMs, group DMs, voice channels and live streams on Discord in the future.
  • For key exchange, they use the Messaging Layer Security protocol. This protocol allows having a per sender encryption key for all members of a group. Whenever a member of the group leaves or joins, the key exchange must be done again to prevent some attacks, which is well-thought out.
  • For identity and user verification, they use the MLS ciphersuite with ECDSA signatures. Each participant generates an identity key pair and shares this with other members on the call. Each device generates a private key so no synchronization isn't needed between devices. These are ephemeral and re-generated for each call.
  • I love reading articles from big companies about security best practices. Since these companies have the money and time to put effort into it, the needle can really be moved with the effort!

Sec-Gemini v1 - a new experimental cybersecurity model - 1633

Google    Reference →Posted 11 Months Ago
  • Sec-Gemini is an experimental AI model focused on cybersecurity. The model has been proven to do very well on cybersecurity-specific topics - better than other models on similar concepts. Pretty neat!

The Three Prompts of Spec Thinking: Yet Another Lens for Smart Contract Auditing- 1632

Dravee    Reference →Posted 11 Months Ago
  • One fantastic hacker is better than five good ones. We can make all of the checklists that we want and this will always be the case. Most bugs are not just items from a checklist - they are broken assumptions or mismatches between what the developer intended and what the code actually does. This article is about Spec Thinking - a strategy to uncover assumptions and the implicit rules of the system.
  • A smart contract is an asset management system where actors gain access to benefits through actions. Pretty simple way to break down some code! The author claims that all bugs fall into three categories: missing paths, incorrect happy paths and unexpected paths. Missing paths are just user intentions that aren't there - you can deposit money but can't withdraw.
  • Incorrect Happy Paths are features that exist but there's a fault or mistake in the state transitions. This is "wrong result but the right path". Things like rewards being miscalculated or state not being updated are good examples of this. These are often caught in testing but it becomes harder to find these with larger codebases or very complex flows.
  • Unexpected Paths are parts of a system that do more than intended. Weird edge cases, unsafe flows or badly scoped permissioned are where these bugs exist. In my experience, this is where most bugs are at and threat modeling works the best.
  • Specifications are how the system is supposed to behave. Invariants are statements that always must hold about a system. For instance, total supply must always equal the sum of all balances. Properties define what should hold true after executing a specific state transition. As an example, after withdrawing the user's balance should decrease by the withdrawn amount.
  • These matter because a bad property means something is wrong. If you understand the invariants, intents and expected properties, you can find how to break them. Understanding these parts of the system helps you get better good coverage. The idea is using this understanding of the system to create specifications at three different levels.
  • The first is the high level specification. This is in plain English how it works like "a user cannot lose funds unless they voluntarily withdraw or trade." The second is mid-level specification with state tracking. Finally, the code level specification for function-levels conditions and transitions. Drafting out the properties, invariants and flows of the protocol allow you to understand the code much better.
  • Formal methods teach you to understand the design intentions versus the implementation. You should be asking yourself three questions when working through these specs:
    1. What is expected?
    2. What is allowed?
    3. What was assumed but never enforced?
  • The specification thinking is something I do a good amount. I usually write out the entire flow from a high level step by step to understand what's going on. Over time, I get some properties and invariants for the protocol and see if I can break them. They have a good question that I should probably use more "What does the code assume, but never check?"
  • Overall, a good thought process on bug hunting. However, I felt this post was really dense and touched on a few too many things. If it just touched on the specs, it would have been better imo.

Azure’s Weakest Link? How API Connections Spill Secrets- 1631

Haakon Holm Gulbrandsrud - Binary Security    Reference →Posted 11 Months Ago
  • Azure API connections allow for cloud-based access to an API behind a logged-in proxy. This allowed for the website to not worry about OAuth dance on Slack and other types of apps. They contain different roles, such as reader.
  • While reviewing one of the requests, they noticed two fields: testLinks and testRequests. This was a generalized way to test the APIs to ensure they were functional. In the case of a credential change, this would be a useful thing for the application and user to know.
  • The developer specifies the path of the request and the method to use. Unfortunately, this is too generic. This is just a proxy now! Any path can be specified, even if the role shouldn't have access to it. This is a case of a user being able to control information they shouldn't because the developer made it modular.
  • Using this, the reader could query more sensitive information than intended on data resources. Azure key vaults, SQL database queries, Jira information, and other extra data could be queried. From what I gathered, the user needs the reader's permission to do this. So, a privilege escalation in the same account but nothing more.
  • The response was funny to me. Initially, it was closed but the author reopened the issue to get it approved. They reported these as two findings: one got paid out and another closed as a duplicate. Overall, good write-up!

CVE-2024-9956 - PassKey Account Takeover in All Mobile Browsers- 1630

Tobia Righi    Reference →Posted 11 Months Ago
  • PassKeys are a form of the WebAuthn CTAP specification to perform passwordless authentication. The idea is for a Client, such as the browser, to communicate with an authenticator, such as a mobile phone or USB device. In practice, "WebAuthn is just SSH (privkey-pubkey) for the web".
  • There is a difficult problem though: if the passkey is on my phone and I want to login via the web browser, how do I do that? PassKeys contain a cross-device authentication flow with various methods. One of these is using Bluetooth low energy (BLE). Since these devices ensure close proximity, the idea is that authentication is now completely phish-proof.
  • When doing cross-device login, WebAuthn authentication creates a QR code to scan. This is how the flow works:
    1. User scans the QR code. The mobile phone's PassKey manager processes this data.
    2. BLE connection is made.
    3. Browser generates a random challenge for the Authenticator to sign with the stored private key.
    4. Authenicator signs the challenge and sends it back.
    5. Browser sends everything to the backend website.
  • FIDO intents, the URI found in the QR code, contain a blob with a bunch of serialized data. Since it contains a public key of the relying party, a timestamp, registered domains, and much more. Since this information is just a QR code, this means that FIDO intents can be triggered cross-origin. Why does this matter for security?
  • Here's the attack scenario:
    1. Victim clicks on a link controlled by an attacker's page.
    2. Attackers' device visits the login page of the victim user and the website they want to exploit. They extract the FIDO link from the QR code using a headless browser and redirect the user to the page.
    3. Victims PassKey manager pops up for the attacked site. This is done by the website, and since there's no validation of FIDO URLs being popped.
    4. The attacker connects to the device user's phone/device via BLE with the session from the first step.
    5. The user approves the login attempt.
    6. Attacker is now logged in via the user's account.
  • This attack requires physical access while the victim clicks on a user-controlled link. Since WebAuthn is baked into the browser, it's not possible to get the PassKey information from the website itself. Instead, I believe that the FIDO link is required to be clicked on in order to start the pairing process. Then, by connecting to the attacker's controlled device that has the session on it, we trick them into logging into the wrong website.
  • To fix this issue, browsers made the FIDO:// URI no longer navigable by a page. Overall, great research into a new form of authentication!