路由器固件安全漏洞分析——开端入坑

前言

今日我们开一个新坑,——路由器固件的分析与漏洞挖掘。

尽管网上文章分析不少,但我还是感觉缺少点什么........虽然本人实力有限,比不上那些逆向大佬。我还是喜欢把自己的思路分享给大家。

固件的分析不同与常规的web网站。我们没有这款固件开发的原始的.c代码,只能利用工具提取固件的文件系统,使用逆向软件分析固件的可执行程序。如ida pro 在逆向界面中我们只能看到的是一条条指令操作着寄存器,栈空间地址。使用软件的反汇编功能F5查看程序的伪代码,这种代码在功能上与源码无差,但实际上代码阅读性上可谓是差了大节。

二进制安全底层的知识,我从来不觉的有很复杂。只是现在的书籍资料经常把一些知识讲的非常晦涩且庞大。这点尤其是在计算机底层原理这块,满篇大论让人云里雾里.....,而且它们总是在说是什么,没有从初设计者的想法出发思考为什么要这么做,做的过程中遇到了什么问题,是如何解决的.最终才形成这样的一个庞大的系统.....

在开始本章前我希望您具备或者说你有这样的理念

1.什么是固件?可以用来干什么?开发的大致流程?
2.指令是什么?指令的分类 ? 为什么这样分类?-----引出架构
3.程序执行内存是怎么分布的?或者说可以怎么分布?
4.栈的原理及调用(很重要)函数调用栈的变化!
5.socket编程c语言版,如何使用c开发自己的web服务器?

固件仿真解决方案

推荐一个项目---一键模拟仿真固件

GitHub - liyansong2018/firmware-analysis-plus: Simulate firmware with one click of firmadyne (使用 firmadyne 一键模拟固件)Simulate firmware with one click of firmadyne (使用 firmadyne 一键模拟固件) - GitHub - liyansong2018/firmware-analysis-plus: Simulate firmware with one click of firmadyne (使用 firmadyne 一键模拟固件)icon-default.png?t=N7T8https://github.com/liyansong2018/firmware-analysis-plus

项目的安装,看项目介绍,有很多坑要安装很多的依赖包。本人也是纯小白,待熟练后考虑出一期专门的踩坑教程

必使用功——binwalk 这个工具在上面的项目依赖中已经有了。如果要单独安装ubuntu官方源apt get就可以直接装。

本次测试的固件下载地址

D-Link Technical Support

我们下载固件版本B03

路由器固件安全漏洞分析——开端入坑_第1张图片

 binwalk -Me xxxxx.bin 可提取固件的文件系统

路由器固件安全漏洞分析——开端入坑_第2张图片

在提取的过程中我们可以从固件中得到一些信息,压缩信息 地址信息 文件系统 大小端 等

在提取后的squashfs-root文件夹中,我们会得到一个liunx的系统文件目录,也侧面说说明最初的开发就是在这样的系统上运行的

路由器固件安全漏洞分析——开端入坑_第3张图片

固件仿真,在firmware-analysis-plus中执行命令

./fap.py -q /qemu-builds/2.5.0/ DIR823GA1_FW102B03.bin

路由器固件安全漏洞分析——开端入坑_第4张图片

访问192.168.0.1,仿真模拟成功。

路由器固件安全漏洞分析——开端入坑_第5张图片

固件分析解决方案

IDA pro 网上搜索下载

binwalk -Me xxxxx.bin 可提取固件的文件系统

本次漏洞分析前置知识

SOAPAction

SOAPAction

SOAPAction 是一个 HTTP 头部(Header),用于指定在 SOAP(Simple Object Access Protocol)请求中要调用的 Web 服务操作。SOAP 是一种基于 XML 的协议,它允许网络上的计算机通过 HTTP 通信并交换结构化信息。尽管 SOAP 可以使用不同的传输协议,但最常见的是通过 HTTP 或 HTTPS 进行通信。

SOAPAction 的作用

当客户端向服务器发送一个 SOAP 请求时,SOAPAction 头部指明了要执行的特定操作。这有助于 Web 服务框架理解请求的目的,并将请求路由到正确的服务方法或操作处理程序。

在某些情况下,SOAPAction 头部也可以用来实现一定级别的网络安全策略,例如,通过检查 SOAPAction 来限制对敏感操作的访问。

示例

假设你有一个 Web 服务,它提供了一个名为 GetUserInfo 的操作,客户端在发送请求时,HTTP 头部可能包括类似以下内容的 SOAPAction

