Introduction
binaryThis is not a normal but very interesting pwn challenge. The target of this chal is to "guess" random 64 bits.
When running binary, it'll fetch 64 random bits from /dev/urandom, and mmap 64 pages according to the following rule:
// bits = random 64 bits void* base = 0x200000000; for(int i=0;i<64;i++) { mmap(base+(2*i+bits[i]) * 0x1000, 0x1000, ...); }
And the result of maps looks like:
After mmap-ed these pages, we can send our shellcode, the shellcode will be executed and it has to answer what the 64 random bits are. The flag will be printed out if answered correctly.
Exploit Method
The first thought come to mind is the famous ASLR breaking attack by VUSec - AnC attack.However, the scenario is different between AnC attack and this challenge.
Basic idea of AnC is accessing an unknown address pointer and the accessing time will be different according to the CPU cache.
While in this chal, we cannot access any address starts with 0x200000000 because it will crash directly if the address doesn't be mmap-ed.
Thanks to +劉育全 's googling ability, he found there's a PREFETCHT0 instruction in x86. This instruction takes an address as argument and asks CPU to bring the address into cache. And according to the reference, this instruction works as no-op if the specified address doesn't exist.
So we experimented how many CPU ticks need to take when the address exists or not. And the result is exciting - it take much longer time when the address is not mmap-ed!
So the exploit is easy, just run PREFETCHT0 many times over two addresses, the one needs shorter time is the mmap-ed one.
Exploit Script: https://github.com/david942j/ctf-writeups/blob/master/0ctf-quals-2017/pages/pages.rb
Flag: flag{rand0mPage_randomFl4g}
沒有留言:
張貼留言