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!

Escaping the Dark Forest- 1125

samczsun    Reference →Posted 2 Years Ago
  • This post has a title that alludes to a famous MEV exploit article called Ethereum is a Dark Forest. In that story, the author of a post found some funds laying around that anybody could capture. They tried getting the funds for the poor victim but a bot swooped in and stole it.
  • samczsun was auditing a large amount of yield farming clones with the same pitch: stake your tokens to become the next crypto millionaire. While looking at some code late at night, they were looking where Ether was transferred and found two hits. The second one was a burn function that sent Ether to the sender.
  • The auditor found an issue. This was a contract to redistribute Ether to the bond holders upon maturity. The vulnerability was that a BondGroup could be made at no cost by providing an empty array. By setting the maturity to be the same as BondGroup 10 (with 25K Eth), it would be a valid.
  • Then, an attacker could exchange the empty BondGroup with a non-empty BondGroup by calling exchangeEquivalientBonds. At this point, they had essentially create a worth bond and turned it into a valid one. Wild!
  • The author had an exploit in hand. What to do now? If they get users to withdraw their funds, then some funds might get stolen. If they exploit it themselves, they could get hit by the Dark Forest. These whitehats wanted a rematch against the bots.
  • They built a trusted war room for people to try to perform this attack. To defeat the Dark Forest, they wanted to tap into a private mining pool. This way, since it wasn't in the mempool, it couldn't get frontrun. SparkPool has a special beta way of sending private transactions. So, this was the way to go.
  • They sent up 4 signed transactions to exploit this vulnerability. They tested them locally and really verified this would work. The plan was to transfer a large amount of 30K of SBT+LBT tokens to the Lien team. Then, the Lien team could run the final transaction to swap this for ETH.
  • They sent the transactions on the private setup and the team got the ETH back. It had worked. They had escaped the Dark Forest with $9.6M. The heros!

Ethereum is a Dark Forest- 1124

Paradigm - Dan Robinson & Georgios Konstantopoulos    Reference →Posted 2 Years Ago
  • This is a classic horror story on MEV bots in Ethereum. Read at your own discretion (and craziness).
  • While on Discord, the author of this post received a question on Uniswap: "is it possible to recover the LP tokens that are sent to the pair contract itself?" Initially, they thought no but it's recoverable - by anyone!
  • When somebody calls the burn function on the Uniswap core contract, the contract measures its own LP balance and burns it. Then, the withdrawn tokens are outputted to the caller of the function. Within the contract was 12K worth of liquidity tokens just waiting for somebody to take it. This is a ticking time bomb, since anybody could burn their LP tokens and accidentally receive the funds.
  • There is a pros and a cons to the decentralized nature of blockchain. One of these cons is that if there is a contract that can be exploited for a profit, then it will be; this is a battlefield. However, this isn't even close to how bad the mempool is, where unconfirmed/pending transactions lay. If the chain is a battle ground, the mempool is the much worse dark forest.
  • The mempool is filled with bots that exploit the ordering of transactions currently in the mempool in order to turn a profit. This is why recovering the funds is a complicated task! If a bot sees what we're trying to do, they frontrun the swap and use their own address to receive the money instead.
  • The name of the game here is obfuscation. We need to make the call to the contract without the bots being able to detect the pattern. Their obfuscation plan was to use two separate calls: a getter and a setter contract that will make these calls instead of a call from an EOA. This way, a simple modification to the transaction wouldn't be possible to perform.
  • Their hope was to deploy these contracts in the same block but separate transactions. If an attacker only executed the get, then the contract would revert. The thought was that by the time the set and get had both been executed, the bot wouldn't know what hit them.
  • When trying the recovery, the get call was rejected by Infura even with manual gas overrides. Oh gosh... this means that the set had been done and the get was getting ready to go. The transaction slipped into the next block... they got a INSUFFICIENT_LIQUIDITY_BURNED error from Uniswap, meaning that somebody had performed the call and stolen the funds.
  • What can we take away from this?
    • The monsters are real. Their are real generalized frontrunning bots out in the world who will steal funds.
    • Don't get sloppy. Have a plan and execute it.
    • Don't rely on normal infrastructure. The reason the getfailed was because it should have failed for the current blockchain state but not what they were updating it with. Or, know a private miner.
  • Overall, an extremely scary situation that's only going to get worse over time. The mempool is the reason for this unique bug class being possible. A product called VeeDo from Starkware has created a Verifiable Deploy Function to make Ethereum applications immune to these types of attacks.

