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!

Desktop Window Manager (CVE-2021-28310)- 471

Securelist    Reference →Posted 4 Years Ago
  • This bug is a combination of a few issues within the Windows Desktop Manager (DWM). Neither of these issues is a vulnerability by itself. But, by causing a desync in the understanding of a structure, it becomes a vulnerability.
  • The DirectComposition API is used for Windows bitmap composition with transformations, effects and animations. This component is known to be buggy and has many reported CVEs already. To send batch commands, a special LPC format is used.
  • When adding a property with this API, there is an issue with input validation. This adds a new property to the resource but only validates the propertyId and storageOffset after it has already been added! Anytime validation is done after an action occurs, that's a sign of something bad to come.
  • The same code path for the Update functionality does zero validation on this though. Because of the complete lack of validation the attacker can use this as an out of bounds write on the propertiesData buffer if a few checks succeed on the data. However, this version only existed in userland and not the kernel (unlike the first bug).
  • By using the first bug to increase the number of properties, an error to occur without fixing the counter; this resulted in a desync for the amount of properties and the count for the amount of properties. Because the length had been changed, the update could now be used for an OOB write.
  • Finding validation after some action has already occurred is a wonderful source for bugs that cause desyncs. Awesome bug and a straight forward write up.

WordPress 5.7 XXE Vulnerability- 470

Karim El Ouerghemmi - Sonar Source    Reference →Posted 4 Years Ago
  • XML External Entity Injection (XXE) is a common attack against XML parsers. When a full XML file or user input being inserted into pre-formatted XML file, a user can include entities. These entities allow for reading files on the local machine, SSRF and sometimes, even RCE. This attack is devastating when it is found.
  • In Wordpress, there is a Media Library that allows users to upload media files for their blog post. To extract meta information from these files, WordPress uses the getID3 library where some of this information is parsed an XML data.
  • In previous versions of the XML parser, Wordpress explicitly turned off entity loading for simplexml_load_string. This was because a vulnerability was discovered in this component back in 2014. So, they patched it but what is the issue?
  • With PHP8, the function libxml_disable_entity_loader was deprecated because the library by default does not parse entities. So, in versions of PHP 8+ the code is not ran.
  • However, the flags for the function specify LIBXML_NOENT which ENABLES the entity substitution! Damn, one would think that by using the default off version of the library that this bug would be fixed. It simply reintroduced the bug into the ecosystem.
  • This vulnerability is exploitable in several locations but all comes up to the bug above. This just goes to show that patching is just as hard as writing secure code in the first place. If I were participating in ZDI, I would just look at patches of old bugs and see if they were sufficient.

Netgear Nighhawk RCE- 469

@colorlight2019 - SSD    Reference →Posted 4 Years Ago
  • This router handles a lot of its functionality through a CGI interface. Because we fully control the HTTP request being made to the server and this is a C binary, it's time for memory corruption!
  • The vulnerability is in a memcpy based upon the Content-Length and the size of the file being uploaded. Because the size of the copy and the size of the buffer are controlled by the attacker, this creates a buffer overflow. This was the original bug here but it had a terrible patch.
  • The patch simply checks to see if the character before the Content-Length is a newline or not. By conforming to this, the original bug still exists but it makes exploitation a lot harder.
  • The exploit uses a fd overwrite (or fastbin dupping) in order to control the next location of the chunk from the heap of this requested size. However, malloc_consolidate is called with a later LARGE allocation (which destroys our bin). So, a way around this needed to be discovered.
  • On older versions of Malloc there is a negative indexing bug with chunks being freed. If a size of 0x8 is used, then the fastbinsY array index is set to -1 and overwrites another value in the malloc_state. What's this value? max_fast! This controls the consolidation is done at. Hurray!
  • So, the attack looks like this:
    1. Trigger heap overflow to create a fake heap chunk with a size of 0x8.
    2. When the fake chunk is freed, it will overwrite the max_fastvariable.
    3. Overwrite 'fd' pointer of a heap chunk.
    4. Allocate our fake chunk (with our controlled data) overwrite the a GOT entry with the PLT of system.
    5. Trigger the function with the overwritten GOT to pop a shell.
  • The article has a nice POC at the end of it as well! It is fun seeing real world heap exploitation of older versions of GLibC malloc.

