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!

Better 2FA Bug hunting Approach- 501

admiralarjun    Reference →Posted 4 Years Ago
  • Instead of having only a password, lots of sites have the option to use an additional way to validate the users identity. This is called multi-factor authentication. Being able to bypass an MFA is part of the process to account compromise. This small article has a list of MFA test cases.
  • The first (obvious) issue is is lack of rate limiting. A few interesting attacks here:
    • Brute forcing the OTP with an unlimited amount of requests.
    • Creating an unlimited amount of OTP codes where the previous ones do not expire.
    • Bypassing the rate limiting, depending on the restriction.
  • Besides the obvious attacks, there can be issues with the logic.
    • The OTP's can be reused. Reused from different actions, or reused from other users.
    • Old OTP tokens
    • Client side validation only.
    • OTP is leaked in headers or error messages.
  • There are some other interesting session management handling issues as well.
    • 2FA does not need to be used to disable 2FA. Interesting attack!
    • No 2FA on sensitive actions such as password resets, resetting a password or something else.
    • Different APIs on web and mobile.
  • Overall, there are some interesting test cases in here to consider. Coming up with ideas for this is complicated to do!

Hacking eInk Price Tags- 500

Dmitry Grinberg    Reference →Posted 4 Years Ago
  • eInk price tags are ESL (Electronic Shelving Labels) that allow for stores to dynamically change the prices as they see fit without placing a new paper on the shelf. Most ESLs are updated wirelessly and use a custom protocol to communicate.
  • When tearing open the device, Dmitry found a Marvell chip that angered him because of the lack of documentation. The only thing that he could find was that this used an Cortex-M3 processor 512K of Flash, 160K of RAM and it speaks Zigbee (an IoT protocol).
  • Cortex-M chips are debugged using an interface called SWD (single wire debugging). SWD only has two pins: one for data and one for the clock. After trying a large combination of pins, his CortexProg tool came up with a connection on pins 22 and 23! Sometimes, blind guessing works out for ya.
  • For whatever reason, the Marvell chip does NOT have any protections against reading out the ROM off of the chip. So, using the tool mentioned above, it was trivial to read 128K of ROM, set breakpoints and do anything a developer would want to do! The Flash was divided into a Bootloader, binary data, peripheral drivers and a Zigbee stack.
  • The REAL firmware was not in the ROM though: it was coming from RAM! The bootloader was using commands to directly interface with an internal QSPI bus. By writing a program to talk to the bootloader directly, it was possible to dump out the real firmware of the program. Even though they attempted to password protect this, they failed miserably with a default going to 0xFFFFFFFFF.
  • The protocol works over the 2.4GHz band using QPSK moduation at 250Kbps with a 5MHz channel spacing. After struggling to find a tool that supported QPSK modulation, he found a tool to speak raw 802.15.4 to interact with the device. Finally, to run custom code on the device, they took the bootloader and patched on his own code with linker magic.
  • A large portion of this article is about the display of the reader, which is not something I cared to take notes for. Dmitry creates his own firmware for the device with a bunch of interesting twists though. Dmitry picks up another one of these devices for fun though: the Chroma 74.
  • When the device turned on, virtually nothing happened. However, when connecting to the chip it had not been code locked! This allowed for reprogramming and firmware downloading in an easy fashion.
  • Overall, another interesting reverse engineering article from Dmitry.

nRF52 Debug Resurrection (APPROTECT Bypass) Part 2- 499

LimitedResults    Reference →Posted 4 Years Ago
  • In Part 1 of this, the author discusses a vulnerability to turn on Debug mode. In Part 2, they exploit a real device. The Logitech G Pro is a computer mouse that uses the nRF52 chip, which is what they choose a target.
  • The computer mouse had JTag and SWD modes disabled. This was dynamically tested on the chip. So, this was a perfect item to target!
  • Decoupling capacitors C5 and C15 are removed and the glitch output is connected to VDD_CPU (DEC1). Then, a The CPU is connected to a glitcher, which attempts the voltage glitching attack.
  • The fault injection is a Python script that is connected to an oscilloscope. After a specific time delay, a fault is injected (lower or raise the voltage) in order to skip over an instruction. This will HOPEFULLY cause the debug mode to never be turned off, resulting in a debug shell!
  • Once the debug mode is set up, Opencd via Telnet is used in order to dump the firmware of the computer mouse. With the firmware in hand, we can reflash the firmware with any modifications that we want! In particular, we can turn on the debug mode once again.
  • Overall, this is an incredibly bad vulnerability to find. This can be used to dump the firmware on all devices that use these chips. Unlike software, hardware mistakes are usually impossible to fix.