SOAPAction: "http://example.com/webservices/GetUserInfo"

这告诉服务器,该请求意图调用 GetUserInfo 操作。

在 HTTP 请求中的位置

SOAPAction 头部直接包含在 HTTP 请求中,紧跟在其他标准 HTTP 头部之后,例如 Content-Type。一个典型的 SOAP 请求可能看起来像这样:

POST /service.svc HTTP/1.1
Host: example.com
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://example.com/webservices/GetUserInfo"
​


    
        
            
        
    

注意事项

  • 在 SOAP 1.1 中,SOAPAction 头部是必需的,但在 SOAP 1.2 规范中,它被定义为可选,并且其用途和行为有所不同。在 SOAP 1.2 中,操作信息通常通过其他机制,如 WS-Addressing 标准中的 Action 头部来指定。

  • 虽然 SOAPAction 头部可以增强 Web 服务的自描述性,但它也可能暴露服务的内部结构,因此在设计 Web 服务时应考虑到安全性问题。

  • 确保客户端和服务器对 SOAPAction 头部的使用达成一致,特别是在使用第三方服务时,需要注意遵循服务提供者的指导和规范。

goahead

GoAhead 是一款轻量级、高性能、可嵌入的 Web 服务器,它被设计用于小型到中型的设备和应用,例如家庭网关、路由器、打印机、家庭自动化设备和其他嵌入式设备。GoAhead 被广泛用于工业和消费级产品中,因为它非常适合资源受限的环境。

主要特点

  1. 轻量级:GoAhead 设计紧凑,内存占用小,适合嵌入式系统。

  2. 跨平台:支持多种操作系统,包括 Windows、Linux、macOS 以及各种嵌入式操作系统。

  3. 易于扩展:提供了简单的 API,使得开发者可以容易地添加自定义的动态内容处理器。

  4. 安全:支持基本的安全特性,如 SSL/TLS 加密、基本认证和摘要认证等。

  5. 支持标准:支持 HTTP/1.1、CGI/1.1、WebSocket 等网络通信标准。

使用场景

GoAhead 常用于那些需要内置 Web 服务器功能的设备或应用中,例如:

  • 嵌入式设备的配置界面

  • 控制面板和监控系统

  • 小型 Web 应用

  • IoT 设备和网关

官方手册

Quick Start

在 GoAhead Web 服务器中,您可以使用 websUrlHandlerDefine 函数来自定义路由。以下是一个示例

#include 
#include "goahead.h"

// 自定义路由处理函数
static bool myCustomHandler(Webs *wp)
{
    // 处理请求逻辑
    printf("Received request for path: %s\n", wp->path);

    // 发送响应
    websHeader(wp);
    websWrite(wp, "Hello, World!");
    websFooter(wp);

    return true;
}

int main(int argc, char **argv)
{
    // 初始化 GoAhead Web 服务器
    if (websOpen(argc, argv) < 0) {
        fprintf(stderr, "Failed to initialize GoAhead Web Server\n");
        return -1;
    }

    // 定义自定义路由
    websUrlHandlerDefine("/myroute", NULL, WEBS_DEFAULT, myCustomHandler, 0);

    // 启动 Web 服务器
    websListen(NULL);

    // 清理资源
    websClose();

    return 0;
}

分析固件启动的服务

位于liunx目录etc/init.d下为启动脚本,每次系统开始会执行(这也说明路由器的设置出厂模式 其实就是重启了设备而已)

本次固件分析的启动脚本如下

#!/bin/sh

ifconfig lo 127.0.0.1

CINIT=1

hostname rlx-linux

mount -t proc proc /proc
mount -t ramfs ramfs /var
if [ -d "/hw_setting" ];then
    mount -t yaffs2 -o tags-ecc-off -o inband-tags /dev/mtdblock1 /hw_setting
fi

mkdir /var/tmp
mkdir /var/web
mkdir /var/log
mkdir /var/run
mkdir /var/lock
mkdir /var/system
mkdir /var/dnrd
mkdir /var/avahi
mkdir /var/dbus-1
mkdir /var/run/dbus
mkdir /var/lib
mkdir /var/lib/misc
mkdir /var/home
mkdir /var/root
mkdir /var/tmp/net
###for tr069
mkdir /var/cwmp_default
mkdir /var/cwmp_config