Duo Two-factor Authentication Bypass- 468

Shaun Kammerling - Sensepost    Reference →Posted 4 Years Ago
  • The days of a single password being used are gone because of the single point of failure. With 2FA, TWO authentication points need to be compromised. Duo is a provider of the second factor of authentication. So, a bypass for this is quite impactful.
  • With Duo 2FA, a code must be requested by the application. When this request to the server is made is where the vulnerability lies at. By simply copying the content of the hacker request, as opposed to the user request, the payload was sent directly to hacker instead of the main user!
  • This first bypass allowed for the location of the data being sent to be changed! However, this required the attacker to have access to this Duo portal in order to work.
  • A second variant was found AFTER requesting the code. When the code had been requested, a transaction id was constantly pulled to see if this had gone through. By sending the transaction id with the other device, the backend could be tricked into accepting the attackers verification code.
  • This bugs were quite simple and just about anybody could have found these. It is amazing that these bugs stayed in the Duo ecosystem for so long without anybody realizing. According to the authors of the article, Duo was incredibly swift about fixing the vulns and was pleasant to work with.

Exploiting System Mechanic Driver- 467

Voidsec    Reference →Posted 4 Years Ago
  • The authors of this article recently took a course on Windows Exploitation at NULLCon and were out to prove they got something from it. The final challenge was a poorly built driver to exploit.
  • The driver takes a kernel pointer and writes a value to that location. This was found through dumb fuzzing within seconds. Clearly, pointers should not be passed directly to the kernel and write to.
  • The interesting thing is that the location is controllable but the value is not, making this a WRITE-WHERE primitive. By abusing this WRITE-WHERE primitive on the credential information (Present & Enabled) this gives the process complete privileges.

A Silly Anti-Disassembly Trick- 466

Alexander O'Mara    Reference →Posted 4 Years Ago
  • The author of this code attempting to review a binary in Hopper (the free version) but was unable to. Why is this?
  • Hopper attempts to detect itself, as if you could remove the license check then it would be super easy to run the binary for free. One of the ways the detection occurs is by looking for a particular string that denotes the owner of the company.
  • By adding this string into the binary, Hopper thought it was reversing itself! Haha, fun and silly trick to prevent some reverse engineering.

Bypassing macOS's file quarantine, gatekeeper, and notarization requirements- 465

Patrick Wardle    Reference →Posted 4 Years Ago
  • MacOS seriously attempts to validate that all applications are legitimate. This is done via checking for cryptographic signatures on the binaries, notarization (scan the application for potential issues), Gatekeeper (are you sure you want to launch this app?) and File Quarantining.
  • MacOS applications are bundled in a weird way. Each .app file actually has many sub-directories that have libraries, the binary and other assets. What is bare-bones application? All you need is a binary that matches the main folder in app_name/MacOS/app_name.
  • For some reason, this does not trigger any of the security checks above though!? The author stumbled upon this bug by simply trying to get a bare-bones app to work. The bulk of the article is about reversing this functionality on MacOS.
  • The bug is fairly simple: only bundled applications are validated. What makes up a bundled application? It must have an info.plist. Because of how simple this bug was, it was being exploited in the wild. Yikes!
  • Sometimes, bugs just fall out of thin air... Reformatting something in a way that violates the developer constraints but still works is where lots of bugs live at.

Big Bugs: Bitbucket Pipelines Kata Containers Build Container Escape- 464