A Wormable Code Execution Bug in HTTP.sys- 498

Kc Udonsi & Yazhi Wang - ZDI    Reference →Posted 4 Years Ago
  • IIS for Windows server is a web server for hosting web content in both static and dynamic forms. This web server has a HTTP listener as part of the networking subsystem that is implemented in HTTP.sys. Finding a vulnerability in a web server allows millions of sites to be compromised in one go.
  • The Accept-Encoding headers dictates which content-coding can be sent back to the client such as gzip, * or deflate. This can be in the form of a list as well. An example with a list looks like Accept-Encoding: deflate, gzip;q=1.0, *;q=0.5.
  • While parsing the string above, there are three states: supported, unknown and invalid. “gzip” is a supported content-coding string, “aaaa” is an unknown content-coding string, and finally “bbbb;” is an invalid content-coding string because it is improperly formatted.
  • The maintaining of this bookkeeping is done using a circular doubly linked list for all unknown content-codings. The vulnerability exists in the handling of the doubly linked list.
  • Initially, a root node is created for handling the unknown content-codings. After sending this information off in the response, there is a routine that unlinks and frees the nodes from the linked list. It starts with the first non-root node and does a multitude of sanity checks.
  • Once all of the content-codings have been parsed, if the list contains any unknown types, then they are unlinked from the root node that resides in the functions stack memory and relinked to a root node structure.
  • Here is where the vulnerability occurs at: the next and previous links of the original root node are STILL connected to the migrated nodes. By crafting a special HTTP Accept-Encoding header with a comma (,) a path can be taken that will migrate some but not all of the nodes.
  • With the root node being incorrect on one of the locations, it can still be used to access the migrated nodes! This can be used to free these pointers, even though they are the wrong ones to be freed. This results in a use after free (UAF) that is exploitable by a remote attacker.
  • This is an interesting bug! Like lots of heap vulnerabilities, it is just bad bookkeeping of pointers. By simply having the wrong pointers in one place, it creates an exploitable scenario.

Security probe of Qualcomm MSM data services- 497

Slava Makkaveev - Checkpoint    Reference →Posted 4 Years Ago
  • Mobile Station Modem (MSM) is a series of different SoCs made by Qualcomm. This is the part of the phone that decoders SMS and radio messages, making it an interesting target for attackers. Besides the remote interface, there is an interface on the device that can talk to the chip as well: the Qualcomm MSM Interface (QMI).
  • The MSM is managed by a Qualcomm real-time OS (QuRT) that is not possible to dump, even on a rooted device. QuRT is managed by TrustZone as well. In order to have access to the OS, a vulnerability needs to be found in the QTEE or the Linux kernel. The purpose of this paper is attacking the MSM data service to patch QuRT on newer SoCs.
  • QMI communication is a client-server model in the QMI wire format. QMI ports are exposed to the Linux-running application CPU core inside the chip. QMI offers support for a multitude of services, such as the wireless data service (WDS), Device Management Service (DMS) and about 40 more. OEMs also add their own services to the chip as well.
  • To know where to fuzz, they found the IPC handlers and reversed the structures to know HOW to call them. They used QEMU in order to emulate the modem to find the vulnerability. This feedback based fuzzing (very little instrumentation).
  • After throwing random inputs to the service for a while, AFL found a heap overflow in the voice service. This vulnerability is simply a lack of bounds checking on the amount of fields are allowed to be used, which results in the linear heap overflow.
  • Overall, the vulnerability hunting of this interface was not the hard part: the setup was. By creating a realistic way to test this interface, it become much easier to find the vulnerability in the blackbox setting. The authors believe this vulnerability could have been used to dynamically patch the application processor and the modem itself.

IBM Spectrum Protect: Exploiting Legacy Authentication Protocol- 496