if [ ! -f /var/cwmp_default/DefaultCwmpNotify.txt ]; then
  cp -p /etc/DefaultCwmpNotify.txt /var/cwmp_default/DefaultCwmpNotify.txt 2>/dev/null
fi

##For miniigd
mkdir /var/linuxigd
cp /etc/tmp/pics* /var/linuxigd 2>/dev/null

##For pptp
mkdir /var/ppp
mkdir /var/ppp/peers

#smbd
mkdir /var/config
mkdir /var/private
mkdir /var/tmp/usb

#snmpd
mkdir /var/net-snmp

cp /bin/pppoe.sh /var/ppp/true
echo "#!/bin/sh" > /var/ppp/true
#echo "PASS"     >> /var/ppp/true

#for console login
cp /etc/shadow.sample /var/shadow

#for weave
cp /etc/avahi-daemon.conf /var/avahi

#extact web pages
cd /web
#flash extr /web
cd /
 
mkdir -p /var/udhcpc
mkdir -p /var/udhcpd
cp /bin/init.sh /var/udhcpc/eth0.deconfig
echo " " > /var/udhcpc/eth0.deconfig
cp /bin/init.sh /var/udhcpc/eth1.deconfig
echo " " > /var/udhcpc/eth1.deconfig
cp /bin/init.sh /var/udhcpc/br0.deconfig
echo " " > /var/udhcpc/br0.deconfig
cp /bin/init.sh /var/udhcpc/wlan0.deconfig
echo " " > /var/udhcpc/wlan0.deconfig

if [ "$CINIT" = 1 ]; then
startup.sh
fi

