|
凌晨三点,跪求漏洞我盯着屏幕上的跪求漏洞报错信息,第17次把同一段payload粘进测试环境。跪求漏洞服务器返回500,跪求漏洞意料之中。跪求漏洞但这次响应体里多了一行堆栈跟踪——`at com.xxx.util.FileUtil.upload(FileUtil.java:47)`。跪求漏洞我愣了一下,跪求漏洞然后笑了。跪求漏洞这年头,跪求漏洞连漏洞都学会钓鱼了。跪求漏洞 事情得从两周前说起。跪求漏洞甲方甩过来一个CMS,跪求漏洞说“随便测测,跪求漏洞下周交报告”。跪求漏洞我打开首页,跪求漏洞后台路径没改,admin/admin直接进。上传点倒是藏得挺深,在文章附件功能里。试了jpg、png,全被重命名成时间戳加随机数。改Content-Type?没用。加`.php`后缀?被过滤。双写`pphphp`?还是被拦。我甚至试了`%00`截断,服务器直接400。 按理说这时候该上burp跑字典了。但那天我偏不想。我盯着上传按钮旁边那个“从URL获取图片”的输入框,突然想看看它怎么处理远程文件。填了个`http://127.0.0.1:8080/test.jpg`,抓包。请求里除了url参数,还带了个`filename=test.jpg`。我把filename改成`test.php`,url指向我vps上那个伪装成jpg的webshell。发送。 返回200。文件列表里多了一个`test.php`,大小和我的shell一模一样。点开,密码正确。整个过程没有绕WAF,没有编码混淆,就是改了个参数名。后来看代码,`filename`参数直接拼进了保存路径,而`url`参数只用来下载内容。开发觉得“反正文件内容是我从远程拉的,你改文件名能怎样”。他没想到有人会传个php进去。 这事让我想起去年另一个项目。某OA系统,上传接口把文件名做了md5,后缀白名单校验。看起来无懈可击。但我在`/tmp`目录下发现了一堆临时文件,命名规则是`md5(原文件名)_时间戳.后缀`。上传时先写临时文件,再move到目标目录。问题出在move之前——有个短暂的窗口期,临时文件是可访问的。我写了个脚本,上传100个文件,同时用100个线程去猜临时文件名。猜中了一个,里面是我传的jpg。但jpg里嵌了php代码,配合那个OA自带的`.htaccess`解析漏洞,直接getshell。 说回开头那个堆栈。我顺着FileUtil.java:47往上翻,发现上传逻辑调用了`getOriginalFilename()`,然后`new File(uploadPath + filename)`。没有`getCanonicalPath()`校验,没有`..`过滤。我传了个`../../../../../../tmp/test.jsp`,服务器把文件写到了系统临时目录。但tomcat没权限访问那里,所以500。可堆栈暴露了绝对路径,我顺着路径找到了webapps下的另一个应用,那个应用的上传点连后缀都不校验。 漏洞这东西,有时候像捉迷藏。你按标准流程走,它藏得严严实实。你换个角度,它自己就撞上来了。我见过最离谱的一个,后台登录框输入`admin' or 1=1--`直接进,但开发把单引号转义了。我试了`admin' or '1'='1`,还是不行。最后发现用户名做了trim,但密码字段没做。密码框填`' or 1=1--`,进去了。 写报告的时候,甲方问我:“你怎么找到的?”我说:“猜的。”他以为我在开玩笑。其实不是。漏洞挖掘到最后,就是猜开发在哪偷了懒。那个`filename`参数,那个临时文件窗口,那个密码框的trim,都是偷懒的证据。工具能扫出来的叫漏洞,扫不出来的叫人性。 现在那个CMS的补丁已经发了。更新日志里写着“修复文件上传逻辑”。我看了眼diff,他们把`filename`参数删了。但`url`参数还在,还是没做SSRF过滤。不过这不归我管了。报告交了,钱到账,下一个目标已经躺在收藏夹里。凌晨三点半,我关掉终端,窗外有只猫在叫。我突然想,它是不是也在找什么漏洞——比如,哪扇窗没关严。 |