CSAPP-AttackLab


Attack Lab

Attack Lab的任务是利用不同的方法和技巧来攻击一些有漏洞的程序,包括以下几个方面:

  1. 基本的缓冲区溢出攻击:在给定的程序中找到并利用缓冲区溢出漏洞,以修改程序的行为或获取特权访问。
  2. 栈相关攻击:了解不同的栈布局和函数调用约定,并设计和实现基于栈的攻击,如修改返回地址、修改局部变量等。
  3. 格式化字符串攻击:利用格式化字符串漏洞修改程序的内存内容,并通过这种方式达到攻击的目的。
  4. 返回导向编程(Return-Oriented Programming, ROP)攻击:构造精心设计的ROP链,通过利用程序中已有的代码片段执行恶意操作。

phase_1

看到getbuf开辟了56个字节的栈空间

发现touch1的首地址是 0x401797

phase_2

将正常的返回地址设置成为注入代码的地址,这次注入直接在栈顶注入,即设置为%rsp

cookie的值写在%rdi里

获取touch2的首地址,这个已经有了

要调用touch2,却不能用call jmp等命令,所以只能用ret弹出,在弹出之前要先把touch2地址压栈。

这三条指令地址我们就有了,就是每行反汇编最前面的一长串十六进制数字,接着我们去找%rsp在哪,借助gdb。0x401785就是getbuf开辟栈空间后的栈地址

得到%rsp地址,然后写注入字符串就好了,字符串为 注入代码地址——无用字符——返回地址。

栈帧图如下

phase_3

与前面不同的是,这次传进的参数是一个字符串,同时函数内部用了另外一个函数来比较。本次要 比较的是”cookie”这个字符串。

· 在C语言中字符串是以\0结尾,所以在字符串序列的结尾是一个字节0

· man ascii 可以用来查看每个字符的16进制表示

· 当调用hexmatch和strncmp时,他们会把数据压入到栈中,有可能会覆盖getbuf栈帧的数据,所以传进去字符串的位置必须小心谨慎。

如果我们将数据放在getbuf的栈空间里面,很有可能就被这两个函数覆盖了。所以我们要把数据放到一个相对安全的栈空间里,这里选择放在父帧即test的栈空间里。gdb看一下test栈空间地址。

思路大致为:

· cookie转化为16进制

· 将字符串写到不会被覆盖的test栈空间,再将该地址送到%rdi中

· 将touch3首地址压栈再ret

使用man ascii命令得到cookie的十六进制

35 66 32 62 39 36 39 36

phase_4

做法还是像之前一样,将cookie放到%rdi,把touch2的地址放到栈中,以ret执行。提示,我们利用的gadget是从startfarm到midfarm之间的,并且只需要两个。结合我们之前phase2的做法,猜测是需要一个mov命令来放参数,另外一个结合提示就是pop命令了,pop会把栈顶的cookie弹出到另外一个寄存器(rax),再用mov命令写到%rdi里。

我们需要的代码是这样

popq %rax
movq %rax,%rdi

栈帧:

phase_5

思路:

· 因为开启了栈随机化,所以不能直接把代码插入到绝对地址,必须找一个基准,我们就只能找%rsp。
· 因为touch3会开辟一个很大的buffsize,若把数据插到touch3下面的栈空间,有关内存之后基本就会被重写,所以要存在touch3的更高地址处。所以要在%rsp上加一个bias才可以,即字符串地址是%rsp + bias。
· 没有直接的加法指令,那就找两个寄存器互相加,,实现了%rax = %rdi + %rsi

所以具体操作就是:
· 把%rsp里的栈指针地址放到%rdi
· 拿到bias的值放到%rsi
· 利用add xy,把栈指针地址和bias加起来放到%rax,再传到%rdi
· 调用touch3

bias的值:可以看到在返回地址和字符串首地址之间有9条指令,每个指令8个byte,共72byte也就是0x48


文章作者: Aiaa
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Aiaa !
  目录