# for wapi certs related
mkdir /var/myca
# wapi cert(must done before init.sh)
cp -rf /usr/local/ssl/* /var/myca/ 2>/dev/null
# loadWapiFiles >/dev/null 2>&1
 
# for wireless client mode 802.1x
mkdir /var/1x
cp -rf /usr/1x/* /var/1x/ 2>/dev/null
mkdir /var/open
cp -rf /usr/share/open/* /var/open 2>/dev/null
 
# Start system script
init.sh gw all
 
# modify dst-cache setting
echo "24576" > /proc/sys/net/ipv4/route/max_size
echo "180" > /proc/sys/net/ipv4/route/gc_thresh
echo 20 > /proc/sys/net/ipv4/route/gc_elasticity
# echo 35 > /proc/sys/net/ipv4/route/gc_interval
# echo 60 > /proc/sys/net/ipv4/route/secret_interval
# echo 10 > /proc/sys/net/ipv4/route/gc_timeout
 
# echo "4096" > /proc/sys/net/nf_conntrack_max
echo "12288" > /proc/sys/net/netfilter/nf_conntrack_max
echo "600" > /proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_established
echo "20" > /proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_time_wait
echo "20" > /proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_close
echo "90" > /proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout
echo "120" > /proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout_stream
echo "90" > /proc/sys/net/ipv4/netfilter/ip_conntrack_generic_timeout
# echo "1048576" > /proc/sys/net/ipv4/rt_cache_rebuild_count
echo "32" > /proc/sys/net/netfilter/nf_conntrack_expect_max

# modify IRQ Affinity setting
echo "3" > /proc/irq/33/smp_affinity

#echo 1 > /proc/sys/net/ipv4/ip_forward #don't enable ip_forward before set MASQUERADE
#echo 2048 > /proc/sys/net/core/hot_list_length

# start web server
ls /bin/watchdog > /dev/null && watchdog 1000&
#boa

goahead &

#Turn off the power led of orange
echo "29" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio29/direction
echo "1" > /sys/class/gpio/gpio29/value
#Turn on the power led of green
echo "30" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio30/direction
echo "0" > /sys/class/gpio/gpio30/value

cp /etc/passwd_orig /var/passwd
cp /etc/group_orig /var/group
MODE=`flash get HW_FACTORY_MODE`
if [ "$MODE" = "HW_FACTORY_MODE=1" ];then
telnetd&
fi
speedcheck&

除了一些基本的操作,如创建一些文件夹,写入一些配置项,配置下看门狗

还有重要的是服务器起了goahead服务

固件服务逆向分析

用IDA pro打开goahead服务。

目的—— 信息搜集 收集当前服务的有关接口,查看存在的接口的执行逻辑,是否可利用的参数可利用的方法调用、除此之外搜集接口信息还可以分析前端发出的包。

路由器固件安全漏洞分析——开端入坑_第6张图片

CTRL + E 选择主函数main进入, F5进入伪代码

路由器固件安全漏洞分析——开端入坑_第7张图片

if条件调用了很多函数,猜想这些函数是什么...... 。那一定有绑定服务的函数,建立socket客户端的函数,线程函数......如果这些代码执行错误那这个服务一定不可执行。之后while循环,这一定是阻塞等待客户端的连接,去处理用户的请求。

厂商既然用了goahead这个项目,就大概率配置了自己的接口,我们可以在while循环前,寻找相关信息

进入sub_423F90函数

路由器固件安全漏洞分析——开端入坑_第8张图片

 注意下面类似路径接口的函数

路由器固件安全漏洞分析——开端入坑_第9张图片

和示例中的 定义自定义路由多像啊! websUrlHandlerDefine("/myroute", NULL, WEBS_DEFAULT, myCustomHandler, 0);

根据原理第四个参数就是接口的处理函数,我们追进去sub_42383c

路由器固件安全漏洞分析——开端入坑_第10张图片

一眼望去 有一个很危险的行为 echo '%s' > 之后执行了system,首先这条语句在liunx一定是可以命令注入的,那么后面就是看参数a7是否可控了!

因为是伪代码,对比正向代码示例

// 自定义路由处理函数 static bool myCustomHandler(Webs *wp) {

a1 到 a7 一定是结构体webs的成员,那么a7就大概率是我们可控的参数。

不过执行system前,我们得先进入if条件语句中,判断for 与 if 的逻辑

循环遍历dword_58E084空间,每次循环将地址空间+8个字节,所指向的字符串与a1+1316的空间的字符串做对比,有则进入if执行代码

先看看dword_58E084空间有什么,+8就是一个字符串,+4就是一个函数(后面执行的函数也可判断出)(猜想 这函数一定是对应字符串的函数 的确是)  路由器固件安全漏洞分析——开端入坑_第11张图片

那么a1+1316指向的空间是什么 ?

有些漏洞的发现无需逆向,凭经验与模糊测试就可以挖掘成功。

就像本次的a1+1316的空间 我们无需纠结那么多的细节,我们可以确定的是在路由器登录的时候一定执行了login方法, 那么a1+1316这个空间就一定符合程序预期的。我们前端抓包一探究竟。

登录页面

路由器固件安全漏洞分析——开端入坑_第12张图片

我们请求的url是POST /HNAP1 但最终处理的不一定不是HNAP1。header请求头中有SOAPAction 这个字段,网上收集资料学习下这种技术,最终明白了它强请求数据为什么是xml这种,为什么请求/HNAP 后端却是调用login函数。那么,a1+1316就大概率是SOAPAction 这个值了。  

a7也被传输了相关方法如login,我们就可以大胆的猜测 这个a7就是xml数据 是我们可控的。

此外我们还可以执行命令查看/var/hnaplog 到底被写入了什么作为日志信息,是请求的url还是请求的数据 是请求端的ip 还是请求的ugent

cat /var/hnaplog 将这条命令 在仿真的界面尝试执行(会有很多日志信息输出 手速快点 目前我没有找到一个干净的shell方法 如果有望告知)

 en.....的确是请求的post数据。

接下来我们就可以进行rce执行了 ,(实际测试本次固件无法发起连接请求,所以用写入文件的方法验证此漏洞)

抓包 输入我们的payload (web_mtn目录是web的根目录 在提取文件系统时可以大致判断出来)

`echo 123test > /web_mtn/1.txt` 

路由器固件RCE执行

POST /HNAP1/ HTTP/1.1
Host: 192.168.0.1
Content-Length: 29
Accept: */*
X-Requested-With: XMLHttpRequest
SOAPAction: "http://purenetworks.com/HNAP1/Login"
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36
Content-Type: text/xml; charset=UTF-8
Origin: http://192.168.0.1
Referer: http://192.168.0.1/Login.html
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close

'`echo 123 > /web_mtn/1.txt`'

路由器固件安全漏洞分析——开端入坑_第13张图片

之后访问路径 /1.txt 漏洞复现成功

总结

除此之外本次固件还有一系列的接口未授权,前端登录等同于虚设。除此之外貌似还有一些缓冲区溢出。 可以说是后端写的时非常随意了各种函数滥用,不考虑认证等问题。

其他说明 :本人纯小白,如有分析不对的地方或者有更好的分析方法 望大佬指出。

你可能感兴趣的:(路由器固件安全漏洞分析,智能路由器,安全,c语言,服务器)