Show Notes

118 - Fastly Infoleak, Samba OOB Access, and Pwning MacOS

A cool bug in H2O’s QUIC implementation leading to disclosing uninitialized memory. Stream data in HTTP/3 comes in an encoding similar to chunked encoding, including an offset in the chain, the data size and teh data itself. The Quicly library which implements Quic provides a callback to H2Os code providing these frames as they arrive, and provides an interface to request the byte ranges that it has received so far. H2O gets these calls backs and tries to create a single contiguous memory block for the received data, resizing as necessary. The problem comes when data arrives out of order creating gaps in the memory that H2O has actually written to. If a frame comes it at say 0x100 and then another at 0x600, the frames between won’t be initalized. Normally of course all these bytes will come in and there won’t be a problem because all the memory will eventually be initialized. One could maliciouslly craft a request that will create these gaps, then by sending a RESET_STREAM frame, terminate the stream and have Quicly just check if it has recieves the right amount of data, and drop all knowledge about the recieved byte ranges. So H2O no longer has any way (apart from tracking it internally) to know which byte ranges in its own contiguous stream have been sent. By getting this request sent along to an endpoint it can disclose memory from the Fastly server about other user’s and their requests.

Mistrusting some extended attributes, using them to calculate an offset leading to out-of-bound read/write primitives; presumably exploitable since these were used at Pwn2Own. In the fruit_pread function will read the org.netatalk.Metadata extended attribute which can unauthenticated user can set.

This attribute is parsed into an adouble structure, and the ADEID_FINDERI entry is ultimately controlled by an attacker. This is used to calculate a pointer from which is will read 32 bytes. The point does need to point within the data block, but by pointing it right at the veyr end it’ll read out of bounds by 31 bytes. A similar issue was found in fruit_pwrite same deal with the pointer, but it’ll write the data to a point, giving a 31 byte out of bound write.

The same issue was found with the ADEID_FILEDATESI entry, providing gadgets for a 3 byte out-of-bounds read/write