Safe This Week: Free Use For Dummies, WiFi Cracking, and PHP-FPM


In brilliant writing, [Stephen Tong] brings us his “Use-After-Free For DummiesIt’s a startling story of a vulnerability that really shouldn’t exist, and a walkthrough on how to complete a flag capture challenge. The vulnerable binary is running on a Raspberry Pi, which is very important. It is a multithreaded application that uses non-locking data sharing, via a pair of integers readable by multiple threads. These ints are declared using the volatile keyword, which is a useful way to tell a compiler not to optimize too heavily, as this value can be changed by another thread.

On an x86 machine, this approach works perfectly, because all out-of-order execution functionality is guaranteed to be transparent overall. In other words, even though thread one can speed up execution by changing the shared memory in advance, the processor will keep the changes to the shared memory in the correct order. When this shared memory controls concurrent access, it’s really important that the order goes as you expect it to. What surprised me is that the ARM platform does not provide this overall order of memory. While out-of-order execution will be transparent to the modifying thread, other threads and processes may observe these out-of-order actions. An example can help:

volatile int value;
volatile int ready;

// Thread 1
value = 123; // (1)
ready = 1; // (2)

// Thread 2
while (!ready); // (3)
print(value); // (4)

It is one of the [Stephen]examples. If this were configured to run in two threads, on an x86 machine, you would be guaranteed that (4) would always print 123. On an ARM, no such guarantees. You may well have an uninitialized value. It is a race condition. Now you can look at this and ask yourself like I did, how does someone program something for ARM chips? First thing, although reorganizing memory is one thing, ARM guarantees consistency within the same thread. This quirk only affects multi-threaded programming. And second, the libraries for offering multi-threaded programming semantics to mark memory access that must be properly ordered across threads.

The exploitable binary in question uses a circular queue for the inter-process buffer and follows a head and tail location to determine how full the buffer is. One process introduces data, the second reads it. The vulnerability is that when the buffer is completely full, reorganizing memory manipulation can cause a race condition. This ring buffer fills with pointers, and when the race is won by an attacker, the same pointer is used twice. In essence, the program now has two references to the same object. Without further tips, this results in a free double error when the second reference is released.

What are some tricks we could use to make this a feat? First of all, be aware that we have two references to an object. This object contains a pointer to another string, the length of which is entirely controlled by user-supplied data. We can trigger a free of one of these references, which leads to the freeing of the object, but we have yet another reference, which now points to uninitialized memory. To turn this into an arbitrary reading, a very nifty trick is used. Before releasing our object, we allocate another object and store a long string. Then we free the object to which we have a double reference, and finally free the object with the long string. Finally, we allocate an additional object, but the string that we store is designed to look like a valid object. Memory is reallocated in the order of last in, first out, so the string is stored in reclaimed memory that we still have a reference to. The program expects the object to contain a pointer to a string, so our bogus object can point to arbitrary memory, which we can then read.

The last trick is arbitrary writing, which is even more difficult to achieve. The trick here is actually to perform the free duplicate, but to manipulate the system so that it does not result in a segmentation error. We can use the trick above to write arbitrary data to a freed memory location. Since the location was on the free people list twice, the system still considered it free even though it was also being used. The Linux memory manager uses a nifty trick to manage the reclaimed chunks of memory, by storing a pointer to the next recovered location in each chunk. Write the location you want to overwrite in this free chunk, then allocate another chunk. The system now thinks your arbitrary location is the next free memory location to use. The next allowance is your arbitrary handwriting. The editorial has more details, as well as the rest of the chain of operations, so be sure to read it all.

How secure is this WiFi?

[Ido Hoorvitch] of CyberArk had pandemic-induced free time, and chose to collect packet captures from 5,000 password protected WiFi networks around Tel Aviv. In the old days, you had to capture a 4-way handshake to have a chance to break WPA encryption. In 2018 a new technique has been discovered, where a single authentication response was all that was needed to attempt to decrypt the key – no active user required. The magic string here is the PMKID, which is a SHA-1 hash of the WPA password and other network details, first performed by a key derivation function.

The popular tool, Hashcat, can take advantage of a GPU to speed up the cracking of a PMKID. SHA-1 hashes are one of the things GPUs are particularly good at, after all. The 8 Quadros handled nearly 7 million hash calculations per second. The problem when trying to decrypt a WPA key is that although they must be at least 8 characters long, they can be much longer which creates a huge search space. The first tip [Ido] used was to take advantage of one of the common password sources, a cell phone number. In Tel Aviv, this means the password is 05 followed by 8 additional digits. This is a key searchable space, and of the 5,000 networks sniffed, nearly half were hacked by this approach. Then it would point Hashcat at a dictionary file to automatically try for known passwords. Between the dictionary attack and the constrained approaches such as the cell number format, 70% of the targeted networks were cracked. Take-out? Use a long password that is not easy to guess and will not easily be part of a forced search.

Use of Google after the free PoC

Reported in June this year by the Security For Everyone team, CVE-2021-30573 now has a published PoC. This vulnerability has been fixed in Chrome / Chromium 92. The trigger code is a bit of simple HTML but very malformed. Trying to parse this code just by looking at it, I immediately called it “damn” HTML, so it’s no wonder Chrome had issues with this as well.

PHP worker to root

A bug in PHP-FPM discovered by Ambionics Security allows to pass control of a PHP worker directly to the root of the system. Although this is a serious issue, it is not a remote code execution vulnerability. Other techniques must first be used to support a PHP worker thread. This means that an attacker should be able to execute PHP code and then find a way to escape the PHP “sandbox”. While this is not trivial, there are techniques and bugs to make this possible.

The problem is that the inter-process communication mechanism is shared mapped memory, and too much of the data structure is made available to individual workers. A worker can modify the main data structure, causing the top-level process to write to arbitrary memory locations. Although the location can be arbitrary, actual data writes are extremely limited in this vulnerability. In fact, it boils down to two write primitives: Set-0-to-1 and clear-1168-bytes. It might not seem like much, but there are a lot of flags that can be toggled by setting a value to 1, and the rest of the exploit makes heavy use of this technique. The real trick is to generate arbitrary error messages, then use the 0-to-1 primitive to corrupt the data structure of those messages.

The vulnerability has been around for a very long time, since PHP 5.3.7. It is fixed in 8.0.12, 7.4.25 and 7.3.32. A final difficulty here is that PHP 7.3 is still in security support, but this was seen as an invasive change, and the PHP maintainers initially chose not to push the patch to this older version. After a few round trips on the bug discussion, the correct call has been made and version 7.3.32 has been released with the fix.

Gitlab in the wild

HN Security asked a client to report something suspicious, and it turns out CVE-2021-22205 used in nature. This bug is an issue in ExifTool, where a DjVu file can execute arbitrary perl code. This RCE has been abused to make new administrator users on the attacked system. If you are using Gitlab, make sure you are up to date. Versions 13.10.3, 13.9.6, and 13.8.8 were released with the patch on April 14 of this year. It seems that versions 14. * were never vulnerable, because version 14.0 was released after this patch. Hackerone and the entire bug bounty community have their share of problems, but the disclosure thread for this one is an example of a correctly executed program.

Source link


About Author

Leave A Reply