前言
迫不及待要找个靶场实践了,抓紧把剩下的两种概念捋一捋。
任意文件上传
上传漏洞本质是
- 可以上传任意类型文件
- 可以远程执行或利用被上传的文件发起进一步攻击
缺一不可。
能上传不能利用的情况:
举例来说,业务代码里没检查上传文件的 mimetype,你传了一个包含恶意代码的文件I_am_hacker_hahaha.php上传到了服务器上,但服务端是一个独立 Go 程序,没有 httpd也没有nginx,那任你传什么恶意脚本都没用——根本不会去执行你的代码。
能利用但没法上传的情况:
比如过滤很完善,会检查文件头的 Magic 之类的。还有一种是服务端用了对象存储服务。阿里云 OSS ,腾讯云 OSS,七牛云。虽然服务器配的是 httpd+php 的经典组合,文件名解析漏洞也没补,但上传的文件根本没放服务器上也不行(emm,没依据,不过要是能执行别的服务器上的代码的话就是远程代码执行的大洞了吧)。
所以要利用的话,应该要求是:
- 用了 CGI这样的协议,传上去的东西有机会被执行。
- 用了动态特性比较强的语言,从 php、python到java都有运行时加载代码的能力。php 不多说,即使静态编译的语言如Java,也有像近期闹得比较大的 Log4J 漏洞,就是利用了运行时加载新代码的能力。更进一步如Go、C/C++运行时加载代码就要靠共享库dlopen之类的方法了,用得不多雷也不多。PS:LD_PRELOAD这里认为不是 运行时 加载代码的方法。
- 有其他被执行的机会,比如能写到 cron.d这样的位置,或者有其他可以结合利用的洞,比如有机会控制命令执行时的环境变量,加上任意文件上传,也能利用LD_PRELOAD之类的方式把上传的 payload 跑起来。
总的来说,未经检查和约束的文件上传接口总是危险的。现在没爆雷,将来某天也可能会爆。
远程代码执行
命令执行
也好理解,和 SQL 注入是比较类似的。如果服务端有这样的代码system("ffmpeg -i /tmp/" + $_REQUEST["filename"]),那控制了filename就能让system去执行任意命令。
比如传一个 filename=|| touch hello,整条命令就变成了 ffmpeg -i /tmp/|| touch hello,|| 或运算连接前后两条命令都会被执行。有Linux环境可以自己试试false||id看看id命令会不会跑起来。
代码执行
代码执行是个很宽泛的概念,因为可以执行的东西太多了。
从最最最底层的,利用栈溢出漏洞覆盖返回地址,让进程执行自己期望的代码,到很上层的,利用eval这样的函数(在php、nodejs、python环境里都有)执行远程代码。
还有如dlopen、java的动态类加载等等,解释执行的语言还可以include或import、require新的代码,等等这些函数的参数如果被用户输入控制的话都会构成远程代码执行的危险。
总结
其实没什么好总结的,都是些概念性的东西,没有干货。