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!

Linux CLOCK_THREAD_CPUTIME_ID LPE- 950

noamr - SSD    Reference →Posted 3 Years Ago
  • A CLOCK_THREAD_CPUTIME_ID timer is used for measuring the amount of CPU time consumed by a thread. A timer will be armed once timer_settime is called. After the set amount of time, a signal is sent to the thread, indicating that time is up.
  • The Linux kernel implements this feature by tiking a k_itimer structure into a doubly-linked list of all the timers. The elements in the list are constantly checked to see if it's time to expire, firing the signal. When calling execve, the kernel will free all of the timers associated with a process, except the global structure of posix_cputimers.
  • Practically, this means that if the timer is already armed before execve the kernel will free the timer while still maintaining the reference in the doubly linked list. This creates a dangling pointer situation. Later, when the timer is set to go off, it will trigger a use after free situation on the object, then free it, creating a double free.
  • The author includes a full exploit in their code. From reading the code, it appears that they are spraying objects to go into the place of the timer to trigger a free on the target object. By doing a page spray (lower level than a heap allocator) with sockets. By freeing this, they are able to get a two leaks.
  • After knowing this information, they leak a msg_msg object with the same strategy as before but only with msgq objects. Finally, they use this to get a KASLR leak.
  • Once they know where everything is located, they trigger the bug again but keep a reference to the timer object with a separate allocation - use after free. They write to the timer with a separate and improper allocation to get an arbitrary write primitive. They use this to overwrite the modprobe path to allow for the loading of arbitrary kernel modules. Code execution gained!
  • Overall, a good description of the bug but nothing on the POC. The POC does have good comments though, which makes it possible to read.

Attacking Firecracker: AWS' microVM Monitor Written in Rust- 949

