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!
TSTORE and TLOAD opcodes. A great use case for this is reentrancy flags. With new functionality comes new bugs!UniswapPool address into storage slot 1. amount that was minted is stored into this slot. The problem is that the amount is never cleaned up! 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.Run in Sandbox as an option for Python execution. This was a sandbox used for executing Python in the context of Gemini. 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./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.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. 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.x-middleware-request header with the path of the middleware being executed. For every piece of middleware it sees, a colon-delimited path is added. If the middleware has already been seen, then the code simply skips the middleware. x-middleware-subrequest: my_path skips the check. If this is used for authentication/authorization, then it's a horrible vulnerability. The path is somewhat guessable and the header can be used as a polyglot as well.middleware or src/middleware. With the changing of the path, it actually makes it easier. Additionally, there is a now a recursive check with a maximum of 5. So, middleware: just needs to be repeated 5 times now.delegateCall was made to a contract controlled by the attacker. At this point, they were able to modify the Safe contract storage to change the proxy slot. By doing this, future calls the attacker made to the contract would go through their proxy to execute a delegateCall, allowing for complete ownership of the assets at the address. Stealing funds is trivial at this point.max_receipt_size. To me, this is interesting - small changes can create subtle new invariants that were not there before.incoming_receipt by other nodes, the exceeded size limit leads to a panic being hit. From their report, they were hunting for possible panics in the codebase and how to hit them. Aka, sink-to-source bug hunting.validate_receipt actually removes the validation of the receipt size. In particular, they ONLY want to check for size constraints during creation and not expansion. I would have expected a check to be added on the expansion code to not exceed the limit, so this patch surprised me.deviceid against the session token and other fields, making this pretty solid.deviceid in the headers that we don't own, the request authenticates us but believes it's a device initiated request because of the header. So, it assumes that the device is valid but it's really not. The explanation and the code snippet they provide helps a lot with this..env, containing deployment credentials, being leaked. This was done via the .gitignore file. For the initial deployment of two packages, this worked well..npmignore file to do this. Surprisingly, the presence of this file invalidated the .gitignore! This meant that the sensitive .env file was leaked. This contained a private key for the deployer account.cat /etc/passwd on a SQL query. Since this is the super user, it's effectively game over.AdmissionReview request generates a temporary NGINX configuration file using a template. Then, to test for validity, it runs nginx -t. Since the configuration file has user controlled inputs, the path is unauthenticated and the config is executed, this makes it a great attack surface.authreq parameter is used for authentication-related annotations. However, this field has zero input sanitization. Hence, it's possible to add arbitrary directives to the NGINX configuration file. There are several other variants of this on the authtls and mirror parameters. So, why is this injection a big deal?ssl_engine directive is able to load shared modules, without top-of-file restrictions like load_module. Doing this would allow for the execution of arbitrary code but requires a file to be on the system./proc file system. Using this, it's possible to access the contents of the file from the NGINX configuration. To make this race condition easier, making the Content-Length larger than the body will keep NGINX waiting. Sadly, this requires brute forcing PIDs and file descriptors, but that's worth the problem..so payload by abusing the file buffer feature.AdmissionReview request to the controller with directive injections. In particular, inject the ssl_engine to load the shared library from step 1.nginx -t can lead to code execution, making configuration injection a very serious vulnerability.