Michael Hamel - Bugcrowd    Reference →Posted 4 Years Ago
  • The CI/CD pipeline for Bitbucket must be user isolated. If it's not, data can trivially be stolen or altered during the build process. This bug was an escape of the CI/CD pipelines.
  • First, a user must escape the Docker service. This was done using known techniques with CGroups release agent functionality. So, step one is complete.
  • The second step is the new/unique part of this article: escaping the kata VM. The kata VM is essentially Docker but with a few slight variations in functionality, such as guarantees of container isolation.
  • With Kata containers, the author started looking at the mounted file systems. An important thing to note is that the hostPath functionality was used in order to mount paths from the container host directly into the container. In order to make the lives of devs easier, one of the mounts was /user/bin/docker.
  • The mounting process for Kata was quite complicated with a bunch of nesting and other steps taken in between. Although the permissions from within the Kata VM appeared to be ReadOnly, the HOST disagreed with this! The HOST believed that the docker mount was rw.
  • Because the mount was actually writable, the Docker binary itself could be altered! Damn, that's code execution as soon as the binary is ran.
  • The author found an additional mounting issue on the Kubernetes pods version of this. The bug was in an improperly mounted log directory. By writing to this directory with a symbolic link, it was possible to redirect the location of the write in order to overwrite arbitrary files.
  • Overall, awesome bugs with interesting impacts! Containers are awesome in practice but are still complex beasts with bugs in them.

A Reference-Counting Bug in the Linux Kernel io_uring Subsystem - CVE-2021-20226- 463

Lucas Leong - ZDI    Reference →Posted 4 Years Ago
  • The Linux kernel introduced a new subsystem for batching I/O operation system calls within the kernel. This is where the vulnerability is at.
  • When passing around pointers all around the kernel, it is important to know where these pointers are being used at. Otherwise, an object may be freed that is still being used somewhere. In order to keep track of this, a strategy known as reference counting is used. This keeps track of the always of pointers referencing this object. When the object gets to zero, it is okay to free the pointer.
  • In the IORING_OP_CLOSE operation, the system call passes a files_struct to the kernel thread. However, the pointer does not increment the reference count! This creates a discrepancy between the amount of expected places using this pointer and the actual amount. This creates a use after free (UAF) vulnerability.
  • In order to exploit this, a complicated series of thread manipulation must be done because there is a small window in which this is actually exploitable. The general idea is to make a call to location that handles files_struct to get a reference. Then, concurrently, get the IORING_OP_CLOSE to quickly run and free the object. Now, the other location has a UAF on the object.
  • In terms of actual exploitation, the author found a good candidate for each of a read and write primitive with map_lookup_elem and map_update_elem respectively. This functionality can be used to free the file object, insert our user controlled data with pointers into this location then the copy_to_user() function is called, allowing for an arbitrary read primitive.
  • For the arbitrary write primitive, a similar flow can be used but with the map_update_elem function with the data being written coming from userland. This exploit method is restricted to a one-core env because of the code being hit though.
  • An additional interesting point in this exploit is about making the race window easy to hit. By setting up recvmsg in the kernel to block on a specific operation, the race window becomes more consistent to win.
  • Overall, reference counting is difficult to do! A single mistake on not adding a reference can lead to complete compromise. The discoverer of the bug made a post that goes into the exploitation.

Curl those funny IPv4 addresses- 462

Daniel Stenberg    Reference →Posted 4 Years Ago
  • This article is about the multitude of ways that Curl will accept IP addresses. This article is written by the maintainer of Curl!
  • When we think of IP addresses, we commonly think of four sets of decimal numbers (such as 192.168.1.1). However, the URL specification allows for MANY other formats.
  • Staying true to the 4 octets, the numbers can be written octal (base 8) with a leading 0 or hexadecimal (base 16) with a leading 0x. For instance, here are the 192.168.0.1 representations of these respectively: 0300.0250.0.01 and 0xc0.0xa8.0x00.0x01.
  • However, even the 4 octet format is not required. Numbers can be written in 1,2,3 or 4 octets. For instance, 3232235521 is 192.168.0.1 as a whole decimal number. Two numbers looks like 0xc0.052000001
  • These can even be mixed and matched, depending on the prefix. For instance, all three bases can be used in a single IP address: 0xc0.0250.1.
  • Parsing IP addresses is NO trivial task! Different bases, octet sizes... if you have an application that is potentially vulnerable to SSRF, try use different bases to hit the inside.