I was confused by the floating point instructions like fldl and fstpl, so I looked at this tutorial, but it wasn't really important to understand them in detail. All that matters for us is that they compare a 64-bit value at $esp+0x98 to a static value from location 0x8048690. If they match, the program accepts the input. If they don't, it prints "Nope".
The command "info float" in gdb shows the floating point stack.
The key is to find out that value, which doesn't change, and include it in your attack. That way you can enter more than 127 characters.
0x0804851d <+0>: push %ebp
0x0804851e <+1>: mov %esp,%ebp
0x08048520 <+3>: and $0xfffffff0,%esp
0x08048523 <+6>: sub $0xa0,%esp RESERVE 160 BYTES ON STACK
0x08048529 <+12>: fldl 0x8048690 STORE CANARY ON FLOAT STACK
0x0804852f <+18>: fstpl 0x98(%esp)
0x08048536 <+25>: mov 0x804a040,%eax
0x0804853b <+30>: movl $0x0,0xc(%esp)
0x08048543 <+38>: movl $0x2,0x8(%esp)
0x0804854b <+46>: movl $0x0,0x4(%esp)
0x08048553 <+54>: mov %eax,(%esp)
0x08048556 <+57>: call 0x8048400 <setvbuf@plt>
0x0804855b <+62>: lea 0x18(%esp),%eax
0x0804855f <+66>: mov %eax,0x4(%esp)
0x08048563 <+70>: movl $0x8048678,(%esp)
0x0804856a <+77>: call 0x80483b0 <printf@plt>
0x0804856f <+82>: lea 0x18(%esp),%eax
0x08048573 <+86>: mov %eax,0x4(%esp)
0x08048577 <+90>: movl $0x8048682,(%esp)
0x0804857e <+97>: call 0x8048410 <__isoc99_scanf@plt> READ INPUT FROM USER
0x08048583 <+102>: fldl 0x98(%esp)
0x0804858a <+109>: fldl 0x8048690
0x08048590 <+115>: fucomip %st(1),%st
0x08048592 <+117>: fstp %st(0) CHECK CANARY VALUE
0x08048594 <+119>: jp 0x80485a9 <main+140> CANARY CHANGED: GO PRINT "Nope"
0x08048596 <+121>: fldl 0x98(%esp)
0x0804859d <+128>: fldl 0x8048690
0x080485a3 <+134>: fucomip %st(1),%st
0x080485a5 <+136>: fstp %st(0) CHECK CANARY VALUE
0x080485a7 <+138>: je 0x80485c1 <main+164> UNCHANGED: GO PRINT "Got "
0x080485a9 <+140>: movl $0x8048685,(%esp) PREPARE TO PRINT
0x080485b0 <+147>: call 0x80483c0 <puts@plt> PRINT "Nope"
0x080485b5 <+152>: movl $0x1,(%esp)
0x080485bc <+159>: call 0x80483e0 <exit@plt> EXIT(1)
0x080485c1 <+164>: mov 0x804a030,%eax PREPARE TO PRINT
0x080485c6 <+169>: lea 0x18(%esp),%edx PREPARE TO PRINT
0x080485ca <+173>: mov %edx,0x4(%esp) PREPARE TO PRINT
0x080485ce <+177>: mov %eax,(%esp) PREPARE TO PRINT
0x080485d1 <+180>: call 0x80483b0 <printf@plt> PRINT "Got"
0x080485d6 <+185>: leave
0x080485d7 <+186>: ret
rm foo
mkfifo foo
./ex5 > foo &
gdb ./pre2
Then, inside gdb, run the file like this:
run <foo
"foo" is a file used as a named pipe. Each time it's used, it's emptied,
like a keyboard buffer.
ex5 is an executable file that prints out an exploit string--you need to create it.
To run the server on the local network, use this command:
nc -nlvp 9010 -e ./pre2
To send an exploit to the server, use a command like this:
./ex5 | nc 127.0.0.1 9010