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!

Analysis of Satisfyer Toys: Discovering an Authentication Bypass with r2 and Frida- 573

Banana Mafia    Reference →Posted 4 Years Ago
  • The author decided to review the security of internet connected sex devices. The device is controlled via a bluetooth from an Android application, where other people can control the device.
  • The interesting part of the post is how the authentication works for the API. When starting the authentication process the user creates the initial Json Web Token (JWT) with the ROLE_ANONYMOUS_CLIENT. After this, the API returns a JWT with the ROLE_USER to interact with the API. Why does the client sign the JWT to start with?
  • The builders of the application clearly did not understand how the security of JWTs worked. By using the JWT signing functionality of the client, the key can be used to sign it for other purposes! For instance, using the ROLE_USER for any other user on the application. The client and server share the same key for signing! This JWT is hardcoded into the application.
  • Using the forged JWT allows for becoming any other user on the application. An attacker could now hijack this and control the Satisfyer of another person or takeover the account.
  • To mitigate this vulnerability, the server-side could use a different key for signing JWTs. Even though this flow is still janky, it would be secure without major changes to the application.
  • Satisfyer also uses WebRTC to send file attachments and control of the other devices. The second feature relies on the TURN protocol from Coturns implementation. Instead of the server generating temporary passwords, they used their hardcoded admin credentials for the communication. This could allow for the viewing of other communication of people... Yikes!
  • Key and password management is a hard problem on cellular phones or game consoles. An attacker has access to everything; how can we stop them for escalating privileges. This is not the way to do it for sure.

Selecting Bitmaps into Mismatched Device Contexts - 572

