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!
IMPORTHTML is a great target because it makes web requests. By concatenating rows in the sheet to the web request, they would be able to see some of the data in the sheet. The server that received the request also logged the host, path, query, timestamp and user agent. createRequest, it takes in a protocol, host name + port and path. A recent vulnerability labeled that the x-forwarded-host header was used to construct the URL without any validation. Although this was fixed, it seemed to open a pandora's box around these types of issues. Notably, x-forwarded-proto was NOT fixed. Since the protocol lives at the beginning of the URL, it's possible to use this header to change the rest of the URL being parsed.x-forwarded-proto and rerouting; if we do this, THIS is the final path. Time for some trickery.x:admin?. First, the parser sees the protocol x. Since there is no /, the path is parsed next - not an authority; the path is admin. If the URL is special, such as http, then the slashes can actually be skipped. http:admin? would have the domain be admin and contain an empty path name./admin. In the case of x:admin? the path is admin! The missing forward slash creates an incorrect string comparison that allows for bypassing the verification. The question mark is required for the path in order to eat the real host and path. x-forwarded-proto header as part of the cache key. So, if the application generates dynamic links based upon Astro.url, this can now lead to XSS. The link can be poisoned to all who access the page. x-forwarded-host was included. By setting this to an empty string, JavaScript treats this as null on the check and no validation is done. Later on, the empty domain is used and concatenated with the path. By setting the path to be the domain the URL becomes controllable once again. A neat bug!0x333333 is written back to the CRIT1 and CRIT2 OTP rows, changing the chip's security. This disables secure boot, bypassing the chip's security. Additionally, DEBUG_DISABLE is also disabled, giving full debug access to the chip. This issue was found by dynamically debugging the chip and observing the results. Pretty neat!otp commands that an attacker could run. This is done by reading the SW_LOCK fuse twice. The code performs left and right 28-bit shifts to clear the upper bits of the locked value. If the right-shift instruction is skipped, then the OTP value will have a corrupted value and the SW_LOCK write to OTP is skipped. This read is performed twice with randomized time delays, but it is still doable with an Electromagnetic fault injection setup. This allows using the OTP boot to read fuses that shouldn't be accessible.solana-program serves as the main library for interacting with the runtime, including transferring SOL and executing syscalls. Once compiled with Rust, keeping all its invariants, the code is lowered to LLVM IR. This is then translated into eBPF for actual usage. This allows for a pre-built sandbox to be executed within Solana.InitializeBuffer and Write() to an account. Once this is finished, a separate instruction runs various checks, such as bytecode and ELF verification. MEMORY_DESCRIPTOR on the UVM_MAP_EXTERNAL_ALLOCATION for Unified Virtual Memory Framework. Usually, this would be a crash, but it has a much more devious consequence. threadStateInit() and threadStateFree() functions are used cross the open-gpu-kernel-modules a lot. The thread-state structure is added to a global red-black tree during initialization and removed once it is freed. The structure is a pointer to the Stack! If there's a kernel oops then the stack would be cleaned up. The second vulnerability is a stack use-after-free triggered by the null pointer dereference from above. I imagine that the author found this issue first and then searched for a crash.vmalloc area. Its purpose is to allocate virtually contiguous memory with page granularity. It's used for stack allocations and for large kernel allocations. The goal is to get control over this data for reads and writes via a new allocation and then use the value in as a threadState. random_kstack_offset feature, but it's a good starting point.open syscall, we can calculate offsets to where we need to write to and then overwrite arbitrary values on the stack. Notably, the file pointer can be corrupted, and it contains function pointers! To get the KASLR slide, sock_from_file() can be used to access private socket data and check the file type. By triggering different errors, it's possible to leak KASLR.llseek() has no checks before calling the handler on the validity of the pointer. From userland, we can control the parameters and return values. How nice! With this, it's possible to corrupt the struct file directly to achieve code execution within the kernel. With this powerful call primitive, they created three primitives: kernel symbolication, arbitrary read, and arbitrary write. With these, they overwrote the creds of a process to become root. Neat!unwrap() that will cause the program to panic when there are more than 60 features. Bad!isalnum from libc that could take in user controlled input and was already loaded in the GOT. The difference between this function and system() is only 0x13230. So, the goal was to add this much to the address in the GOT entry to trigger code execution. While hunting for quick/easy gadgets, they didn't find any. All of them had side effects that made it infeasible. isalnum@got and store the results in r6. The gadget wasn't perfect but did the job before jumping into the value in r3 for the next gadget.system(). Then, trigger the overwritten GOT entry for code execution./api/v2.0/cmdb/system/admin/) and then traversing backwards via ../ it was possible to traverse a different CGI executable on the device. The program likely took the rest of the path after the API endpoint and just used that as the path for the executable. However, the actual vulnerable path wasn't confirmed. cgi_process. The first check just performs basic JSON validation. The second item, labeled as cgi_auth(), is an impersonation function and NOT an authentication check. It extracts the header CGIINFO to decode a username, profile name, virtual domain and login identifier. With this information, you can impersonate any user in the application, such as the built-in admin.