计算机系统基础实验 AttackLab

本文是作者的作业备份,仅作参考,不可照搬抄袭!

实验背景:

本实验分为五个阶段,ctarget的三个使用的是CI(code-injection),rtarget的两个阶段使用的是ROP(return-oriented-programming),如表1所示

ctarget和rtarget都是用getbuf函数从标准输入读入字符串,getbuf函数定义如下:

函数Gets类似于标准库函数gets,从标准输入读入一个字符串(以’\n’或者end-of-file结束),将字符串(带null结束符)存储在指定的目的地址。从这段代码可以看出,目标地址是数组buf,声明为BUFFER_SIZE个字节。BUFFER_SIZE是一个编译时常量,在你的target程序生成时就具体确定了(每位学生的targetBUFFER_SIZE不同)。

函数Gets()gets()都无法确定目标缓冲区是否够大,能够存储下读入的字符串。它们都只会简单地拷贝字节序列,可能会超出目标地址处分配的存储空间的边界。

如果用户输入的字符串足够短,getbuf会返回1

如果用户输入的字符串很长,就会出错, 如图3所示:

实验步骤:

第一关:

首先调用了test函数,test中调用了getbuf函数,经过getbuf函数后返回test函数。

    而第一关要求调用test函数后,不是正常返回test,而是执行touch1

    从touch1函数可以看出,只有一个输出函数,不需要写入新代码。所以只要在栈中将程序getbuf的返回指令ret中的地址换成touch1的地址就可以了。

    从sub $0x18,$rsp 可以看出getbuf创建的缓冲区大小为0x18,即24个字节。

    而touch1的起始地址为0x401911,所以只需要利用缓冲区溢出去更改返回地址就可以了。

    所以我们的攻击字符串attack1为

第二关:

与第一关类似,需要调用test在getbuf函数返回时,执行的是touch2而不是test

       而观察touch2发现,除此以外,还需要利用缓冲区溢出注入数据,使得val中的数据等于我的cookie=0x66c417e7

       而touch2的起始地址为0x40193f,而“cmp %edi,0x203baf(%rip)”说明touch2中的val则存在$edi中。也就是我们需要先将edi中的值设置为cookie,然后再跳转到touch2执行。

       通过汇编与反汇编代码得:

       第一串攻击字符串为48 c7 c7 e7 17 c4 66 68 3f 19 40 00 c3

       而通过gdb,在0x401907处设置断点去查看getbuf下rsp所在地址

       得到地址0x55666448,

       所以最后得到攻击字符串:

 

第三关:

       Getbuf调用后执行touch3,而touch3中调用了hexmatch的函数,而在hexmatch代码中我们可以看出需要让touch3参数val等于我的cookie字符的字符串表示。

       我的cookie=0x66c417e7

       而字符串表示 0x66c417e7=36 36 63 34 31 37 65 37

       Touch3的起始地址为0x401a56,确认函数位置后我们需要确认将cookie的字符串表示放在合适的地方,而当调用hexmatch函数后,缓冲区中的数据会发生改变,所以我们需要看一下调用前后缓冲区的情况。

       先写一个attack3.txt的攻击字符串,通过./hex2raw < attack3.txt > bufraw3.txt 转换成攻击代码,gdb进入touch3去看缓冲区.

       缓冲区地址由第二关可知是0x55666448

       在调用hexmatch(0x401a6d)前后设置断点。

       比较调用前后的缓冲区,可以发现除了前面16个字节存放注入代码以外,还有0x55666450开始的40个字节也没有合适的空间可以存放调用后数据。

       然后我们发现从0x55666468处开始的8个字节是前后不变,都没有存放其他数据,可以用来放我们的cookie,所以将这个地址注入rdi中

       汇编与反汇编得:

       所以第一串攻击代码为48 c7 c7 68 64 66 55 68 56 1a 40 00 c3

       最后得攻击字符串为:

 

第四关:

使用gadget farm里的gadget来攻击rtarget函数,根据指令的字节编码,得出指令如下:

mov   %rsp,%rax

ret

mov   %rax,%rdi

ret

popq  %rax        

ret                 

movl  %eax,%edx

ret

movl  %edx,%ecx

ret

movl  %ecx,%esi

ret

lea   (%rdi,%rsi,1),%rax

ret

而本题要求:

  1. 只能使用movq 、popq、 ret、 nop的gadget。
  2. 只能使用前八个x86-64寄存器。
  3. 只能用两个gadget实现此次攻击。
  4. 如果一个gadget使用了popq指令,那么它会从栈中弹出数据。这样一来,攻击代码能既包含gadget的地址也包含数据。

与第二关相同,需要让val等于我的cookie值,而使得存放val的rdi寄存器注入cookie,可以用到以下的指令:

    需要用到两个gadget,分别是

mov   %rax,%rdi

ret

popq  %rax         

ret                 

所以攻击代码如下:

第五关:

本题要求为:

  1. 允许使用函数start_farm和end_farm之间的所有gadget。
  2. 可以使用movq、 popq、 ret、 nop、 movl指令,以及2字节指令。
  3. 只能使用前八个x86-64寄存器。
  4. 至少需要8个gadget实现此次攻击。

与第三关相同,需要将rdi的值设置为cookie的字符串表示的值,也就是存储cookie字符的地址。

       与第三关相同,需要将rdi的值设置为cookie的字符串表示的值,也就是存储cookie字符的地址。需要先将buffer填充溢出,然后再加上cookie的偏移量。

       结合上面的代码,可以进行这样的操作:

mov   %rsp,%rax

ret

mov   %rax,%rdi

ret

popq  %rax        

ret                

movl  %eax,%edx

ret

movl  %edx,%ecx

ret

movl  %ecx,%esi

ret

lea   (%rdi,%rsi,1),%rax

ret

mov   %rax,%rdi

ret

       而从第一条指令结束一直到cookie之前还有9条指令,所以偏移量为0x48

       所以攻击字符串为:

  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值