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!

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!

Fatal Residue | An On-Chain Heist Triggered by Transient Storage- 1629

SlowMist    Reference →Posted 11 Months Ago
  • Transient storage is a new type of EVM memory that stores data only for the length of the transaction. It is cheaper than storage but deletes itself at the end of the transaction. These are callable via TSTORE and TLOAD opcodes. A great use case for this is reentrancy flags. With new functionality comes new bugs!
  • The vulnerable contract was a Vault contract that interacted with UniswapV3 via callbacks. The smart contract is making a call to a UniSwapV3 pool. When the tokens are transferred back to the Vault, it must know who the intended caller is. This is done by specifying the UniswapPool address into storage slot 1.
  • On the swap callback function from UniswapV3, there is verification being done that it's indeed the proper pool. This is done from reading slot 1 of the transient storage. Later on, the amount that was minted is stored into this slot. The problem is that the amount is never cleaned up!
  • Both the amount and UniswapPool use slot 1 of transient storage. Since the amount being minted is a user controlled number, the attacker used this property to write an address they controlled with the amount value. Now that this was set, they were able to bypass the UniswapPool verification check to call the contract to steal all of the funds in the callback.
  • Don't reuse storage slots... this isn't 1980's video games. Good writeup!

We hacked Google’s A.I Gemini and leaked its source code (at least some part)- 1628

Roni "Lupin" Carta    Reference →Posted 11 Months Ago
  • At a live hacking event, the author of this post Roni decided to look at a new release of Gemini. In this update, the interface had Run in Sandbox as an option for Python execution. This was a sandbox used for executing Python in the context of Gemini.
  • The sandbox is powered by Google's GVisor, which is a user-space kernel. It does some magic with intercepting system calls and does a great job at restrictions access. It has a 100K bug bounty so this was likely impossible to escape. So, what's in the sandbox itself? Remember, this is a custom Python binary that is being ran.
  • They rewrote Front End to run their own Python code in the sandbox, to give them more flexibility. To see what they could do, they downloaded the Python interpreter itself. The custom Python binary had the os package in it, making it easy to see the file system. They were unable to pop a shell so this was the best they could do.
  • Exploring the file system led to some interesting files. In particular, the /usr/bin/entry/entry_point file. It was 579Mb in size though. Trying to base64 print it over the network just led to a network hang. Eventually, they read parts of the file in 10Mb chunks to get the whole file out.
  • Using binwalk, even though it's just a binary file, lead to some files being revealed. Upon reviewing these files, it appeared that some source code had been leaked. This code was not meant to be public, as pointed out by some comments in the interpreter program itself.
  • The sandbox had access to some Google specific network services but failed on other outbound connections. From reviewing some papers and reading internal source code, they realized that the process for opening up network information was done via Gemini itself. Gemini self-prompts to unlock necessary access. For instance, writing a prompt to access the Google Flights API will spawn a sandbox with the proper privileges - this wasn't noticed earlier because of how the sandbox was being started in their session.
  • By using a secondary prompt injection, access to a more privileged sandbox was given that did have this type of access. The hope was that they could get access to two extra file descriptors that they were not always given there. They were hopeful this would lead to a P0 type of issue to do things on Google infrastructure. The Google team did some assessments and believed that nothing extra on the box could be accessed even with a secondary prompt injection.
  • Within the sandbox, they found several protobuf files that were meant to be "internal-only" that exposed some sensitive information. Although I can't see the data they saw, I felt like the leakage of data was over-hyped. Maybe I'm missing something here though.
  • Overall, the post was okay. The sandbox escape discussion was fun! However, instead of memes and commands that they can't show the result of for "legal reasons", diagrams of the flow would have been appreciated. I also like posts that are more into the weeds with less story telling but that's a style choice I suppose.

Incorrect processing of effective balances in Electra epoch processing- 1627

alexfilippov314    Reference →Posted 11 Months Ago
  • Ethereum is migrating to the newest fork Pectra. In order to make sure it's secure, the Ethereum foundation is hosting an attackathon on all Pectra-specific changes on Cantina with most Ethereum clients in scope, including the Ethereum Consensus client Lighthouse. The vulnerability would lead to a split of Lighthouse nodes from Ethereum, breaking consensus.
  • Lighthouse had paralleled validator updates because changes made to one validator did not affect the other. In the Electra upgrade, consolidations were introduced that allow for exits straight to another validator. Naturally, these two things collide and it was noticed by the development team.
  • To make this work with the parallelization strategy called single-pass epoch processing, the function process_effective_balance_updates was rerun on each validator index. Unfortunately, there are other functions with side effects run between these runs. This leads to different results when ran multiple times! Word of the day: hysteresis - a property lagging behind the changes in the effect causing it.
  • There is a very detailed situation that is described that makes Lighthouse differ from the specification. By using the multiple updates, a node would have a different effective balance than they should. If Lighthouse was the only software used, this wouldn't be a huge deal. However, since it has to be perfectly aligned with the other clients, this is a problem.
  • To fix the vulnerability, single-pass epoch processing only happens on validators unaffected by the consolidations. All nodes affected by consolidations are processed before updating their effective balances. They also mention the adding of specification and fault injection tests around this to try to find other variants of it. Overall a great find and an amazing write up about it.