前言
从nameless师兄那里借来了TOTOLINK T6设备,当作入门IoT漏洞挖掘研究的起点
开始
固件 -> telnet -> busybox -> 固件
串口调试这一步我暂时还没做。直接从固件开始做起
在TOTOLINK的官网可以直接下载到T6/T10的固件
binwalk解包一下得到一个.web.extract文件夹
发现webscte文件夹,进去看到telnet.html
直接访问ip/telnet.html
可以看到telnet的开关,把它打开
终端telnet连接一下
需要用户名,直接使用root,登录需要密码
这里需要从固件里reverse得到密码
先分析启动文件rcS,寻找password相关指令,看到这个
看到使用的是cs指令,需要在squashfs文件里寻找这个指令的实现
使用find ./ -name "cs"
然后可以ida逆这个文件,可以很容易找到password
然后就可以通过telnet连接,获取到路由器本身的shell,但是很丑陋,而且没有路径显示
到这已经可以执行一些指令比如ps这些
下一步可以考虑塞一个busybox进去,busybox是开源的,但是可以直接在网上找到mipsel架构的已编译busybox-mipsel
具体方法是在本机文件夹起一个http server,在路由器的shell里使用wget指令获取
然后可以先执行busybox看看它的内部applet
先加个权限chmod +x busybox-mipsel
执行./busybox-mipsel sh
就可以使用busybox的shell
在这之后再亲自提取一次固件
首先查看/proc/cmdline “/proc/cmdline是载入 kernel 时所下达的相关指令与参数,查阅此文件,可了解指令是如何启动的”
这里可以看到串口调试的波特率是38400(在串口调试的时候会要求输入),固件是在/dev/mtdblock1这个目录
这里使用dd指令把这个固件文件也提取到/tmp目录
然后翻了一遍busybox的指令,看到有ftpget ftpput这些的指令
似乎并不能通过起web服务传到本机,这里使用ftpput,在本机开一个ftpserver,给上传和下载文件的权限,然后指定接受目录
在路由器的shell里执行./busybox-mipsel ftpput -P 21 192.168.55.2 ./mtdblock1
就可以通过ftp传到本机
然后就提取到了固件。
虽然说从固件入手再提取固件有点多此一举,但是这也是流程里比较重要的一步。
一些额外的探索,仅用于个人学习研究
写入mipsel-linux-gnu-gcc编译的程序
首先sudo apt install mipsel-linux-gnu-gcc
下载mipsel编译器
然后自己写一个有点意思的程序
1 |
|
编译mipsel-linux-gnu-gcc <file name> -static
,就得到了一个mipsel架构的静态链接的可执行程序
注意因为要写进路由器,所以应该采取静态链接
写入路由器的方法也和传入busybox-mipsel的做法一样使用wget就可以
这以后是不是可以做到一些比较有意思的事呢~~(狗头)
同理也可以写入自己编译的busybox
试着打打!
有了上述固件telnet漏洞的研究,我们尝试对其加以利用。(仅作学习,不干坏事)
先尝试往我们自己的路由器ip发一个请求
回显是这样,我们可以选择一些响应的值作为特征,去shodan查找有此特征的ip
然后找到了两个都是T6型号的网友,其中一个可以访问到
我们直接访问/telnet.html
虽然telnet.html页面需要登录,但这个后台cgi接口不
需要cookie仍然能成功开启telnet
web佬可能会选择使用抓包工具抓包或者python request发请求,pwn手可能会用命令行curl发送bash格式的请求
这里我拿自己的内网ip做演示,利用curl发bash格式的post请求开启telnet,避免一些暴露人家的信息
这样会回显success,也就是成功通过后台cgi接口发请求开启telnet
很可惜的是这位用户开启了防火墙,不能玩更深入的东西(x
最后再发一个请求关闭这位用户的telnet。(做一个守法黑客)
物理提取
深入 追寻telnet的实现
在传入busybox以后,我们还可以利用netstat -pantu
指令查看端口和tcp udp的连接
看到我们80端口的进程是lighttpd,同时还注意到1883端口有cs_broker,说明可能还有mqtt。
同时我们知道后台用于处理请求的cgi文件是cstecgi.cgi,那么我们是不是可以寻找这个进程和cgi之间的关系
ida打开cstecgi.cgi文件,看到在main函数开始时调用了getenv()函数调用环境变量
然后查找一下环境字符串还在什么地方出现
看到在lighttp/lib/mod_cgi.so这个文件里也出现了,之后再看一下这个mod_cgi.so文件
没有main函数,直接字符串搜索query_strings
找到对应函数
在这个函数的底下看到使用execve传参和执行进程
我们接着grep一下lighttpd看进程,看到进程id是1709,然后去/proc/1709查看maps内存分布,看到他的一些链接文件,其中有mod_cgi.so
到这里我们可以理清楚了cstecgi.cgi作为lighttpd的子进程而存在,由lighttpd进程中的动态链接库mod_cgi.so启动,
接下来直接在cstecgi.cgi文件里找"telnet"
找到这个位置
这个位置需要在addiu esp(抬栈的位置)create function,快捷键是p,然后就可以f5反编译
看到调用的是__imp_safe_cs_pub,以及传参,第一个参数是ip,第二个参数是SetTelnetCFg字符串
直接再grep safe_cs_pub
去对应的链接文件libmystdlib.so找这个函数
可以看到对应的端口是1883
去对应目录直接执行cste_pub
看到有意思的东西:mosquitto
发现是一个mqtt的客户端,那么这个路由器还存在mqtt协议的使用
接着去找使用了这个协议的1883端口
先在linux终端里面nmap扫一下发现确实是mqtt
同时在shell里看到1883端口是由PID为1698的cs_broker进程和1699的cste_sub监听
可是到这两个关联的程序里寻找telnet字符串都没有结果
回头去看我们发的请求,body部分的变量名是telnet_enabled。
那么如果在squashfs-root目录下全局搜索这个字符串,总应该能找到东西
冲wireless.so试试
在ida里直接搜telnet_enabled字符串,找到这个函数
找到了我们前面看到过的SetTelnetCfg函数,也看到了开启telnet的函数system(“telnetd &”);
但我们前面在找进程的时候没看见wireless.so这个链接库的存在呀,它又是被谁加载了呢?
直接搜wirless.so,找不到任何文件
再找他的目录cste_modules,找到了调用这个目录的程序cste_sub(眼熟吗?)
ida打开这个程序搜索cste_momdules,找到这个程序
看到load_modules函数调用了load_plugin函数来加载cste_modules目录下的所有链接文件,这里单指wireless.so
至此,我们追寻完毕了telnet的开启过程,这一路上发现了一连串相关的进程,也找到了新的利用点
理一遍我们这一路的顺序:
发送请求:{‘telnet_enabled’:‘1’} --> 80端口 --> lighttpd进程 --> mod_cgi.so程序 --> lighttpd子进程cstecgi.cgi --> 链接文件libmystdlib.so --> cste_pub函数 --> cs_broker监听 --> cste_sub处理 --> load_plugin加载cste_modules目录 --> wireless.so程序真正调用system函数开启telnet
我学到了dlopen的加载方式,也就是通过目录加载.so链接文件,这里函数是load_plugin
再深入 遇见更多利用
(待更新)
如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !