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!

Remote Code Execution with XMPP Stanza Smuggling in Zoom- 851

ifratric - Project Zero (P0)     Reference →Posted 3 Years Ago
  • XMPP is a messaging protocol based on XML. This is based upon short snippets of XML called stanzas. These messages are sent over the same stream connection as control messages to the server. XMPP allows the client to have full control of data within the <body> tag, including their false XML snippets.
  • If a user could escape this XML, to get into the control section of the message, they could add arbitrary stanzas into the data. The author dubbed this attack XMPP Stanza Smuggling. Since there are two points of parsing: server and client, the difference between these could cause problems. This is where the author searched for vulnerabilities at.
  • Between the server-side (Expat) and client-side (Gloox), there are two XML parsers: gloox and fast_xml (Expat). Both of these support UTF-8 but handle it differently. Expat is fully UTF-8 aware and handles errors appropriately. Gloox has only a minor effort to detect invalid characters, since it does the parsing character by character.
  • One the server-side, it will send aa\xeb><aa;. The \xeb designates a unicode character is being used, since this denotes the 3-byte prefix for UTF-8. Once Expat receives this, it does not check that the next two characters in the sequence at valid - it adds them to the XML tag as is by creating <aa\xeb><aa/> from our input.
  • Once Gloox receives the data, it will NOT see 0eB as the start of the 3-byte sequence. Instead, it is just another character in the tag name. It will read the data as two tags: <aa\xeb> and <aa/>. Neat! We have smuggled in a closing tag to the client.
  • As a result, the author believes it is possible to escape the <message> tag. To exploit this, they used a quirk within Gloox: smuggle in the tag <?xml ?> in order to completely reset the state of the parser, making our node the new root node. This is only possible because of the UTF-8 encoding bug talked about before. As, otherwise, it would remove the <?xml ?> data.
  • With the smuggling bug in the XML stanzas, how do we actually exploit this? Of course, we can know spoof users and control things that we normally cannot control. However, we can do better! Using the <stream:error> tag, we can specify all of the servers that the device be using, since we can control the endpoint this goes to. This effectively man in the middles the entire connection!
  • With the man in the middle position, we can exploit the update process to get code execution. This was done by first downgrading the Zoom client to an older version (that is still signed) then exploiting an unverified .cab file, which contains installation data. The replaced .cab file will NOT call Zoom as it should. Instead, it can call an arbitrary file, such as cmd.exe.
  • After posting this, the author found an additional smuggling bug unrelated to the previous finding. When the server uses Expat, it creates a parser with a newline as the delimiter between the namespace URI and the local part of the name. Since we can add arbitrary data into this (including newlines), we can confuse the two modes.
  • Since the parser believes we have added a delimiter (when we really haven't), we can smuggle in arbitrary XML tags. This leads to the same XML stanza smuggling bug as before. This was simply done by adding a newline!
  • Overall, I love this report because of the parsing differences between two XML parsers. Even without memory corruption, Zoom can still be compromised. I also enjoyed the downgrade attack, proving that cryptographic signatures are not enough (no wonder Apple limits versions on iOS).

2nd RCE and XSS in Apache Struts 2.5.0 - 2.5.29- 850

mc0wn    Reference →Posted 3 Years Ago
  • OGNL (Object Graph Navigation Library) is an expression language used for getting and setting properties of Java Objects. This is used by a plethora of big products, such as Apache Struts.
  • OGNL evaluations are exploitable when OGNL code is evaluated twice. According to the author, this is often done when the findString() or findValue() function is called consecutively inside an object with nested calls. While reading on previous work, the author noticed that special Apache strut files called ftl (FreeMarker) files can also have OGNL expressions.
  • ftl (FreeMarker) files are used to define how an element will present itself in the final HTML code. Within a ftl file there was a call to findString() on a user controlled parameter. Then, later on, the function getText() is called, which has a nested call to findValue().
  • The code for the call is stack.findValue("getText('" + text + "')");, where text is user controllable data. getText() appears to have limited functionality for getting code execution. But, because we have a string concatenation on a dynamic query language, we can escape the original call and make our own call. This is similar to SQL injection in that way.
  • The payload text = a') + #application + getText('b will result in us escaping the getText() function to allow arbitrary queries to be ran. Using this, a payload to achieve code execution can be made but is too long to put into this resource. The article has a good example of this though.
  • The author found a minor XSS issue on the onChange event. This required user interaction in order to exploit though. Overall, I really enjoyed the double OGNL bug leading to code execution in Struts. It is interesting to see a query language that I'm unfamiliar with get exploited in a way similar to SQL injection.

This is how they do it!- 849

Flamingo-Tech    Reference →Posted 3 Years Ago
  • The author of this posts does not like DRM put onto filters. So, he wanted to be able to create his own filters and save the world from waste.
  • The Xiaomi filter relies upon a password for communication between the filter and purifier. This communication is done via NFC. The reverse engineering of this is shown at xiaomi-air-purifier-reverse-engineering.
  • The generation for the passcode is based upon the UUID (because it's unique) of each filter. Some mystery gentleman sent the author of the blog a code snippet that generates the keys. It uses selective bytes from SHA1 of the uid in order to do so. The author does not go into how they figured this out though.
  • The code for this is shown below:
    import sys
    import hashlib
    
    # Usage: pwd.py 04A03CAA1E7080
    def getpwd(uid):
        uid = bytearray.fromhex(uid)
        h = bytearray.fromhex(hashlib.sha1(uid).hexdigest())
        pwd = ""
        pwd += "%02X" % h[h[0] % 20]
        pwd += "%02X" % h[(h[0]+5) % 20]
        pwd += "%02X" % h[(h[0]+13) % 20]
        pwd += "%02X" % h[(h[0]+17) % 20]
        return pwd
    
    assert getpwd("04A03CAA1E7080") == "CD91AFCC"
    assert getpwd("04112233445566") == "EC9805C8"
    print("PWD:", getpwd(sys.argv[1]))
    

Remote kernel heap overflow- 848

m00nbsd - HackerOne    Reference →Posted 3 Years Ago
  • Point-to-Point Protocol Over Ethernet (PPPoE) is a network protocol for communication between network endpoints. This is included on the Playstation, which is where this was reported at.
  • The vulnerability is fairly straight forward: a statically allocated buffer (2048 in size) can be appended with more data than this. When processing a PADI packet, it copies in data into this buffer, with a size less than 2048.
  • However, by tagging this correctly, two packets will be combined into a larger packet. When these packets are combined, it creates a buffer larger than 2048. From their experiments, the largest possible overwrite is 2800 bytes, which is quite the overflow!
  • From the authors understanding, this originates from buggy code in BSD. To run this exploit, turning on Ethernet is required. Then, after connecting to a laptop, reconfiguring the device with the malicious payload will trigger the buffer overflow.
  • Overall, great bug but I wish there was more insight into how they found it and if this was exploitable or not. Even though these appear to be non-default settings, they were awarded 10K.

F5 iControl REST Endpoint Authentication Bypass Technical Deep Dive- 847

James Horseman - horizon3.ai    Reference →Posted 3 Years Ago
  • F5 recently patched a critical vulnerability in their BIG-IP series. The blog post is a technical dive that starts from a payload to identify the vulnerability. This is shown below:
    POST /mgmt/tm/util/bash HTTP/1.1
    Host: 127.0.0.1
    Authorization: Basic YWRtaW46aG9yaXpvbjM=
    X-F5-Auth-Token: asdf
    User-Agent: curl/7.82.0
    Connection: X-F5-Auth-Token
    Accept: */*
    Content-Length: 39
    {“command”:”run”,”utilCmdArgs”:”-c id”}
    
  • The service is a Java application running on localhost, which is exposed by Apache. The vulnerability exists because of a difference in understanding between the reverse proxy (which the code is in mod_auth_pam.so) and the service itself.
  • The module mod_auth_pam.so would perform authentication checks in most cases with the Authorization header. However, if the X-F5-Auth-Token was used, it was the job of the downstream service to verify it. If the flow got into the downstream service without the X-F5-Auth-Token token, it was assumed that the auth had already passed.
  • This seems to be failing open at the downstream service. Is it possible to drop the header X-F5-Auth-Token prior to getting the downstream service by after the initial verification?
  • By using the Connection header to drop the X-F5-Auth-Token (hop to hop header), this will do the trick! The dropping of headers was done AFTER the verification step for auth mentioned above in the library prior to the downstream service. Wow!
  • Overall, an amazing vulnerability that led to a lot of pain and suffering for people. Any times things are failing open, there is likely a leak in there they can be exploited. Don't do it kids!

VMware Authentication Bypass Vulnerability (CVE-2022-22972) Technical Deep Dive- 846

James Horseman - horizon3.ai    Reference →Posted 3 Years Ago
  • VMware recently patched a critical authentication bypass vulnerability in their VMware Workspace ONE Access, Identity Manager and vRealize Automation products. This bug could have been used to log in as any user on the site.
  • This vulnerability comes down to improper trust of the Host Header. From the browser, an attacker cannot control it. However, from cURL or another manual requests, it is trivial to control this.
  • The Host header is used to make a request to validate users. Since this header is controlled by an attacker, we can control WHERE the user is authenticated from. By standing up a malicious server, we can simply say yes to every authentication attempt. Lolz.
  • Overall, the article is okay. There is no in-depth discussion on the bug; only a patch diff and an exploit writing. Fun to see an exploit work on a live box though!

Virtualizing a Fan Controller with GNU Radio- 845

Grant Hernandez     Reference →Posted 3 Years Ago
  • The author has a fan that they wanted to reverse engineer the signal. Since they have fancy SDR equipment, this was a task they could take on. They use PyBOMBS, which is a package manager specifically for GNU Radio and related tools; this runs similar to virtualenv for Python, which is awesome.
  • Simply capturing and replaying the signal is easy. From looking at this in GQRX, you can clearly see it is a form of Amplitude Shift Keying. The author wrote a script in Gnu Radio Companion (GRC) to read in the file, make it louder then send it off. This did not have any rolling code or anything fancy in it.
  • They reviewed the signal in Inspectrum, a spectrum analyzer, to decode the data by hand. From this view, they found out that On-Off Keying (OOK) was being used.
  • Sending the data via OOK only requires a basic understanding of GNU radio. the block diagram is quite small but the baud rate is the important thing of note. Additionally, they use a vector source (just an array of values) for the OOK signal. Finally, the sample rate is derived from the baud rate as well.
  • Demodulating is a totally different story, in terms of complexity. The first magic block is Symbol Sync. This is used to do a timing recovery on the incoming signal since we do not know when a valid pulse begins or ends. The parameters feel like black magic to the author and myself.
  • Next, Grant converts the complex number into a float with an increased magnitude. Finally, they use a binary slicer block to create a stream of unsigned chars to be used for later processing. Prior to the binary slicer, the value is subtracted from, which I assume is for the binary slicer.
  • Now, having the data with valid 0s and 1s is not enough. How do we know if a string of inputs is valid or not? For this, the author grabbed on out of tree module to do some more heavy lifting. Essentially, the Sync and Create PDU block does a pattern match for a particular bit sequence. If this is found, then the byte stream is passed through to the final block.
  • The PDU part is counter-intuitive in GNU Radio. Most of the time, data is seen bit by bit. In this case, we only want a block though. The final block is custom written by the author, which is a small script that takes in the raw 0s and 1s then converts them further to his understanding. 100 is actually 0 and 110 is actually 1.
  • At this point, Grant can easily decode data on the fly. Now, it is super easy to reverse engineer the signal itself. With two remotes, he found that the first section was a remote ID, a separator then a command. These appeared to be quite redundant, in terms of the amount of bits used. They have further notes at Github.
  • Overall, a really awesmoe post with plenty of great diagrams and explanations for what was going on. I have always found GNU Radio hard to use; so, this breakdown made my life a bunch easier.

CVE-2022-27666: Exploit esp6 modules in Linux kernel- 844

etenal    Reference →Posted 3 Years Ago
  • The vulnerability exists in the esp6 crypto module. When receiving a buffer, there is an allocation that is 8 pages wide. The input, from the user, is written recurisively to this page without restriction on the size. Buffer overflow!
  • The overflow is quite a powerful primitive. Upon initial analysis, they noticed that the final several bytes (tail bytes) were not controllable. This was the only restriction though. The weird thing is that the overflow is at the page level instead of the heap allocator level. Page-level fengshui is a little weird!
  • The page allocator (buddy allocator) manages physical pages in the Linux kernel. This is what manages the SLUB, SLAB and other heap allocators in the kernel. The allocator maintains free pages in a data structure called free_area; this is just an array of elements that keeps track of the sizes of pages. Order-1, Order-2 - all pages to the power of 2.
  • If there there are no freed pages in the list, then it borrows them from a higher order. To shape the heap properly for the OOB write, they forced the complete usage of a single order. Then, when a higher order is used we KNOW the data will be continuous. To mitigate the noise from a kernel daemon, they found a weird pattern that worked 90ish percent of the time.
  • To get an arbitrary read primitive, the object user_key_payload was used. This field had a length value, making it perfect for an out of bounds read primitive. The tail corruption constraint worked with this object as well. This object had a hard cap on the amount that could be created. As a result, the feng shui had to be very calculated.
  • Once they have the OOB read, they decide to leak out data from the struct msg_msg. Since this has pointers, it is nice for breaking KASLR. Additionally, they use this leak to corrupt the msg_msg->next pointer and the length value of this structure to get a more powerful OOB read.
  • Once we have the leak, then we can ues our corruption to overwrite arbitrary data. Again, msg_msg is the object of choice. This is done by forcing a pause on a copy from userland to kernel then overwriting msg_msg->next with our overflow. Once the copy into our structure happens, we can write the data to arbitrary memory.
  • With the aribrary write, the authors overwrite the PATH of mobprobe, which is used to load userspace kernel modules. Their driver simply adds the setuid bit to bash to become root. Easy!
  • The bug is fairly simple. But, they had to learn all about the page level allocator and find unique objects to make this work because of the constraints in play. Overall, a great write up with awesome diagrams. It's sad this was found prior to their pwn2own entry.

When “secure” isn’t secure at all- 843

Martin Smolár - WeLiveSecurity    Reference →Posted 3 Years Ago
  • UEFI is the modern boot manager used on a plethora of devices. UEFI has a few different concepts for implementations:
    • Boot and Runtime Services. Application and driver initial entry points. Include the installation of protocols, memory allocation and more.
    • Variables: Store various configuration data; they are made up of a name, GUID and a value. These can have attributes for read and write permissions.
  • The System Management Mode (SMM) is a highly privileged mode of execution, commonly called ring -2. It is used for power management, special OEM code and secure firmware updates. It has hardware protected memory called SMRAM. To enter this mode, a special SMI interrupt is called.
  • How is SMM interrupt handlers and secure boot protections protected? Two main things:
    • BIOS Control Registers. Whether the BIOS space can be written to or not.
    • Protected Range Registers (PR0-PR4). Used for thigns such as allows SPI flash writes, SMM code configurations and other things.
  • The vulnerabilities in the post are simple in concept but deep into the secure boot rabbit hole. The first and second bugs are access control problems. By setting UEFI variables with specific values, security features can be entirely disabled on boot. For instance, the driver SecureBackDoorPeim will check for the variable name cE! to be set, bypassing all checks. Yikes!
  • The final vulnerability was an SMM issue. SMI interrupts have specific function handlers being used. So, of course, these must be secure when taking input from a user. One of the handlers has a built in read/write primitive. By abusing this, the entire contents of the SMRAM can be read/written or SPI flash can be written to.
  • Overall, this write up was quite thorough with the description of the bugs, how they were found and the background on these issues. The bugs themselves were quite simple but I loved the context behind the bugs.

FIRMWIRE: Transparent Dynamic Analysis for Cellular Baseband Firmware- 842

Grant Hernandez, Marius Muench & Dominik Maier    Reference →Posted 3 Years Ago
  • There are a seemingly endless amount of cellular protocols and specifications. How do our phones handle this? The baseband controller chip. Since these chips are closed source and are insanely complicated, security research on these is difficult.
  • The authors of this paper (who presented at CanSecWest as well), built an emulation platform for Baseband controllers called FirmWire. They wanted to be able to fuzz and statically analyze these platforms with a debugging environment.
  • The custom items for each vendor are how the program is loaded into memory (loader), peripherals and hooks to interface with the device. At the heart of it, is QEMU though. Besides the emulation, they created hooking and many great debugging plugins.
  • For the vendors, they chose to implement Samsung and MediaTek. Unfortunately, the biggest player Qualcomm has a proprietary architecture without QEMU support. They had to manually reverse engineering both images in order to understand how it worked, before the emulation was possible.
  • The images are Real Time Operating System (RTOS). Unlike regular operating systems, these are based upon launched tasks. So, to build a fuzzing harness, it is all about calling these tasks correctly from Python. The fuzzing is coverage based but must rely on black-box instrumentation.
  • Initially, they decided to fuzz three components: LTE Radio Resource Control (RRC), GSM Session Management (SM) and GSM Call Control (CC). They ended up finding 7 unique vulnerabilities this way.
  • Four vulnerabilities were found in RRC. The first one is in the parsing of data pre-auth. The parsing calculates an invalid length for a buffer on the stack, leading to a buffer overflow that can overflow the instruction pointer. This vulnerability existed in the reencoding, which demonstrates why full emulation allows for better bugs to be found. Two other similar re-encoding bug was found on the heap, which crashes since the boundaries have a static canary of (0xAA).
  • A double free was found in MediaTek's baseband image for RRC. This occurs when something is freed, an error path is taken, leading to a double free. This is dedicated by the heap allocator itself, which is cool.
  • In CC, they found a buffer overflow from an unsafe memcpy. The OTA length field is trusted, even though the size should never be larger than 16 bytes. The final bug is caused from an error case still attempts to decode data, resulting in a buffer overflow on the stack.
  • They eventually reproduced the vulnerabilities over the air using a USRP software defined radio. From talking to them at the conference, sending the bad bytes was the easy part of it. But, setting up a fake base station to connect to the phone is the complicated part. Overall, real amazing research!