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!

USB Over Ethernet | Multiple Vulnerabilities in AWS and Other Major Cloud Services- 709

Kasif Dekel - Sentinel One    Reference →Posted 4 Years Ago
  • Amazon WorkSpaces is a fully managed and persistent desktop virtualization service that enables users to access data, applications, and resources they need anywhere from any supported device. Session information is handled via HTTPs but the stream is handled via PCoIP or WSP (Workspaces Streaming Protocol. WSP uses many third party libraries in order to make the virtual PC feel like it is more physical than it really is, such as USB over Ethernet by Eltima SDK.
  • USB redirection is done by the Eltima SDK. The Kernel IO Manager (IOMgr) controls the flow of the information between kernel and user mode. When a user-mode request is sent via a IRP_MJ_DEVICE_CONTROL packet, the input and output data depend on the IOCTL code that is invoked. The CONTROL CODE is a 32-bit value with several fields, including the field TransferType.
  • This field indicates how the NtDeviceIoControlFile syscall will return data. There are three different modes for this: METHOD_BUFFERED, METHOD_IN/OUT_DIRECT and METHOD_NEITHER. The first one will copy the caller input data into the user provided buffer. The second version will supply an memory descriptor list (MDL) and ensures that our thread has access to this information. The final one takes in a user-mode address and reads/writes into this with no validation. Of course, the driver uses the insecure METHOD_NEITHER
  • METHOD_NEITHER by itself is NOT secure. However, the IOCTL handler is responsible for validating, probing, locking and mapping the buffer, depending on the use case. Since this is the case, double fetches, TOCTOUs, bad pointer dereferences and other vulnerabilities may be possible to exploit. Although this is not a vulnerability by itself, it is a code smell that should be checked out.
  • While reviewing the code handling for these IOCTLs, the author noticed that the size parameter given by the user request was blindly being trusted. Later on, this size was used with a multiplication operation which could easily be overflowed. Additionally, the copy operation was not verified to be smaller than the allocation!
  • The proof of concept has an allocation size and a copy size. To exploit this, they set the allocation size to be smaller than the copy operation size. Then, when a copy operation happens, a trivial buffer overflow happens with the user controlled write value. Since the data and size are both controlled, this leads to a highly exploitable vulnerability.
  • An additional point of concern is that the IOCTL does not have any ACL enforcement turned on. This means that the vulnerability can be triggered via several different mediums, such as the browser (if they didn't do their own filtering).
  • In the disclosure timeline everything seems fairly normal except the vendor that created the library. They claimed to have known about the bug but said that it was not possible to hit the code path because the feature was turned off. After a back-and-forth discussion with them, Eltima eventually pushed a new build with the vulnerabilities fixed. It's not a bug, it's a feature!

Local Escalation of Privilege Ubuntu Desktop- 708

Flatt Security     Reference →Posted 4 Years Ago
  • eBPF (extended Berkley Packet Filter) is a Linux kernel functionality that allows code to run in the context of the kernel without gaining further privileges. In order to do this, there is a verification step to ensure that all of the actions are memory safe. Because it runs in the kernel, it is faster than running it is userspace.
  • eBPF has many different map data types with one of them being a ring buffer (circular queue). When creating the file descriptor, two calls to allocate dynamic memory are made. One of them is the bpf_ringbuf_map and the other is bpf_ringbuf.
  • bpf_ringbuf_map contains a pionter to the bpf_ringbuf. bpf_ringbuf contains a consumer and producer position alignment and page aligned data, where this memory is mapped twice to give a ring buffer feel. In the eBPF bytecode, the data has a memory allocation for the data; this is essentially a call to malloc in the eBPF world but has to be a static value. The verifier knows this value because it is passed in as a const during the verification process.
  • The size of the allocation should not surpass the value passed to the verification function; this is the key to the bounds checking of the function. The main verification for the index check is the consumer and producer positions in the buffer. The check verifies that producer position - consumer position is less than the size of the buffer. This makes sense but has a terrible flaw in it.
  • The vulnerability comes from the fact that the data can be mmaped directly with the data not being validated after this alteration. The main check, mentioned above, can then be manipulated to pass by altering the producer and consumer position values so that the eBPF allocation goes much too large for the memory given to it. This leads to an out of bounds read and out of bounds write in the kernel.
  • With this primitive, the exploit strategy is fairly straight forward for the kernel. First, they create a read and write function to abstract away the vulnerability above and to only worry about exploitation. eBPF has many different protections in place to prevent exploitation, which limited the functionality that could be used in this exploit.
  • The author allocates two adjacent bpf_ringbuf structures and a kernel stack for exploitation. This is achieved by creating huge maps and then spawning a bunch of processes. Eventually, this lines up the way the attacker wants. Once the memory feng shui is done, the out of bounds read can be used to leak kernel pointers from the bpf_ringbuf object.
  • Once the randomness has been broken, we can overwrite the kernel instruction pointer on the stack in order to start a ROP chain. Since this is another process, we need to force it to pause while our full exploit happens. This is done by calling the syscall read and waiting to write to the buffer. With a full ROP chain setup, with user controllable values from the primitive above, popping a root shell is trivial.
  • One thing to note is that the read syscall function call does not have to be adjacent to our block. This is because we can search for the address of read until we find the kernel address that it would be at until the end of the function. That is super neat and takes out a lot of the system randomness.
  • Overall, this was a super interesting vulnerability in the Linux kernel! Verifying running code is extremely hard to do. Even with all of the effort and mitigations in place, eBPF has been a security problem for a little while. This shows that deeply understanding a code base allows for the discovery of vulnerabilities though :)

Making it rain with Software Defined Radio- 707

RK - Spurious Emissions    Reference →Posted 4 Years Ago
  • This post starts with a device that the author wants to hack: a wireless weather station and a temperature sensor. They knew it was using some custom protocol to communicate the temperature to the base station but did not know how.
  • The author had an RTL-SDR and an Adalm-Pluto. The Adalm-Pluto is Analog Devices (the company) branded education level SDR. This SDR has a 20MHz bandwidth, 12-bit ADC & DAC, full duplex, Gnu radio blocks and a range from 325MHz-3.8Ghz. These and the tool Universal Radio hacker (URH) were great starting points for this project.
  • The device itself had a carrier frequency labeled on it at 915MHz. When going to this on a spectrum analyzing, there were two peaks. Two distinct peaks indicates binary (0,1) frequency shift keying (FSK) in order to communicate the data. From looking at the spectrum analyzer, the communication occurred every 12 seconds ont the dot about the temperature.
  • The author absolutely abuses Universal Radio hacker for this project. Using this tool, it automatically decoded the symbol rate, samples per symbol and the modulation type (obviously FSK). From there, they took a bunch of recording with the device in several different locations, such as the freezer with specific temperatures.
  • Once they had 10ish recordings, they began to analyze the protocol. Once they began analyzing, they realized URH had done the automatic decoding wrong, which led them down a path of manually calculating some of the parameters for the calls. Eventually, they got a data that looked consistent enough to attempt to really decode.
  • The protocol had two beginning portions: a preamble of A's (0x1010) then a sync word to sync up the timings once everything had been completely powered on. It is common in a lot of RF communications to have both of these values. The middle portion contained a slightly different values that appeared to be the temperature. Finally, there were two values at the end that they were unsure of but were likely a CRC.
  • The payload were binary coded decimal (BCD) digits shifted by a -40C offset. They found this common practice out by googling online, since the initial values were confusing to the author. The -40 offset is because they did not want to send negative numbers.
  • What about the CRC? The author attempted to use the built in CRC maker in URH with all the different parameters but did not get anywhere. They tried online but nothing checked out. Eventually, they ran into a project that called CRC_RevEng which, given enough inputs, will find the proper parameters for the CRC check. Neat!
  • After doing all of this work, they noticed a simple replay attack works. Even cooler, in URH, they could change the temperature information from the signal where the CRC would automatically be updated. Once this was done, URH could be used to transmit the signal to the weather station. Cloudy with a chance of pwnage!
  • The author had some issues making this work on other devices though. Eventually, they figured out what the 8th and 9th nibbles were: a synchronized time to transmit the signal from the thermometer to the base station. There were 256 possible timing that it chose at bootup; this allowed for the station to ONLY listen at this interval and sleep otherwise.
  • The two channel mode just had a different timing interval. Besides this, everything was exactly the same as the previous protocol. Overall, I really appreciated the article with practical knowledge on using URH, the CRC repo and practical knowledge in protocol reverse engineering. Good work mate!

Understanding the Root Cause of CVE-2021-21220- 706

Hossein Lotfi - ZDI    Reference →Posted 4 Years Ago
  • Validation and actuality are the causes for some of the biggest bugs around! This blog post goes into a difference between how the optimizer sees code and how the code is actually represented in Chromium.
  • The proof of concept is literally 6 lines of code, which is absolutely wild for a JavaScript 0-day. The first part of the bug is when InstructionSelector::VisitChangeInt32ToInt64 converts a 32 bit integer into a 64-bit integer by either sign extending or padding the value with 0s.
  • While dealing with optimizations, the exploiteers found an edge case: if the value is XORed with 0, then we can PROVE the value should be the original output. If this is true, then the XOR operation can be entirely removed from the code during the optimization phase.
  • Here is where everything perfectly collides: the new value from the optimization is now UNSIGNED, even though it should be SIGNED. When the case is hit with an unsigned number, the new value gets changed after the optimization. This unsigned to signed problem creates a type confusion which is likely exploitable.
  • In the POC, the original value is -2^32 and the JITed value is 2^32, demonstrating an issue when the expected vs. real representation of the value. The authors of this post have a substantial amount of debug information in this post as well, which may be useful if you are getting into Chromium hacking.
  • In a followup article, they actually exploit this bug. How can a simple bad JIT interpretation turn into RCE? Let's find out!
  • Previously, turning an bad numeric result into an OOB read/write was done by abusing array bounds check elimination optimization. However, the optimization that allowed this to happen was removed because of how often it was exploited. The authors found a new strategy that was mentioned at Pwn2Own 2020 by abusing ArrayPrototypePop and ArrayPrototypeShift.
  • Array.shift removes the first element from the array, returns the removed element then computes the new size of the array by subtracting one. By abusing the original vulnerability and using it for the size of an array, the confusion is created. By running Array.shift, the length of the array will become -1, since there is no bounds check at this point in the optimization as everything is supposed to be safe.
  • Since the subtraction leads to an integer underflow of the length, the array now has infinite size. This means that we have a relative read/write for the entire memory space. They use this to create an addrof (address of) and fakeobj (fake object) primitives.
  • After creating the primitives, they use it to leak the address of a wasm function they created. Since the wasm
  • Overall, a good series of posting on modern exploitation in the browser. It is absolutely wild how complex these issues are becoming but are still weaponizable.

refcount increment on mid-destruction file- 705

Jann Horn - Project Zero (P0)     Reference →Posted 4 Years Ago
  • ep_loop_check_proc is trying to increment a reference count of a file in the Linux kernel via a call to get_file(). However, get_file() does not do the proper sanity checks on the file prior to access: only get_file_rcu() does.
  • In the epoll Linux subsystem, this becomes a problem because ep_loop_check_proc only has a weak reference to the file. Since this weak reference is NOT enough from it being deleted, it can be deleted while being used in ep_loop_check_proc. This created a use after free on the object. Even though this leads to a use after free, the author of the post labels this as a object state confusion bug.
  • The vulnerability was introduced while trying to fix another vulnerability that dealt with reference counting. This patch was attempting to validate that when adding a new fd to epoll, the deletion does not occur concurrently to this. The attempted fix was to check the reference count of the file via get_file, which is where the bug was introduced at.
  • Fixing concurrency bugs is incredibly hard! There are so many ways for an object to be affected and it is hard to consider all of the cases for this. Good bug find!

Insecure Handling of Bind Mount Sources- 704

Fwilhelm - Project Zero (P0)     Reference →Posted 4 Years Ago
  • runc and libcontainer are what makes Docker, Docker. This handles all of the chroot, namespaces and everything else in between. Docker adds a nice wrapper around all of this to make it more practical to use and install things. runc is written in GoLang and libcontainer is written in C.
  • The interface between C and Go is an important one to consider. A non-issue in Go may be a terrible issue in C, if things are not handled properly; differences between languages can make a big difference! When communicating from runc about the bind mounts via a Go to C call, the Go string can have embedded nullbytes inside of it.
  • The communication between the Go and C library, for communicating the Bind mounts above, is all separated by nullbytes from message to message. As a result, this created a message smuggling bug when the Bind Mount had an embedded NULLbyte inside of it. An example way to exploit this would be to bypass hostpath restrictions in Kubernetes clusters.
  • When sending a message from Go to C, there are two fields: an uint16 for the length of the message and a byte[] for the bytes themselves. Even though this looks totally fine, the length can be overflowed! This resulted in another smuggling bug since we can now specify all of the data in a message, even though we should not be able to.
  • Using the bugs together, it would be possible to create an arbitrary message. This message could do some malicious things, such as specifying the container to have the CLONE_FLAGS_ATTR. This would give the container access to the host namespace.
  • Interfacing with other languages can be complicated because of the inherit differences in the representation of data. Additionally, integer overflow issues exist in all languages. So, watch out world!

Windows 10 RCE: The exploit is in the link- 703

Fabian Braulen & Lukas Euler - Positive Security    Reference →Posted 4 Years Ago
  • Our computers are filled with many URIs (universal resource identifiers). Our computers have packages with built in functionality to know how to handle these links. Common URIs are http and file. However, many applications create their own in order to allow for extra functionality inside of the application. The authors of this article went after the common URI handlers on Windows 10 to see if they could find any vulnerabilities.
  • The vulnerabilities in URI handlers commonly lead to code execution. While enumerating through registry keys on the system they came across the URI ms-officecmd. Since Office is crazy complex, this was a legacy protocol and would be installed everywhere, they started looking around this URI handling. The URI accepted valid JSON, with a simply payload being ms-officecmd:{}.
  • At this point, they had to start reverse engineering the application. Luckily for them, it was written in C#, which is easily decompiled with variable names and everything else still intact. After reverse engineering a few applications (including another URI called ms-officeapp:), they were able to get a valid payload to work. The
  • The JSON had the following format:
    • appId: The office application to be opened. This included Access (1), Excel (2) and many other Microsoft products.
    • Filename: This contained a file path or a URL to a file to be opened in the application that was chosen above.
    • Name: The name of the application to open.
    • Command: The local location to execute for the application.
  • The first bug was that an arbitrary URL could be added for Outlook. When a user opened the application, it would take them to Outlook with an open Webview with the web page. This is a great way to do a phishing campaign!
  • Besides the phishing attack, files could be specified. Even though the file:// was blocked, using C:// bypassed this validation to access a local file. Additionally, by adding a trailing / the file extension check is bypassed but is ignored once the executable is open. In the POC on the page, they should PUTTY being opened directly. If we can trick the user into downloading something, we could even run our own executable here!
  • In order to open up another application, the AppBridge.dll library handles the URI. To do this, they need to include some of the user input into a cmd argument directly. By adding a double quote (") into the filename parameter, they found this could be used to escape this parameter. As a result, argument injection was now possible for whatever application they were trying to load.
  • Argument injection on a simple application with one or two flags is not likely to be a problem. However, with the complexity of Word, Outlook and other things, this was a disaster waiting to happen. They believe it would be possible to use an add-on to Word or Excel, but never got this working.
  • In Microsoft teams, which is built on Electron, they figured out how to launch a man in the middle attack via the CLI parameters. By adding in the flag --ignore-certificate-errors and an IP host rewrite rule, this could be done. Because of previous CVEs in Electron, Electron decided to not parse information after a file URI. Still though, they made an exception for 1 letter URIs. With a bogus URI and our flag above, a MITM attack could now be performed.
  • In both Teams and Skype the flag --inspect flag could be inserted. This flag can specify a debugger port to connect to. Upon connecting exec("<command>") was executed, giving RCE on the device, assuming an attacker knew where to connect to. Another bug was a command injection via the --gpu-launcher parameter of Electron, which comes from Chrome. This trick was used in a previous exploit as well.
  • Overall, great article on the tails of their research. A few takeaways from this:
    • Parsing and validation is hard to do properly! Even if validation prevents the obvious attack, see if some slight difference bypasses the validation but still works practically.
    • Argument injection is a very serious bug!
    • Do not trust vendors to pay out for what they say they will. There's always a loophole they will find.

Apache Log4j allows insecure JNDI lookups - 702

CMU    Reference →Posted 4 Years Ago
  • Log4J is a popular logging framework for Java. This is used by many large applications, including AWS. The vulnerability is similar to that of a format string bug: data within a string was being treated as trusted input, when it should not have been. This resulted in strings, provided by the user, being capable of large capabilities.
  • The default configuration of Apache Log4J supports Java Naming and Directory Interface (JNDI) lookups. This means that it can execute arbitrary code. Besides that, it LDAP, DNS and Java object usage would also be possible. Really, it's that simple. Put a string with ${jndi:ldap://localhost:1389/a} that gets logged and it will make a call to this to execute arbitrary code.
  • The patch disables JNDI by default in the lookups. This is now a configurable feature that can be turned on again if you like RCE from logging (lolz).
  • In some non-default configurations, the vulnerability was still possible to exploit. When data is passed to some other locations besides the message, it can lead to issues. Praetorian shows a proof of concept of this exfiltrating data. Additional details can be found at a twitter thread.
  • CVE-2021-44228 and CVE-2021-45046 are some of the worst vulnerabilities ever discovered with how widespread the Log4J package is used. I suspect, down the road, this will be talked about alongside heartbleed and shellshock.

Looking for vulnerabilities in MediaTek audio DSP- 701

Checkpoint - Slava Makkaveev    Reference →Posted 4 Years Ago
  • MediaTek chips are in 37% of all smart phone and IoT devices in the world. Modern chips contain AI processing unit (APU) and digital signal processing as well. The APU and the DSP have a custom architecture called Xtensa, where MediaTek even has their own custom instructions. How did they find all of this out? By a whole lot of reverse engineering!
  • First, they rooted a Xiaomi Android phone. The host operating system must communicate to the chip somehow; this was done via the audio_ipi at vendor/lib/hw/audio.primary.mt6853.so. This library has a single export: AudioMessengerAPI, which is responsible for Inter-processor interrupt (IPI) messages to the audio DSP. The driver has 6 ioctls, which the authors interact with directly during the later proof of concept.
  • The authors of the article got the firmware by stealing the factory update image file audio_dsp.img. However, this also could have been done by reading the /dev/block/platform/bootdevice/by-name/audio_dsp on a root device. The article dives into the format of this img as well but they do find out it runs a custom version of FreeRTOS. Here is the interesting part though: IDA has no idea how to process a large part of this code.
  • IDA Pro 7.6 supports the Tensilica Xtensa architecture. But, not well and there are many customized instructions, which can be variable length as well. Using the Xtensa SDK many more of the instructions can be decoded. Additionally, MediaTek had very helpful logging that made it easy to find functions and their usage. Not everything was perfectly decoded but it was good enough for this research.
  • The drivers, from the Android side, have to interact with the chip somehow. The authors reviewed this source to find the best possible entry points in the code for the DSP chip.
  • The first vulnerability they found was a classic heap overflow in one of the IPI message handlers (ID 6). When processing the input, the function copies the message payload into an object, with the amount of bytes being copied directly controllable by an attacker. There is no validation on this size, which leads to a memcpy out of bounds write on the heap. Sending more than 20 bytes triggers the bug.
  • A similar issue was found with an IPI ID of 7. A copy is performed with a user controlled size in a buffer of only 0x20 bytes. Even though there is a validation, it checks the wrong size value (0xE0). It is like somebody wrote the code with a hardcoded size but the eventually size of the buffer change, without the validation ever being changed.
  • The last vulnerability on the DSP processing is an out of bounds write via lack of validation of array indexing. Simply put, the user can provide an index but this index is never validated. By providing something outside of the expected range, a write can occur with a user controllable value.
  • These bugs are awesome but there is one problem: only specific processes are allowed to use these drivers. Some sort of privilege escalation would be required to hit these drivers! The authors noted that the Mediatek hardware abstraction layer (HAL) was controllable via standard function calls to the AudioManager. The authors believe that this was left over for testing purposes but gives us access to more things than we should!
  • Normally, the HAL configurations are set by the manufacturer and are not a source of malicious input. But, in this case, we can alter the HAL configuration to do whatever we want. Since this is not a normal location for input, the security was much weaker. On the Xiaomi device, they found a vulnerability that allowed for the calling of the DSP drivers from inside the library.
  • A few things that I took away from this:
    • Hard to reverse targets tend to have easier bugs. The effort is just put into reversing instead of vulnerability hunting in this case.
    • Sandboxes are quite useful! As we move more and more towards sandboxing, LPEs are going to become more common.
    • Changes in unexpected places usually leads to security bugs.

A deep dive into an NSO zero-click iMessage exploit: Remote Code Execution - 700

Ian Beer & Samuel Groß - Project Zero (P0)    Reference →Posted 4 Years Ago
  • NSO Group is a access-as-a-service company. They will build full & weaponizable exploits to compromise computers and phones for companies. The entrypoint of choice is via text message. One weird trick is that iMeessage supports GIFs; by specifying .gif as the extension but sending another file type, it will parse this file format instead. Since file parsing is notoriously hard to do. NSO uses the "fake gif" trick to target a vulnerability in the CoreGraphics PDF parser.
  • The PDF parser appears to be Apple proprietary code. But, the JBIG2 implementation is from Xpdf, which is open source. JBIG2 format is a series of segments, which can be thought of as a series of drawing commands which are executed sequentially in a single pass. The vulnerability is an integer overflow when combining referenced segments. The overflow occurs within a loop that is continually adding the segments size together.
  • The size above is then used for a call to malloc. Since the overflow occurred, the buffer is undersized! This leads to a buffer overflow inside this buffer. This should lead to a crash though, right? 32GB of data looks would be a large overflow!
  • To avoid the crash, NSO group does a crazy trick to stop the overflow from being too large and causing a crash. By doing heap grooming, it is possible to write off the end to the GList backing buffer. This buffer stores segment information and is used to find the segments to use for the writing process. By using the overflowing write to corrupt the backing buffer pointer with pointers to bitmaps, we can cause this program not to crash! Even function pointers still work properly since the bitmap type inherits from the Segment type.
  • At this point, we have caused an overflow and the program has not crashed. So, now what? Get a more powerful primitive! By carefully lining up some other objects in memory, three more Bitmap pointers can be written to the GList buffer. By doing this, the VTable for the object and the expected size of the buffer have been altered. This gives an unbounded drawing canvas. This means that future segment commands can read and write outside of the expected buffer length!
  • This gives the attackers an relative read and a relative write in this process. You may be asking yourself "If this is a parser, then it's a single pass, right?" The JBIG2 refinement format is flexible with many different operations. By performing these operations (XOR, AND, OR and XNOR) on out of bounds elements, on the unbounded memory, you have a turing complete computer to cause all of the damage that you need.
  • What if rather than operating on glyph-sized sub-rectangles you instead operated on single bits? You can now provide as input a sequence of JBIG2 segment commands which implement a sequence of logical bit operations to apply to the page. And since the page buffer has been unbounded those bit operations can operate on arbitrary memory. Now, you have a Turing complete computer!
  • According to the author, there are over 70K segment commands defining logical bit operations to make a tiny computer. It even has registers, a 64-bit adder and a comparator to search and perform arithmetic operations. The author says "The bootstrapping operations for the sandbox escape exploit are written to run on this logic circuit and the whole thing runs in this weird, emulated environment created out of a single decompression pass through a JBIG2 stream. ". This is truly amazing and probably took this team an insane amount of time to write.
  • The author says that the sandbox escape (which will be detailed in another post), uses the mini-computer described above. This post really blew me away with what is possible with weird machines.