Post Mortem: mev-boost relay incident and related timing issue- 1123

Bert - Flashbots    Reference →Posted 2 Years Ago
  • In the world of cryptocurrency, there are many bots who are attempting to make money on the eco-system. If a bot sees an arbitrage opportunity or a sandwich, it will see it and try to make money from it. However, as the space got more and more crowded, problems arose. In particular, to front-run you either collude with a miner or pay a higher gas fee. Since many bots exist and keep doing this, the price kept going up and up.
  • This behavior is bad because it was clogging up the network with a bunch of bad and failing transactions. Additionally, the gas price was skyrocketing because of the frontrunning attacks. A solution to this? Flashbots! This is a market place that connects block makers, bot operators (aka block builders) and others to only have a handful of these opportunities pop up. This makes less congestion on chain happen.
  • The service uses a first price sealed-bid auction in order to make sure only valid transactions are added (no more frontrunning the frontrunner). Each block builder will propose a price they are willing to pay; the highest bidder wins. On top of this, there is the new proposer user. This player can give the builders the proposed blocks for a price. With Flashbots, this is called MEV-Boost.
  • On April 3rd 2023, an issue with part of the MEV-Boost stack was found. MEV-Boost works through a commit and reveal scheme. This is so that builders cannot see the contents of the proposed block but can see how much value it would bring; if they could see the block, they would be able to use the knowledge immediately. This is done via a relayer.
  • This whole system relies on the relayer securely handling the proposed block. In particular, the builder will sign block headers. However, the relayer did NOT validate the block header for accuracy. If the block header was invalid, it would attempt to publish the block to the chain and get rejected. Regardless, the relayer would reveal the body to the proposer. Since the proposer had the block body, they could use the knowledge of the block ordering themselves to make a profit with sandwiches and arbitrage opportunities.
  • An additional issue was found after evaluating the security of this system. A malicious proposer with two slots in a row could ask a relay for a block too late in the slot. If this is done, the proposer would miss their slot but the block body would be sent over. With this knowledge, they are able to build the block with optimal settings with the second slot.
  • The attack steps are super interesting:
    1. The attacker sends multiple transactions to the public mempool with large swaps and infinite slippage. This was a bait to the sandwich bots.
    2. The bots pick up the mempool transactions with a profitable sandwich. The block is sent to a relayer.
    3. The attacker requests a block header then gives a poorly signed block header for the previously constructed block.
    4. The ultrasound relay attempts to publish this but has a bad block header. Prior to sending this, the full block is sent to the attacker.
    5. The attacker constructs a block that drains the sandwich bots! This isn't elaborated on very much but it's assumed that they added in transactions around the sandwich bot to make their transactions lose money instead of gain money.
  • To fix this vulnerability, MEV-Boost relays no longer return the block body if the publishing fails. To fix the second problem (race condition), there is a cut off point of 3 seconds. Overall, an awesome and crazy view into the world of bots in cryptocurrency.

Bypassing Amazon Kids+ Parental Controls- 1122

n00py    Reference →Posted 3 Years Ago
  • The author of this post has a very young daughter. They wanted to protect their kid from bad content on the internet using the child protective services. First, they needed to make sure it was secure on the iPad.
  • They go through clicking all of the random buttons to break out. There are some screens that go into a a webview within the app. The author noticed that clicking on any links, in particular, Google links, allowed them to open up arbitrary web pages within this view.
  • At first, they thought this was just a single app that had the problem. After trying this technique on a few other pages, they found the same problem. So, they deemed this a security lapse on the iPad itself, especially since links like this on the iPhone don't work.
  • We don't see many kiosk escapes anymore. This was a good reminder of the trick of clicking on links.

Argument Injection Vectors- 1121

