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!
/.well-known/acme-challenge/{token} to verify the domain. The CA fetches the token; if the bytes match, then the certificate is issued. ..;/ performed a directory traversal on the website but was considered valid at the original path on Cloudflare. NextJS made it possible to leak some details that are normally not public (I don't get this one). floats; everything is an integer. So, 5/2 is not 2.5 but 2. To combat this, fixed-point arithmetic is used, which most folks know as decimal arithmetic. Now, 5 is no longer 5 but 5^18. Now, when you divide by 2 it's 2.5^18 which keeps most the precision. Some libraries also provide functionality for rounding up or down depending on the situation. balanceOut * (1 - balanceIn / (balanceIn + tokenIn)) from Balancer. if balanceIn is 0, then this can become balanceOut * (1-0). balanceOut is the only value leftover. This can happen by combining a flash mint with a pool unbalanced. This truncation allows the attacker to steal all funds from the protocol. The fix is rounding up instead of down.COPY command was used instead. Given the impact of this, it was weird that it was only a $5K payout. A good takeaway is that concurrency is hard to get correct and should always be considered.SHA256 header. In reality, there was another header that could effectively contain arbitrary data. Since this value is a C string, if you add a nullbyte, vertical tabs and carriage returns, the data is effectively skipped on signing but looks legitimate! With a MitM, an attacker could add arbitrary text into the message being signed. minisign, they found a similar issue with comments as well. If you try to add a newline or carriage return to the comment, it will replace it with a nullbyte and check the signature of that. When the actual string is displayed, it uses the full line though. So, signed\ninjected will become injected when signed but display all of the content. The tldr; is that C strings are hard!unoswap sometimes uses a different value as the source token. In particular, with UniswapV3, it will use the bitmaps from the pool value from before. So, there's a desync between the validation and usage.balanceOf. Now, on the second part of the trade, we can get all of the funds out. mediacodec sandbox on Android. This is constrained by SELinux, where non-secure software is initialized. After reviewing the available attack surface, they found the driver /dev/bigwave was accessible from the sandbox. This is a Pixel SOC that accelerates AV1 decoding tasks, meaning it was intended to be accessible.inst to store private data is created. Within this is a job that tracks register values and the job status. To submit work to the bigo hardware, a process called an ioctl is used to place the job in a queue and have it be used by a separate thread. In practice, this meant that an object whose lifetime was bound to a file descriptor was accessed by a kernel thread without any validity checks. BIGO_IOCX_PROCESS submits a job to the bigo worker thread. In this, it enters wait_for_completion_timeout with a 16-second timeout. After this, the job is removed from the priority queue. If enough jobs are queued, the thread may exit early. If userland closes the file descriptor associated with BigWave, the job is destroyed while the worker thread still references it. kmalloc allocations, such as Unix Domain Socket messages, it's possible to control the job->regs. This allows for where and what is being written by the program. This creates a 2144 byte arbitrary write! From previous research, they found that 0xffffff8000010000 (.data) is static and contains many useful kernel globals. So, there's no need to defeat ASLR at all.init_cred. They now have root credentials with SELinux disabled. emdf_payload_size parameter. Ivan Fratric found that copying the data from this content into the heap contained a simple integer overflow. By using this, along with a stop point for the emdf_container_length of the buffer, a buffer can be underallocated without turning into a wild copy.skip. By carefully filling the heap with multiple payloads, it's possible to overwrite the pointer and have arbitrary attacker-controlled data written to it. mediacoded difficult, primarily SELinux. Some co-workers, Jann Horn and Seth Jenkins came up with a plan to work around these limitations. Use ROP to write to /proc/self/mem repeatedly to make it a descriptor that's easy to guess. Then, use pwrite on the shellcode in memory to overwrite a function's code. This works because /proc/self/mem allows for any memory in a process to be overwritten for debug purposes. mediacodec contains several seccomp rules that prevent a process from executing syscalls that aren't necessary but were left out of the Pixel 9; this would have prevented the pwrite strategy that was used in this post. This would have required several weeks of development effort to implement the entire exploit in ROP.-fbounds-safety flag, the exploit isn't possible. m.facebook.com with strict origin verification. The cross-window message-handling mechanism allows direct HTML injection, which is assumed to be safe because it's from a trusted domain. The reality is that all messages originating from this domain were trustworthy. Practically, origin validation is only as strong as the security of the trusted origin.direct_debit_ach_initialization's learnMore event injects HTML directly into the DOM. This creates an XSS opportunity, if we can find more bugs. On one of the third-party providers, they found code that loads a remote configuration file via a URL and calls eval() on the cmd parameter. location.href of the iframe and compromise the account. postMessage to get XSS on Facebook.extra_data commonly contains a redirect path, which is verified by the application that depends on it. This endpoint allows redirects to /accounts_center/ for the Instagram application. By using double URL-encoding and path traversal, it's possible to bypass the normally strict redirect endpoint.postMessage with the * origin, including the token in its payload. This is the leak of the token that we wanted. This ONLY works if the nonce is set correctly.