文章总结: 这篇文章详细分析了Iptime路由器固件中的多个安全漏洞,包括未授权访问、未授权修改账号密码和远程调试后门。文章首先介绍了如何获取和分析固件,然后通过IDAPro逆向分析了固件中的cgi文件,发现了认证机制中的逻辑错误。通过分析,作者展示了如何绕过认证机制,实现未授权访问和修改账号密码。此外,文章还发现了一个远程调试后门,攻击者可以通过特定的密钥和命令执行任意系统命令。文章提供了详细的漏洞原理分析、复现步骤和利用方法,对网络安全研究人员和渗透测试人员有较高的参考价值。
综合评分: 85
文章分类: 漏洞分析,渗透测试,固件安全,WEB安全,逆向分析
Iptime漏洞分析,未授权、未授权修改账号密码、远程调试(后门)
原创
朝阳
Sec朝阳
2025年12月6日 18:42
新加坡
一、信息收集
我们拿到手发现熵值有很大变化,我们尝试解包一下。应该是没加密的,我们解包后发现了一个文件系统,我们进去看一下。
1、漏洞信息
未授权远程代码执行
- 由于逻辑错误存在未授权访问漏洞,可以利用该漏洞进行账号密码修改,功能开启,进而进行远程命令执行
- 供应商: ipTIME
- 产品: AX2004M
- 版本: 14.19.0
2、确定架构
这里我们发现是Mips、32位小端架构。
发现了有NX保护,没有栈保护。
二、FirmWare模拟
启动模拟后访问网页看到了这个登录界面。
(1)、查看进程
这里我们能确定是启动了httpd服务。
(2)、分析路由器文件
这里有一个cgibin的文件。
/cgibin目录与路由器相关,他会将Web界面上的操作,例如更改目录、设置网络等转换为实际的系统命令。
我们看到Web页面也发现了几乎所有的功能都在这个路径下,去看一下这个位置。
都会调用这类cgi文件,那这类文件应该就是功能处理的作用了。看一下这个比较河西你懂文件,timepro.cgi,这个文件里面有很多参数,甚至还有system命令。
这个位置很有RCE的嫌疑,我们先去看这个timepro文件,看一下能不能发现什么。
后面再看看这个数据包,还有一个cookie的验证。
(3)、cgi文件分析
这里我们就关注比较核心的cgi文件。
login.cgi, login-cgi 作为请求登录请求
sys_apply.cgi 应用系统设置,重启、时间等,可能会存在很多system()或execve()
net_apply.cgi 网络设置、子网掩码、静态路由等,可能出现ipconfig、route等命令
wireless_apply.cgi 应用无线设置(SSID、密码、加密类型)
download.cgi, download_...cgi 提供下载功能,可能有任意文件读取、目录遍历
比较重要的应该是timepro.cgi,因为我们之前的请求
/sess-bin/timepro.cgi?tmenu=system&smenu=info
就是通过这个文件进行的,很大概率会有漏洞。
(4)、IDA分析,未授权访问
根据漏洞作者披露,该路由器固件在验证身份验证时存在逻辑错误,漏洞点在ftext函数。
我们根据提示说有验证身份时存在逻辑错误,在ftext函数,找到这个函数看看。
我们逐行分析这个函数作用以及谁调用它
一开始会去做一共session验证,然后又在下面做了一共检查csrf攻击的检查。
然后下面
我们看下这一段,是对POST请求做一个处理,他会经过一个get_value_post函数,就是获取我们提交的命令commit,然后经过一个commit_process函数,else下面又是获取我们的commit,再往下走又出现一个goto LABEL_46,大概率是判断我们输入的值是否为空 。
接下来我们看下commit_process函数是怎么处理的命令。
我们能看到,我们输入的commit会当作a3进入到下面的if中,分析一下这几个函数的作用。
commit_current_wireless(a1) ,无线配置提交,负责WI-FI名称、密码之类的,可能调用iwconfig,有RCE风险。
commit_pf_restore(a1, a2) ,端口转发函数。
commit_fw_restore(a1, a2) 防火墙恢复、 commit_vpncli_file_upload(a1, a2) VPN客户端文件上传。
我们再往下分析,这一大段伪代码用于认证检验、还是一个请求分配中心,负责处理Web界面的大部分操作。
看下第二个判断的函数,这里是两个参数,会获取我们的session和Cookie,来进行一个判断。
这一段,比对session和v9,检查Web服务器是否配置使用session认证,认证机制不是session函数返回1。
检查用户是否已登录的核心逻辑,说先获取COOKIE头部,通过 extract_session_id_from_cookie(v5, v8) 从COOKIE中解析出Session ID, check_session(“httpcon”, v8, v4) 比对服务器的Session列表中检查ID是否有效。
所有结果都成立,Session有效情况下,进入if,最终返回1认证成功,如果认证失败则走下面的else if。
就是这个redirect_login函数
这里负责未通过认证的用户重定向登录页面。
现在后面的我们了解了逻辑来看前面的函数
这里就是检查URL是否检查以/sess-bin/开头,是的话返回True,不是的话返回False。
(5)、漏洞链分析
因此我们就能得出两条路来进行未授权和远程调试的后门。
if ( httpcon_check_session_url() && !httpcon_auth(1, 1) )
return 0;
远程调试(后门链)
当我们再次回归这里,第一条链。
攻击路径/cgi/d.cgi,整条条件不成立,执行到包含后门的代码块。
( httpcon_check_session_url() && !httpcon_auth(1, 1) )
False && True
这条链我们不需要删除Cookie,这样逻辑最终返回错误。
因为这条链的逻辑是两个条件都为True才会返回0,终止这条链。
因此我们只需要任意一条为0即可。
未授权操作(未授权链)
( httpcon_check_session_url() && !httpcon_auth(1, 1) )
True && False
走这条链时,我们需要删除Cookie才不会终止程序,然后左边路径要正确。
三、回归身份验证逻辑函数
我们分析这一大段伪代码,我们关键分析点应该检擦绕过httpcon_auth,是这样的,漏洞点在于未授权,那我们就应该想办法绕过这个鉴权机制,然后就能访问里面的文件了,所有回归鉴权函数。
e_log_init("cgi.timepro", a2, a3);
if ( httpcon_check_session_url() && !httpcon_auth(1, 1) )
return 0;
httpcon_check_session_url() == 1(会话有效)且httpcon_auth(1, 1) == 0(认证失败),条件成立,return 0 ,无法进行后续操作。httpcon_check_session_url() == 1(会话有效)且httpcon_auth(1, 1) == 1(认证成功),条件不成立,可以进行后续操作。
含义就是我们要让前面函数为1并且后面函数为1。
对于未授权用户来说的话,!httpcon_auth(1, 1)应该始终为1,我们需要让前面函数返回0
我们去找一下这个函数位置。
这个函数是用到外部库,我们分析一下这个库。用IDA打开后搜索这个函数。
我们找到了这个函数,简单分析一下,他会读取我们请求的URL,然后做一个判断,不为空会执行右边的操作。
这个函数的目标就是需要认证的页面(如/sess-bin/)返回1,阻止访问,不需要认证的页面,返回0,实现绕过。那我们要做的就是不能以/sess-bin/开头。
那接下来就很简单了,我们只需要把sess-bin改成其他文件路径就可以任意访问了呗。
四、未授权漏洞/未授权修改账号密码复现
1、未授权
我们把Cookie删除,然后退出登录,再次尝试。
未授权访问成功。
2、未授权修改账户密码
这里我们在修改账号密码位置抓包。
成功修改密码
captcha_file(验证码路径)
captcha_code(验证码)
new_passwd(新密码)
new_login(新用户名)
我们想获取这个验证码就去/sess-bin/captcha.cgi下面找,会访问这个路径生成验证码。
3、远程调试
开启了远程调试功能,我们去看看数据包
抓包后看一下信息
这一行就是他的调用方式了,我们找找这个服务,远程支持。
能发现很多这个服务,我们看下这些函数。
在这个函数中发现了有remtesupport字样,看着像一个表单,我们分析这个函数功能。
这个函数就是一个生成html的表单,用于创建用户界面的,我们要找这个远程支持的功能点或者函数。
我们就看谁调用了这个远程支持的函数,先看这个函数。这个函数
首先看这一段,就是调用get_remote_support()函数,把结果放进去,然后检查默认密码。
回归之前的绕过,这段代码就是获取系统配置中远程支持的状态,然后查看远程支持是否开启。
来看这一段,这里就是如果没忍住跳转到LABEL_51,如果认证了会获取aaksjdkfj值,然后检查这个值是否匹配一个字符串。
看着一段,如果设置了fdump=on则程序会读取用户输入的rname参数作为文件名。
这里输入是程序调用get_value(a1,”cmd”,…)获取用户输入的cmd参数,把他拼接到v20后面,然后调用popen(v20,”r”)执行。这里好像是通过后门钥匙就能提交cmd=[shell],一会儿尝试一下。
那其实就是说我们可以通过URL或POST数据包提交一个名为cmd的参数,他会存入v20中并且调用popen,或许可以尝试构造一下。
其实这里相当于构造一个密钥,把他转换一下就是 !@dnjsrurelqjrm*& ,这个应该就是密钥了。
那我们应该是只需要输入密钥和指令应该就行进行命令执行了。
构造成功。
如果想找到这个后门就需要到这个函数中,这里有解释。
这段代码做了三件事,确认参数名称,确认了参数就是 aaksjdkfj ,确认渲染方式,这是一个字段,这意味着他会在调试界面的文本框里,确认默认值,格式字符串中%s对应遍历就是v8。
并且在上面提到了提交的方法,是\d.cgi\
这段会确定我们没有提交了aaksjdbfj参数,那么v8的值就是空的,就是strcpy(v8,””),空字符串
如果提交了aaksjdkfj那么v8就是我们提交的密钥字符串,也就是有这个参数才能进入后门页面。
当我们调试时,URL没有携带密钥,渲染的文本框是空,提交了文本框才会回显密钥。
over。
漏洞原理:
第一步,就是认证机制绕过。这个漏洞是故意让认证失败来实现的。/sess-bin/d.cgi,认证条件是
if ( httpcon_check_session_url() && !httpcon_auth(1, 1) ) ,利用条件就是攻击者不提供有效Cookie。
如果httpcon_auth(1, 1)失败会返回0,也就是没有Cookie的情况下,但是前面有一个!符号,也就是说只有不带Cookie他才会返回1嘛,因为在这个函数内的逻辑是有session返回1,没有session返回0,我们就让他返回0,然后加上前面的!符号,就绕过去了,所以我们想绕过去就不能带Cookie。这样后面的函数就永为1,也就是True。
条件成立后会往下走,在认证失败后触发隐藏代码中的后门。
而且我们在ftext函数中发现了后门的踪迹,如果调用了这个d.cgi文件,他会检查cgi脚本的路径,路径匹配后会进入到show_debug_screen函数中再次进行判断,它会调用我们之前发现包含 aaksjdkfj 后门的密钥检查和cmd命令诸如函数。
也就是进入这里,访问了这个路径后检查我们的参数是否为这个密码
都通过了就进入到这个后门了,也就打开了。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:Sec朝阳 朝阳《Iptime漏洞分析,未授权、未授权修改账号密码、远程调试(后门)》