Valentina Palmiotti - Grapl Security    Reference →Posted 3 Years Ago
  • Firecracker is an open source Virtual Machine Monitor (VMM) by AWS written in Rust. The purpose of this project is to allow for multi-tenant services to run on one machine. Firecracker is built on top of the KVM, built by the Linux project. Being able to break out of Firecracker would allow for cross-tenant access to data, a major problem.
  • The KVM is a type 1 hypervisor, meaning that it runs on bare metal (unlike Hyper-V). The KVM is made up of two modules: one for providing the virtualization infrastructure and the other for processor specific models to take a slice of the CPU. Each VM runs as a regular Linux process on the host, with a low level API for interacting with it at /dev/kvm.
  • Firecracker is a VMM that uses the Linux Kernel’s KVM virtualization infrastructure to provide Linux and OSv microVMs on Linux hosts. Storage is done via a block device and there are several virtualized services like this as well. The API that the vulnerability was found in is the vsock, which is used for communicating between a virtual machine and the host. AWS designed this in such a way to reduce VMM attack surface and put most of the stuff on the client side.
  • virtio-vsock is a guest/host communication device that allows applications on the guest and host to communicate via socket. In QEMU, this is implemented in a kernel module. For FireCracker, it is implemented in user space, but the device model is over MMIO to the VMM directly.
  • When a VM is created, RAM is allocated using MMAP into the MemoryRegion structure. This has a guest_base (physical address on the guest and MemoryMapping, which is a pointer to the memory of the Firecracker process this belongs to. The drivers running in the guest’s kernel communicate with Firecracker through shared buffers.
  • The guest creates buffers with a descriptor table and signals that the buffer is ready to be consumed. Each index of the table contains a table with an address and a length field for I/O to be performed. Since this is user provided input, it should be treated as malicious/untrusted. However, the validation of the data simply checks that an integer overflow hasn't occurred. So, what's the problem?
  • An address may NOT exist within an allocated memory region or overlap with a different region. Memory corruption is upon us! How do we exploit this though? Using the VsockPacket, it is possible to read or write out of bounds as long as the buffer starts in a valid region and ends in a valid region. So, we can use the space between two regions using the unsafe Rust code.
  • To exploit this vulnerability, an attacker needs code execution within the context of the kernel to hit the virtio-vsock driver. What's in that gap space? Nothing too interesting. The author eventually gave up on exploitation, simply because the overflow didn't allow for the overwriting of anything helpful. A buffer overflow into the stack was possible, but there were guard pages setup.
  • Since this bug was fixed, a few extra mitigations were put in place that are interesting. First, there are guard pages between all Memory Regions. This prevents this type of attack from happening in the future. Second, the there context is restricted via a jailer program and per thread secccomp filters. Hardening and exploit mitigations from the beginning make memory corruption vulnerabilities extremely hard to take to full code execution. Overall, good post on security design!

Tesla Charge Port Remote Control Signal- 948

akrutsinger    Reference →Posted 3 Years Ago
  • The Tesla charge port is vulnerable to a simple replay attack. The author of this post analyzed the signal deeper.
  • Using GQRX, they captured the signal. From reading the FCC ID, this runs at 315MHz. However, for the recording, you want to use something NOT exactly at 315MHz, just as 315.5MHz. This is because there is always a loud frequency at the center where we want to listen (DC voltage issue).
  • With the recording in hand (raw I/Q data), the author takes to it in Inspectrum. The signal is very clearly using OOK (on off keying). Using the threshold plots, the raw bits can be recovered from the signal. Inspectrum is such an amazing tool!
  • From looking at the recording, a transmission is made up of 3356 symbols with a symbol rate of 2.5kBd.
  • The signal has a preamble of oscillating 0s and 1s. After that, there is a 42 byte charge port signal. These two sections are repeated 10 times each.
  • The author created a GNU radio flow graph for this as well. Simply adding your port number and sending this would open the Tesla! Overall, a cool topic with a fun analysis.

Attacking Titan M with Only One Byte - 947

Damiano Melotti & Maxime Rossi Bellom - Quarkslab    Reference →Posted 3 Years Ago
  • The Titan M chip was put onto Pixels in 2018. This chips main purpose is to reduce the attack surface for attackers. This chip is on a separate SoC that runs its own special firmware and communicates to the main chip via the SPI bus. The point of the chip is to hold secret information, such as a hardware backed keystore.
  • The firmware runs a lightweight open source operating system called Embedded Controller. The OS acts as a Real Time Operating System (RTOS) with only the concepts of tasks. It only have a fixed stack size and no heap. Additionally, it has Nx but no other binary protections, such as ASLR or stack canaries.
  • The authors decided to fuzz the different services offered by the Titan M chip for memory corruption vulnerabilities. They tried two approaches: black-box fuzzing and emulation based fuzzing. The black-box fuzzing was simple to do since the tasks use ProtoBuf, allowing for the built in libprotobuf-mutator to be used. ProtoBuf definitions have to be around somewhere in order for this to be usable. They found a few bugs with this but because they couldn't just hook GDB up to the OS, it was much harder to find deep bugs.
  • Emulation based fuzzing was more fruitable on this project, since the firmware was publicly available. After reverse engineering the firmware some more, they found the proper place to put the inputs in order to mutate the proper things for fuzzing. To emulate and fuzz, they used AFL++ and their Unicorn emulation mode. One issue with emulation based fuzzing is that hardware-dependent functions must be hooked to have no functionality in order to still run.
  • After fuzzing for a while, they found a crash in the call to ImportKey. The parameters were simply taking a large index and writing the value 1 to this. This vulnerability looks small but can be triggered multiple times. Additionally, since the memory is completely static and this is a relative write, lots can be done with this.
  • Before they wrote the exploit, they had to find a reasonable way to debug this... without GDB or some debugger. The chip has UART debug output on it. If they could run code that would print to this log, it would be possible to learn some information about the system. Attacking these chips is hard not because of the complex vulnerabilities but because of the non-standard exploitation environment providing other challenges.
  • What do we even overwrite with a single 1 that would be useful? After writing Ghidra scripts looking for good targets they found the structure KEYMASTER_SPI_DATA, which contains information about the messages going back to Android. By overwriting a pointer to this structure from 0x192c8 to 0x101c8, later incoming requests will be written to this location! Since this is a valid address, this gives us a much better primitive for writing.
  • They noticed that writing a valid code address to 556 bytes after the payload for a KeyMaster operation allowed them hijack control flow. This was tested by force printing logs to the UART console. From there, they wrote a ROP chain with a complicated stack pivoting gadget.
  • The only way we could return our leaked bytes back to Android was to copy them in the response of an SPI command. To do this, they needed to be in the context of the handling, which was essentially in a jump table. To make this work, they used the previous calls to setup a stack frame with a SINGLE gadget to move the stack. By doing this, they could write to a location where the data wouldn't be changed between execution of tasks. Eventually, another call could be made, using the previous data as the final ROP chain.
  • The final ROP chain called memcpy with the user-provided arguments, allowing them to read in the Keymaster SPI response buffer. Then they could jump back to the Keymaster stack, like the normal command handler would have done, to return the data. This allowed them to dump all of the secrets on the chip. Overall, great post on vulnerability discovery and exploitation!
  • The PS5 has a major bug bounty program. The author decided to look into this device, being a legend in the playstation hacking scene. After looking at the attack surface, they decided to look at the Playstation 2 emulator. This was because the JIT privileged code had been removed from other part of the system and it would be unpatchable once fund.
  • Initially, the author needed code execution within the context of the game while in the emulator. This was done by using a known save game exploit from Okage Shadow King, with a standard buffer overflow in the player/town name. Since the PS2 had no exploit mitigations, this was trivial to do.
  • Now, it was time to reverse engineer the emulator itself. While reviewing the code for memory read/write callbacks, the author noticed a missing bounds check on the buffered operations. This would allow for writing 16 times the allowed amount of data; this bug had several variants of it in other locations.
  • By using the first vulnerability, we can overwrite a status index being used. Using this, we gain the ability to write an arbitrary byte to an offset of 4 bytes. Since this is relative to a static buffer, ASLR can be defeated with the relative write.
  • The vulnerability above allows us to corrupt a set of function pointers within the program. Since no CFI is enabled on this, this allows for arbitrary functions to be called. Additionally, this returns a value in EAX, which could be used for a very strange read call.
  • The PS5 has ASLR turned on, which needs to be defeated. One way would have been using Spectre-like side channel attack. In this case, they found that using a relative overwrite on the function pointer allowed (which was written to EAX), to return instantly allowed for the leaks of pointers.
  • From this leak, they could gather the offsets they needed for the rest of the eboot binary; they knew where the executable, read/write and read only pages were. This allowed for further gadget created within this part of the ecosystem. They found a gadget to leak the stack address, using the code execution technique above.
  • Single code gadgets are nice, but not powerful enough. Instead, the author wanted to be able to execute arbitrary ROP chains of multiple gadgets at a time by pivoting the stack pointer. To pivot the stack several nested calls had to be made to control the value in ESP.
  • To load a custom game, a few things could be done, such as USB ports or networking. The program had to be put into a recognizable state but arbitrary PS2 games could now be loaded to the system. In part 2, they will get arbitrary code execution outside the emulator for a homebrew-like experience.

Breaking Bitbucket: Pre Auth Remote Command Execution (CVE-2022-36804)- 944

AssetNote    Reference →Posted 3 Years Ago
  • Bitbucket is a service similar to Github. The authors of this post were after an RCE bug. Since they know that many platforms will end up with calls to git, they wanted a way to trace this.
  • To trace this, they pspy, a way to snoop on processes without being root. In particular, they were looking for calls to git in the process logs with the canary PEWPEW inside of it. They triggered a bunch of requests to see what would happen.
  • First, they found a argument injection bug. However, this bug appears to be unexploitable because of the command that was the arguments could be added to. Eventually, they ended up tracing a call to git archive where the value of the --prefix= could be controlled.
  • Bitbucket is written in Java. Since this is the case, the input is likely parameterized when being inserted into a command to execute, making it unlikely that argument injection is possible. However, passing in nullbytes via %00 in the parameters seems to bypass this limitation.
  • By adding padding%00--option%00padding, the prefix option was escaped and they got the error message "--option is not a option a git subcmd". Amazing! They had escaped the command by simply fuzzing and trying different things!
  • git archive has the amazing flag --exec. Passing in a command for this parameter, alongside the flag --remote-flag with a file URI would lead to code execution with this parameter. At the very end, the injection input was x%00--exec=/bin/bash+-c+'touch+/tmp/haced%23'%00--remote=file:///%00x.
  • After writing the exploit, the authors wondered why the nullbytes being added worked. Atlassian had patched this bug by disallowing nullbytes in the parameters of this call. This is because the function Java_java_lang_ProcessImpl_forkAndExec was being used to execute commands; this takes a char array as the command.
  • Since the char arrays are separated by nullbytes, they were transforming the amount of arguments used in the low level Java call. This allowed for the injection of the new parameters. Pretty neat!
  • Sometimes fuzzing and trying random things is more important than understanding the entire eco-system through and through. I probably would not have found this, simply because I would have assumed the Java API was secure against this. Overall, good article!

AttachMe: critical OCI vulnerability allows unauthorized access to customer cloud storage volumes - 943

Elad Gabay - Wiz.io    Reference →Posted 3 Years Ago
  • Oracle Cloud Infrastructure (OCI) is a similar service to AWS, being a cloud computing provider. Isolated components from other clients is immensely important for security.
  • The AWS EC2 equivalent is the OCI compute instance. This is simply a server that is span up to perform operations that the user wants.
  • When using a compute instance, you can attach volumes, or disks. The vulnerability is that the volume attachment did not validate that the user had access to it. In particular, this could be done cross account in order to steal sensitive information or modify the volume to escalate privileges.
  • To exploit this, an attacker would need to know the OCID of the target volume, which could be brute forced, guessed or found on the internet. It's unreal that these trivial bugs exist on a cloud platform in use today. Personally, these types of issues are unacceptable from a security standpoint, which is why my website is hosted on AWS.

Securing Developer Tools: OneDev Remote Code Execution- 942

Paul Gerste - Sonar Source    Reference →Posted 3 Years Ago
  • OneSev is a self-hosted Git server with many other features like CI/CD, code search and many other things. Since it is open source, this was a good target for an audit.
  • A user is allowed to set webhooks, which must be provided a URL, with event data in its body. The URL is not restricted at all, allowing for the server to call itself on an internal IP. The first vulnerability the author found was a Server Side Request Forgery (SSRF) bug; a very limited one at that.
  • There was an internal authentication check on the server. This was done by seeing if the X-Forwarded-For header was set to 127.0.0.1. If this is there, then some access control checks are completely bypassed. This header can be spoofed or made by the SSRF.
  • Using the auth bypass on push events, arbitrary environmental variables and commands can be specified. Alas, this had safeguards against command injection and argument injection but NOT messing with the ENV variables.
  • By setting specific GIT environmental variables, havoc can be caused. The variable GIT_TRACE_SETUP allows for verbose output to a file, with drawbacks. First, it would only append to existing files NOT overwrite them. Second, only parts of the debugging output are controlled by us.
  • To get around this, the attacker noticed bash scripts used by the service that could be appended to. By creating a special directory and referencing this file, the output could be included to have a bash command put into the script.
  • OneDev recommends starting the server with access to a Docker socket to enable its Docker-based CI/CD pipelines. If the OneDev server is hosted in a Docker container itself, this is recommended to be done by mounting the host's Docker socket into the OneDev container.
  • By making requests to the Docker socket, it is trivial to escalate permissions by using mount and privileged onto the main host. This is almost a security vulnerability by design.
  • Overall, good post with concrete bugs. I do wish examples of the exact requests made for the vulnerabilities were shown though.

Wheel of Fortune Outcome Prediction – Taking the Luck out of Gambling- 941

Jesus Calderon Marin - NCC Group    Reference →Posted 3 Years Ago
  • Roulette is an over the board game that is similar to Wheel of Fortune. Since these are spun by hand of the person running the board, the author asked "is this good randomness?"
  • In the game, there are 54 small segments: 1, 2, 5, 10, 20, 40, 1x and 2x. Players bet on a number that the wheel will land on. For payouts, the player gets the money bet * segment + 15. If it lands on a multiplier, the players winnings are multiplied by that amount.
  • The author did an analysis on which numbers were landed on, which segment was landed on and a few other pieces of information. From there, the author looked at the randomness of these values to see if they could gain an edge.
  • The author noticed that the particular numbers on the board did not have random probabilities for being landed on for the turn being performed. They did analysis on the expected amount of money outputted from this as well. For example, position 29 had a 2.15% probability instead of the expected 1.851% probability.
  • The strategy is pretty simple. Wait for the 40 number to be the in the relative 29th position. If not, then don't bet. Using this strategy would take a while but would yield results with a 90% probability. This means that the house edge could be overcome but exploiting the lack of randomness on spins.