Critical Security    Reference →Posted 4 Years Ago
  • IBM Spectrum Protect is a backup solution that provides data protection. It has a client-server architecture style with different types of nodes involved. The authentication protocol has a vulnerability in it though.
  • Here are the steps for the protocol:
    1. The client generates session and validation tokens. This information is encrypted using the hardcoded AES key and sent to the server.
    2. The server selects the password of the connecting user from the database and encrypts it using the same hardcoded key. In this step, the clients information is also decrypted using the encrypted password as the key.
    3. The sever generates its own validation token. The server encrypts the clients validation token and its own token suing the decrypted session token.
    4. The information above is sent back to the client where the client decrypts the validation tokens using the session token.
    5. Once the token is known (from the decryption process), the validation token is sent back to the server.
    6. The server validates the two tokens are the same. This is done in order to verify that the client actually knows the session token.
  • The authentication method above uses a challenge-response format in order to verify if the user has the proper secret. If they have the proper secret, then they can access the server. So, what if we could brute force the secret somehow?
  • Prior to the server sending back the the challenge, it encrypts the data using the session token. Because we know part of the ciphertext (validation token from client), we have a known ciphertext problem!
  • With the known ciphertext, the session token from the server side can be brute forced offline until we get the expected plaintext! This allows us to authenticate, even though we never knew the secrets.
  • Although this requires the brute forcing of a key, it can be used to find the password on the server. Considering this is JUST a password (and not an AES key), this seems doable after a fair amount of tries.
  • Besides the vulnerability itself, the situation for this is interesting. This is the old protocol, which has been deprecated for security reasons. However, this legacy authentication method is still enabled by default on newly created administrators. So, even though this is deprecated, it is still possible to use!
  • Overall, this is a fun vulnerability in the authentication flow of an application. The sending back of user data does not feel like a big deal until you realize that the password used to encrypt this data can be learned with offline brute forcing. Great find!

That Single GraphQL Issue That You Keep Missing- 495

doyensec    Reference →Posted 4 Years Ago
  • The CSRF attack vector is starting to disappear with the addition of the Same-Site cookie flag. However, there are still many situations that assumed to be secure endpoints can be manipulated to do something malicious. GraphQL is an up-in-coming technology for querying information meant to replace REST endpoints.
  • GraphQL uses JSON based endpoints. JSON requires a pre-flight request, which means that it is NOT vulnerable to CSRF unless something weird is happening on the back-end. So, the first trick is changing the content-type to be a form-urlencoded encoded in order to bypass this protection.
  • Secondly, if the endpoint has any mutations via GET requests, this is an automatic vulnerability. Most frameworks will not validate CSRF tokens on GET requests. So, this now becomes a really easy target to hit. These are standard CSRF test cases but it interesting to hear them be called out on GraphQL in particular.
  • The final thing to look out for is Cross-Site Search (XSSearch). The idea is that a malicious user does not have access to some piece of information BUT the victim user does. By launching GET requests to search for some information, a timing difference can used in order to figure out if the data is valid or not. It should be noted that the return of the request gets blocked because of the same-site policy.
  • Overall, these are good callouts and I finally have a better understanding of a realistic scenario for XSSearch.

Attack llvmpipe Graphics Driver from Chromium- 494

Jan Ruge - Insinuator    Reference →Posted 4 Years Ago
  • This blog post is a bug in the Mesas llvmpipe Gallium3D graphics driver which was accessible via Chromium's WebGL. This driver is used to simulate GPU processing when the hardware is not available.
  • LLVMPipe is a software rasterizer that uses LLVM to compile the shader code to run on a CPU. The vulnerability is in the compilation process of shader code.
  • The vulnerability is in that the size of arrays is not validated within the shader code. When this is created, it is added to the stack as a variable length array (VLA).
  • Because there is no length check on the length of the array, the VLA can be mapped outside of the current stack mapping. This causes a crash because a guard page is hit within Chromium though. Can we do anything else with this?
  • Chromium has an additional exploit mitigation: all of the allocations are zeroed out before being used in order to prevent uninitialized memory leaks. Although, this causes issues because we don't want to write over the top of unmapped memory.
  • In order to prevent the initialization of zeros from happening, an always failing if statement can be used. In order to hop over the Guard Pages, we need to allocate a significant amount of memory in other locations.
  • By carefully fine-tuning the offsets for the VLAs, partial control over the RIP on the stack can be controlled. Eventually, with a few tricks for handling AVX instructions, the full RIP could be controlled!
  • To pop a full shell, this vulnerability would need to be chained with a memory leak. Additionally, the GPU runs in a sandbox which would require an additional vulnerability to break out.
  • This is an interesting vulnerability! This is the second VLA issue that I have seen in the last while; bounds checking on the high end needs to be taken seriously on stack memory in order to avoid these subtle issues.