Sonar Source    Reference →Posted 3 Years Ago
  • Command injection is a well known bug where user input is concatenated with a bash command. Because of the string concatenation, an attacker can inject things like ` or ; to execute a different bash command entirely.
  • Over the years, shell metacharacters have started to get filtered out. So, can we do anything useful? Well, it depends! The concept of argument injection is using the same input vector but the goal is to add arguments to the command.
  • Some CLI commands are extremely powerful. For instance, on Chrome, --gpu-launcher is an argument that can be used to execute arbitrary commands. This link is a set of known commands that have easy-to-pwn argument injection payloads. This is sort of like gtfobins.

Competing in Pwn2Own 2021 Austin: Icarus at the Zenith- 1120

Axel "0vercl0k" Souchet     Reference →Posted 3 Years Ago
  • Have you ever wanted to participate in Pwn2Own!? The author of this post took the jump into competing at this hacking event. They were part of a team with 2 other players trying in the routers, printers and phones event. They picked a consumer NETGEAR router since they thought it was the path of least resistance.
  • First, they started by opening up the box and getting a shell on the target. This was done by soldering some pins onto the device and interacting with a UART console. Luckily for them, it outputs a root shell with no further troubles.
  • Next, they started looking for juicy attack surfaces. In particular, they wanted to look into something that had never been popped before; this was to ensure their wouldn't be duplicates. Initially, they looked into uhttpd, which was able to invoke and run Lua extensions. The router had scrambled the opcodes, causing decompilation issues.
  • While looking at the netstat output, two open sockets on 0.0.0.0 were not associated with any process. It turned out that this was a network USB stack that was running in the kernel. Although this had been popped in the past, they found an integer overflow vulnerability they could be made into a smaller write than the size of the overflow! A user controlled value, without bounds checks, was passed into a call to malloc with additional values being added and multiplied. Pretty neat!
  • The exploit code to trigger this is less than a hundred lines of Python code. The buddy alloactor is used for allocating this chunk. This means that it's allocated in groups of 2**N pages, limiting the allocation sizes that can be used for the exploit.
  • The kernel driver was missing ASLR, NX and sent addresses (for debugging) over the network on a different port. Although they had a bug, they wanted to emulate NetUSB using QEMU to develop their exploit. After spending hours compiling and using other kernel, they learned about some compilation flags that must have been set on the build of this driver that weren't set on their builds. Eventually, they got everything to build!
  • They looked at the Linux source code and played around with different objects. Eventually, they learned that a small pause after the allocation of the buffer but before overflowing it, an interesting structure would be magically allocated fairly close to the buffer. Inside the wait_queue_entry object is a function pointer, which they choose to overwrite.
  • Getting code execution was as simple as overwriting the function pointer and jumping to existing code. Since ASLR and others things were turned off, they could even hardcode addresses! Porting this to the real router was pretty easy and had a success rate of about 3 out of 5 times.
  • Entering the contest was rough though... Netgear put a patch out the day before the event and they were unable to get their exploit to drop live. Overall, an awesome post on an end-to-end Pwn2Own experience with a good amount of diversity on the content.

A Race to Report a TOCTOU: Analysis of a Bug Collision in Intel SMM- 1119

NCC Group - Jeremy Boone    Reference →Posted 3 Years Ago
  • In October of 2022, the source code of the BIOS for Intel's Alder Lake platform was leaked. While poking around the code, the author found a pretty devastating vulnerability.
  • System Management Mode (SMM) is a very high privileged part of the execution process. Naturally, we need to execute defined code in here but nothing else. As a result, there are defined call locations called System Management Interrupts (SMI) Handlers to jumping into this region of code.
  • For data being passed in, rigorous input validation needs to be performed in order to ensure memory corruption doesn't happen. In particular, the address provided for either a read or a write needs to make sure it's in a valid region of memory (not the SMRAM). It is common for the SMI handler to copy memory from a user controlled location into the SMM locations for further processing. There are standard functions for both of these operations.
  • The SMI handler SPI_FUNCTION_FLASH_READ falls into a bad trap - fetching data more than once. First, the function will read the data into a local copy. Next, it verifies the users controlled version in a separate section of memory. If the validation passes, then it will continue using the local copy. Since the user is able to modify their own version, the local copy can have malicious data then the user controlled one can modify itself to be valid. This double fetch problem results in a Time of Check vs. Time of Use (TOCTOU) vulnerability.
  • All of the SPI function handlers, including reads and writes, are vulnerable to this exact problem. The location of the write for the buffer can be put into SMRAM, leading to terrible memory corruption that leads to code execution in the SMM. Validation should be done on the same data being used. Otherwise, it's pointless.
  • Attacking this is very complicated. This would require a SPI flash chip that can be quickly read and written from with triggers on these actions to modify the data. In all likelihood, an attacker would use a FPGA to do this and it would require long term physical access to exploit. Overall, a pretty neat bug in a obscure part of the Intel tech stack.

Server-Side MIME Sniff Caused by Go Language Project Containerization - 1118

omnipresent    Reference →Posted 3 Years Ago
  • Answerdev is a question-and-answer platform written in Go. The original post is at here but the translation is what I used above since I don't read anything besides English.
  • Using can upload pictures. When they upload a file, it's stored on the file system. When it's retrieved, a static resource server called gin will grab the resource and send it back. To prevent vulnerabilities for running JavaScript or something else on the site, the Content-Type is set based upon the file extension. This prevents many attacks, since the Content-Type changes how the browser will handle the file.
  • The MIME standard library is used for the returning the Content-Type given a file extension. This relies upon a set of mapping files stored in a few different locations, but commonly added by other packages. If there is not an extension-to-type mapping, then this is simply ignored.
  • Why is this bad? MIME Sniffing is the browser trying to guess the type of the response based upon the content of the page. Without a Content-Type and X-Content-Type-Options: nosniff, this functionality occurs. If we can find a file that isn't in the mapping that can be uploaded by the server, we can confuse the browser to upload HTML, leading to XSS!
  • Oddly enough, this bug was discovered because of a difference between production and development usage of a docker container. In the production version, a minimized version of Alpine was used. So, the MIME types were not present in the container, leading to a tiff value to be used as an XSS payload. An example of this can be found at here for client side attacks.
  • Although this is a weird use case for MIME sniffing on the server-side, it is an interesting vulnerability that is still valid in today's world.

Azure B2C – Crypto Misuse and Account Compromise- 1117

Praetorian - John Novak    Reference →Posted 3 Years Ago
  • Microsoft Azure's Business To Customer (B2C) Active Directory (AD) service allows for a customer to create a website with AD for authentication that customers can use to create accounts. Using this, a full authN/authZ scheme can be built from pre-existing and known technology. A really good thing to build!
  • The flow in question for authentication and authorization is the OAuth authorization flow with Proof Key for Code Exchange (PKCE). This uses the standard OAuth flow besides that it will also return a refresh token that uses JWE_RSA-OAEP. This uses an asymmetric encryption algorithm called RSA, which contains both a public and private key.
  • In the flow, there is a signing key and an encryption key. When using the encryption setting, the public key is used for encryption. Now, this keeps the data secret from a snooping adversary but anybody can encrypt the data. Here in lines the problem: the RSA encryption is used for the generation of the refresh token. Since the public key is public, anybody who has access to this key is able to create their own tokens!
  • The MSRC web portal uses this form of authentication as well. Since it's trivial to obtain the public key, they were able to craft refresh tokens for arbitrary users on the site. This means they could have viewed arbitrary bug reports, 0-days and much more.
  • Overall, this is a classic case of misunderstanding the use case of cryptography. Gotta love it!

BonqDAO- 1116

Immunefi    Reference →Posted 3 Years Ago
  • BonqDAO is a non-custodial, over-collateralized lending protocol on the Polygon blockchain. This project allows for any protocol to borrow against their own token at a zero percent interest rate.
  • Users lock their assets into a smart contract only controlled by the users - non-custodial protocol. Users lock their collateral in a Troves (unsure what this means), which have a minimum collaterization ratio. If the values fall, then anybody can liquidate these balances.
  • TellorFlex is the Oracle system of Bonq. The submitValue function allows reporter to submit a value to the Oracle. Since this is permissionless, anybody can write a value provided that a few conditions are met:
    • Nonce is legit to prevent replay attacks.
    • A minimum amount of tokens have been staked by the poster of the price.
    • No reported price for the query ID.
    • Timelock check to make sure a person cannot report more than once in quick succession.
  • How hard are all of those requirements to met? Barely an inconvenience! All we have to do is stake funds and we've updated the price without any sanity checks. In fact, the contract used the spot price of the token as well. This can be used to arbitrary inflat or deflate the value of a given price feed.
  • The attacker exploited this in an interesting way. Instead of simply making money off of buying/selling, they went the liquidation route. First, they increased the price of WALBT, leading to a very large borrow using a modest amount of capital. This money can be used to fund our attacks later on.
  • Next, report a price on the new block with a very small spot price. Since the price is small, we can use this to liquidate all of the loans taken out. We will obtain lots of collateral for almost nothing in return.
  • The blog post has a new PoC in Foundry for a test environment as well. This was a pretty major hack for how simple the bug was - anybody could set the price of a cryptocurrency.