Marcin Wiazowski - Zero Day Initiative (ZDI)     Reference →Posted 4 Years Ago
  • To handle devices on which drawing can be performed (pixel-based devices), Windows provides so-called device contexts (DCs). Device contexts are an abstraction of the user-mode and low-level drivers that actually perform the actions for rendering on the screen, such as pens, brushes, bitmaps and so on.
  • Bitmaps are rendered as surface objects in Windows. The hdev value of a bitmap is used as a handler to point to an object in physical memory, being a device object. Gaining control over this value would spell havoc!
  • Prior to Windows 2000, printer and screen drivers were in the kernel. But, because vendors were making horrible drivers that were riddled with security issues, the printers were stuck into user mode. Still though, a fair amount of printer functionality still exists in the kernel that just points back to user mode functions. Sometimes, there are differences between the two!
  • By calling one of the kernel functions instead of the user mode functions we are able to control values that we normally cannot control. In this case, we have control over the dhpdev and flags when calling SelectObject or EngAssociateSurface in the kernel world. dhpdev can either point to kernel memory or user space memory when passed into this function.
  • When GDI graphics are used, there are two code paths that can be taken: the known path and the generic implementation, which is taken via the flags field to call a specific list of allowed functions. By mixing and matching the kernel and user space API calls, we can get the program into a state where the dhpdev is desynced from the expectation. Instead of pointing to a pointer in the kernel it now points to user-mode memory.
  • This is a really interesting type confusion bug! We control a pointer to data that we should not be able to directly control. Using this bug, we can trick the display driver into overwriting arbitrary kernel memory by passing in a malicious dhpdev block. There are some tricky requirements that are specific to Windows and the subsystem (so, I won't go into it).
  • The rest of the article is about creating a malicious dhpdev block that allows for compromise of the kernel. The other interesting thing about the article though is the fix for the bug. Microsoft added a function called win32kbase.sys!bIsSurfaceAllowedInDC to check for this exact case of events. Seems like a brittle fix to me.
  • Great research and a lot of background on this part of the Windows OS. Type confusion/logic bugs are always fascinating to me because it is using the system in an extremely unintended but just barely valid way.

Stored XSS using .xbl files- 571

Positive Technologies (PT) Swarm     Reference →Posted 4 Years Ago
  • .xbl or XML Binding Language is an XML-based markup language for altering the behavior of XUL widgets. Different file types get rendered on the web page while others do not.
  • When a client is using a denylist of file types (js, HTML, etc.), then using obscure file types, such as .xbl, are awesome for getting XSS. Interesting find that I will have to try out!
  • It should be noted that the Content-Type header makes a big difference on how items get rendered. So, trying this on Google Drive will likely not work. But, if only a denylist is used without setting this header properly, you may find XSS!

CVE-2021-31969: Underflowing in the Clouds - 570

Hossein Lotfi - Zero Day Initiative (ZDI)     Reference →Posted 4 Years Ago
  • The Cloud is the way to go! Even on your Desktop, you can sync cloud based file storage with local storage. This post is about the Cloud Files API on the Windows OS.
  • Windows Cloud File API offers support for cloud sync engines and handles tasks such as creating and managing placeholder files and directories. This syncs between remote file system and the local client. With a large file, instead of taking up a massive amount of space on the computer, a placeholder is inserted instead.
  • When performing this operation for syncing the file system, there is a bug on changing the length of the packet. After the initial connection, the length of the point data can be set to 0. Clearly, the data we are written does not have a length of 0!
  • The problem is not the length being 0 though; there are bounds checks that happen. The vulnerability is that the length of the buffer used is subtracted by 12 when decompressing itself.
  • Because of the subtraction, this results in an integer underflow and a length of 0xFFFFFFF4 on the buffer. Whether this bug is exploitable is not mentioned in the article. The exploitability of this bug is dependent on whether the wildcopy can be stopped or not with controlled data.
  • Microsoft fixed this vulnerability by adding a check to make sure the retrieved length is not less than 4. This makes it impossible to trigger an integer underflow.

Hacking DEF CON 29- 569

Reznok    Reference →Posted 4 Years Ago
  • Historically, for DEF CON, you purchase everything in cash at the conference. This allows for people to remain anonymous if they would like to. Because of covid 19, you are supposed to buy the ticket online prior to the conference. With online data comes the potential for things to be leaked!
  • After Reznok purchased his ticket, there was a screen for reviewers the order with a click for the badge. The author noticed that he had no logged in and there was no token in the URL. Why not throw this into incognito?
  • When the author popped this into incognito mode, the payment information was still there! To make matters even worse, the ID was sequential, making these purchases easy to find. The author looked for a few other tickets then decided to report the finding to the Dark Tangent.
  • Reznok could have seen the name, ticket and email of all the people that had bought the tickets online. For a group of people that value anonymity, this is really bad! The issue was fixed quickly from the host company.

32 bits, 32 gigs, 1 click- 568

Jack Dates - RET2    Reference →Posted 4 Years Ago
  • Web Assembly (WASM) is an assembly-like language intended to make the web fast. Applications can be compiled into WASM, such as Rust, in order to make a faster internet. This article is about breaking parts of WASM to get code execution within the browser.
  • The WASM execution pipeline has three stages of execution: parsing and two JITs. The Low Level Interpreter (LLInt) or parsing functionality is used for the bytecode generation process for the browser.
  • This parser is responsible for verifying function validity, including type checks and flow control. Wasm functions have a structured control flow in the form of blocks (which can be a generic block, a loop, or an if conditional). Each block has its own expression stack and can return multiple variables.
  • The m_maxStackSize field of a function is needed to get track of the amount of stack slots. This value is updated at multiple points, such as a push operation. When the parsing is done, is it rounded up for stack alignment purposes.
  • However, this alignment is not validated for an integer overflow! By setting the m_maxStackSize to UINT_MAX (0xffffffff) we can wrap around to 0. The variable m_numCalleeLocals, which determines the stack frame size during the prolog, will not allocate any data for the stack frame but write a bunch of data!
  • To trigger the operation the bug, the authors wrote a Wasm function that contains 2^32 push operations. With wildcopy bugs, we need to stop the write somehow. By using a quirk of the JS engine with it's handling of unreachable code, we can trigger the largest possible stack frame without crashing.
  • This exploit requires 16 vectors take on about 2GB of memory for a total of 32GB. On macOS, compression memory makes this doable! To run this, it takes about 2.5 minutes to allocate all of this memory.
  • With the stack frame in a weird state, we can now get a memory leak. To make this happen, the authors write a function that has 2 arguments. When processing Wasm, there are what are called slow-paths, which will call C++ functionality natively. By calling the slow path in a particular way, we can get the C++ functions to overwrite our parameters for an information leak. One of the paths gave the address of JavaScriptCore dylib and a stack address.
  • The offsets for writing will only go DOWN the stack. As a result, nothing useful can be overwritten within the context of our current thread. So, in order to make this exploit work, we are going to hop from our current thread into something else. By using quirks of the engine, we can write to arbitrary offsets in the positive direction.
  • With the arbitrary write from a particular offset, the authors can overwrite values on the victim stack. Using this, it is trivial to overwrite the RIP on the other threads stack. For leaks, we can simply read from an offset of the stack.
  • To read from the location on the stack, the following Wasm works:
    local.get 0 ;; JavaScriptCore dylib address
    i64.const <offset to gadget>
    i64.add ;; the addition will write the gadget to the stack
    
    For writing, the same primitive works but using a local.get 1 instead.
  • To get arbitrary code execution with our own shellcode, we need to bypass SIP, which only allows sections of code to be RWX if mapped with MAP_JIT. So, we must map our own section to wrote our own shellcode.
  • This vulnerability was patched by utilizing checked arithmetic within the generator for the various stack operations. Besides using unsigned values, it also has code to ensure that no overflows occur.

Sequoia: A Local Privilege Escalation Vulnerability in Linux’s Filesystem Layer - 567

Bharat Jogi - Qualys    Reference →Posted 4 Years Ago
  • A file system is an organization of data and metadata on a storage device. It controls how the data is stored and retrieved, and its most important function is to manage user data. Finding a vulnerability in this is catastrophic!
  • The Linux kernel's seq_file interface produces virtual files. Each record must fit into the buffer size. When the node grows too big, the size is doubled. This size value is of type of size_t, which is a 64-bit unsigned integer.
  • This size value is passed to multiple functions that use an int, which is a signed 32-bit. This results in an insecure truncation and a insecure signed issue. This can lead to memory corrupt bugs when allocated the right buffer size for the information for the file node.
  • In order to trigger this, an attacker needs to create, mount and delete a directory structure whose path is larger than 1GB. Then, when looking at /proc/self/mountinfo, the code path deals with the insecure integer truncation.
  • The actual issue is that the function dentry_path expects a 32 bit signed integer. However, the truncation results in a negative value for the length of the buffer. When this buffer offset gets used, it writes the string //deleted to a specific offset.
  • When an attacker controls the system as well as they do on Linux, this primitive is enough to get things started to get deeper primitives. In order to exploit this, the authors created a small eBPF program that has been validated within the kernel. Once this has been validated, the vulnerability is triggered that overwrites instructions of the eBPF code, breaking the security guarantee. This is done multiple times.
  • This overwritten instruction transforms into an out of bounds information disclosure and a limited write. Using the out of bounds write, they turn the exploit into a full on arbitrary read/arbitrary write by using ntf and map_push_elem.
  • It's truly amazing how such a simple bug (integer truncation) turns into a full Linux kernel privilege escalation. To me, this integer truncation issue is more likely in many more spots. Most of the time, compilers do not call this out. Great find and great research!

Finding and exploiting hidden features of Animal Crossing's NES emulator- 566

James Chambers    Reference →Posted 4 Years Ago
  • Animal Crossing is a social simulation video game series developed and published by Nintendo. It has many iterations including GameCube, Wii and Switch versions. The focus of this article is on the GameCube version of the game.
  • While exploring Animal Crossing in on the Dolphin emulator, the author wanted to know how the NES emulator in the game works. From a tiny bit of reversing, the game has small NES ROM image within the game. This means that the game itself contains a custom NES emulator. But, how does the emulator load the game and how does it know which game to load?
  • The author used the Dolphin GameCube emulator to force jump to the section that would load the ROM. The game itself it stored on a memory card when it tries to load the ROM, which can be seen in the crash logs. Now, we know that the game itself it stored on a memory card when it tries to load the ROM.
  • After some more reversing, the author found the location where the game was being loaded from the memory card: offset 0x642. After adding a ROM to this memory card location with the proper magic file headers, most NES games booted up. At this point, the author has a Save Game attack vector: what can we do with this?
  • The author was interesting in spotting a Save Game exploit that would cause enough memory corruption to take over the GameCube. From messing around with special tag functionality, the author noticed complex memory manipulation for loading metadata with dubious calls to memcpy. Because of this, they started bug hunting in this area.
  • The NES is a 16-bit system. So, most of the offsets for values were only 16 bits long away. However, the QDS parsing area loads a 24-bit offset. One issue has a maximum value of 0xFFFFFF, which is much larger than the boundary of the ROM. But, because this write zeros everything out first then later does the write, this did not look like a good option to pursue. There were many other deadends that would simply cause crashes but nothing exploitable.
  • Eventually the author found the PAT tag, which was by far the most complicated of all of the tags. A PAT tag has a 8-bit type, 8-bit patch size and a 16-bit offset value, followed by the patch data. Using this patch code, it would be possible to edit the NES game being loaded on the current platform.
  • The patch address validation is flawed! Because of the poor validation, it allows us to overwrite arbitrary data on the heap from 0x80000000 - 0x807FFFFF with the format described above. Because Animal Crossing loads in this space, we can use the patching functionality to overwrite arbitrary locations inside of Animal Crossings game on the GameCube. This is a complete emulator escape!
  • Patching data is trivial. But, what if we want to patch the game? Because of the Instruction Cache on the CPU, overwriting the instructions does not do anything to start with. To get around this issue, the author overwrite a function pointer within malloc to divert the flow of execution. Because the pointer was now changed, we could point it to our own code to do whatever we wanted within Animal Crossing.
  • To wrap this up, there are few interesting reversing tips that should be pointed out:
    • Error messages go a long ways when debugging.
    • Files and parsers LOVE magic values, such as AA55 for bootloaders.
    • Dynamic debugging is the way to go in order to hit normally unreachable code paths. This will help you see if something is worth your time or not.
  • This is an awesome post on a 20 year old game console that I grew up on as well. Emulation is tricky to do, which is why this exploit works in the first place.

Gotta Catch 'Em All: Frida & jailbreak detection- 565

Romain Thomas    Reference →Posted 4 Years Ago
  • Clients that run on machines have an interesting problem: we control the client. How do we know that the device is not being tampered with? How do we know that the application is not being reversed? Because developers do not want their IP stolen, there is a constant arms race on exploitation and protection.
  • Pokemon Go is mobile phone game meant to bring Pokemon to real life. The authors of the game, understandably, do not want people cheating at this game. People can cheat by spawning arbitrary Pokemon at will or teleports to foreign countries without actually traveling.
  • To make cheating harder, they have added anti-cheat protections. To start with, whenever the app is loaded when a Jailbroken phone, the game simply crashes. But why? The crashes are intentional!
  • The main Pokemon Go application is just a stub around the Unity implementation, which has the main logic. Among the things loaded is the NianticLabsPlugin plugin. This contains the myriad of protections put into the game to stop reversing, cheating and other things. This library is where the crash happens at.
  • Analyzing constructors gets us a long ways. On iOS and Android, we can hook the function call_array from the ELF loader. Within this, all constructor addresses are checked beforehand, making this a wonderful place to debug the code.
  • By hooking at this location, we can get control before the execution of constructors. This allows for the ability to trace them, replace/disable them and detect to hook other constructors as well. From this, NianticLabsPlugin has 120 constructors with various detection methods.
  • First, it checks for debuggers by seeing if PTrace is attached to the binary. If so, it kills itself. Straight syscalls are used instead of the normal wrapper function around PTrace.
  • In the same area, this is a kill to the PID of the binary with a signal of 0. According to the man page "[…] A value of 0, however, will cause error checking to be performed (with no signal being sent). This can be used to check the validity of pid." If the PID is not valid, we crash the program.
  • Pokemon Go opens a socket on the same port that Frida uses and tests the Frida handshake. If this is the case, then simply crash the program.
  • There is also simply Jailbreak detection that is done by checks if specific files exist. If so, the device is likely jailbroken and should crash. At some point, signature validation is done as well.
  • The ant-debugging techniques on this are pretty serious! The author goes into how to decode obfuscated strings in the binary as well. The new feature of the post (for Frida) is undo all relocations of symbols with an ELF. Overall, interesting post on anti-debugging techniques!

Meet WiFiDemon – iOS WiFi RCE 0-Day Vulnerability, and a Zero-Click Vulnerability That Was Silently Patched- 564

Zecops    Reference →Posted 4 Years Ago
  • A format string vulnerability was discovered within the WiFi daemon. However, it was determined to be unexploitable besides for a DoS. The authors of this article decided to dive a little further into this bug.
  • To me, format string vulnerabilities are incredibly serious because of the capabilities that format strings have. From arbitrary reads to arbitrary writes, it's an extremely serious bug!
  • Within WiFi daemon, while processing SSID names, is where the vulnerability was at. The same bug was found in a log file printer as well. This is where things hit the fan...
  • This new format string bug only required seeing the WiFi in the vicinity; it did not even have to be connected to! To make matters worse, iPhones automatically scan to every 3 seconds for different WiFi names when the phone is off! This is a 0-click attack, as long as the attacker is around.
  • %n in traditional format string exploitation is used to write to arbitrary locations. Apple did not implement this functionality for security reasons. But, the %@, in Objective-C, can be used to print the contents of an object.
  • By using the %@ format string, we may be able to use another object on the stack in the format string. This attack could be used as a use after free for something on the stack or many other objects on stack for a write.
  • By spraying a substantial amount of objects to be on the stack with a Beacon Flooding attack, they found potential values that were being put onto the stack that are controllable!
  • By deferencing these values, pointers and potentially function pointers, could be written in order to pop a shell. With control over the RIP, a ROP chain will do in order to compromise the device.
  • This exploit would likely require a memory leak of some kind in order to exploit. But itself, this bug is enough to get code execution but an attacker would have no idea where to jump to or where to reference pointers. Awesome and bug and research!