How I Hacked Google App Engine: Anatomy of a Java Bytecode Exploit- 493

polybdenum    Reference →Posted 4 Years Ago
  • Java App Engine allowed arbitrary Java to be ran within the context of the sandbox. In order to make this usable to developers but still secure, there is a substantial amount of static and dynamic analysis that eventually leads to bytecode rewrites.
  • Rewriting Java byetcode!? How could this possibility be done securely in order to protect against all possible privilege escalation methods.
  • When rewriting the bytecode, it is based through ASM for an in-memory serialized representation of it. This means that a parsing difference between ASM and the JVM can allow for bytecode transformations to bypass the security checks.
  • The first vulnerability is in a difference between Java classfile opcodes. In a ClassFile, older versions used a bytecode of 1,1 and 2 bytes to represent the Code attribute. In newer versions, this is 2, 2, and 4 bytes in size.
  • By carefully crafting a file, the Classfile can be parsed valid as an older version (with smaller sizes) and the newer version with larger sizes. Using this bug, it would be possible to change interpretation of the bytecode if App Engine didn't have a minimum version of 49.0.
  • When Java bytecode needs to reference a string, the string data is stored as a two byte length field, followed by that many bytes of string data. ASM does not check for integer overflows on this size though. This means that a string of a very large size would be seen as 0 size by the JVM and the rest of the string would be interpreted as the bytecode.
  • However, it is impossible to create a string large enough to cause this overflow. So, another way to trigger the parsing error needs to be found.
  • The strings within ASM are parsed with the MUTF-8 encoding while Java uses UTF-8. The main difference is that NULL bytes are stored as a two byte sequence within MUTF-8.
  • The vulnerability occurs where ASM will allow for the input to be in the MUTF-8 format and the UTF-8 format. This slight difference between ASM and the JVM can be used to trick the length of a string to trigger the overflow bug above.
  • The exploit involves using the integer overflow in order to create valid bytecode. Obviously, handwriting bytecode is a tedious and annoying part of this exploit though. The rest of the article dives into how the bytecode was created in order to launch this full exploit.
  • In order to remediate this vulnerability, App Engine changed the flow to run the ASM again in order to check for discrepancies. By doing this, an entire class of exploits was removed.
  • This is an insanely long post but I appreciate the thoroughness of the post. Differences in parsers will always be an issue with security.

NoSQL Injections in Rocket.Chat - 492

Paul Gereste - Sonar Source    Reference →Posted 4 Years Ago
  • Rocket.Chat is an open source chat platform for team communication (like Slack). Both of these vulnerabilities are NoSQL injections in MongoDB that have a devastating impact on the application.
  • NoSQL queries are typically JSON objects that are based to the query object. Because of this, if the user input is simply added to this object with type validation, the meaning of the query can be changed (similar to SQLi). For example, the operator {"$ne":1} would force the query to always return true instead of being a normal input.
  • The first NoSQLi is in the validation of password policies. The bodies token does not have its type validated but is added directly into the query. Hence, NoSQLi operators can be injected into this in a blind fashion.
  • To do something meaningful with this, we need to create a blind oracle, such as a timing change or something else. In this case, the regex operator can be used to character by character to steal a users password reset. This is a horrible vulnerability that allows complete compromise of any non-2FA account.
  • The second vulnerability is in the users.list function. This function takes a parameter that is used for the users collection information. Because not all fields in the collection should not be accessible by everyone, there is a denylist of items.
  • This denylist of items does not consider the usage of MongoDB operators though! So, we have the ability to add an arbitrary operator into the query being used. The regex way would work just fine but there's a better way.
  • The $where operator can take JavaScript expressions for more complicated queries but only within the context of the MongoDB instance. By triggering an error message within the query via the JavaScript in the $where clause, the response could contain secrets inside of it!
  • This attack allows for the leakage of a controlled field! Using this, at the admin password hash and 2FA secret could be leak. Game over!
  • Once the admin user is compromised, it is even possible to pop a shell on the system. This is done by adding incoming and outgoing webhooks via the Integrations, code execution is trivial to get on the host machine. So, this is kind of code execution by design.
  • At this point, the attacker is trapped within the Node vm module which is apparently not made for security. To escape the VM context, the attacker has to get access to objects from the parent context. By referencing parameters given by the parent, a simple 3 lines of JavaScript gives access to the host machine.
  • Input validation is incredibly important for stopping simple attacks like this. Checking for types and values can drastically reduce the exploitability of an application.