文件下载原理
了解任意文件下载漏洞,首先要知道用户从服务器下载文件的方式是什么。对于网站的文件下载,有两种方式,一种是直连下载,另一种是非直连下载。
直连下载
直连下载:用户通过访问服务器系统目录文件直接下载文件。
url:www.oops.com/soft/1.zip
当前目录有这个文件,且浏览器不认识zip,无法解析,所以会下载这个文件。但是当访问www.oops.com/soft/index.php 时, 浏览器认识php文件,会继续解析,而不会下载。
这种方式一般不会有安全问题。
非直连下载
非直连下载:后端代码中用下载协议去解析文件。
url:www.oops.com/down?file=1.zip
非直连中将下载的文件名或者相关信息通过参数传入,后端代码进行处理,实现下载。
这种方式可能存在安全问题。
漏洞成因
1.由于没有对用户输入的文件名进行过滤,而造成用户输入的文件名可以通过../实现路径穿越来访问其他目录下的文件并下载
2.另一种情况就是传入的是参数值进行下载,例如?id=3,服务器会通过这个参数去通过数据库寻找到某一行,通过该行元素中的其中一列来找到下载文件的地址,如果用户可以通过其他功能实现对数据库操作,写入恶意路径,那么就可以实现任意文件下载。
利用方式
- 下载网站源码
- 下载系统敏感文件,例如etc/passwd
- 下载数据库配置文件,获取数据库权限
黑盒测试
在黑盒测试下,主要通过功能点和url特征来进行发现此漏洞,一般发现此漏洞要按照两个步骤,第一步是寻找下载功能,第二步是对下载功能的url进行分析。若url为直连下载,一般没有漏洞,若为非直连下载,则可能存在漏洞。
1.下载功能分析
2.URL分析
测试技巧
- 路径穿越下载任意文件
/download.php?filename=../../../../../etc/passwd
-
路径穿越+截断:当代码中固定文件后缀名时,可以使用\0字符来截断后缀名
/download.php?filename=../../../../../etc/passwd%00
白盒测试
- 文件下载功能没有特定的函数,在白盒挖掘此漏洞时,不建议从关键函数出发,比较好的思路是从功能点出发抓包,定位代码段进行分析,下面的函数均可以实现文件下载的效果
file_get_contents()
readfile()
......
- 文件下载-白盒测试流程
功能点抓包--寻找代码文件--寻找变量控制--构造payload测试
案例1-src实战
- 发现上传头像功能,一开始打算测试是否可以直接上传webshell,发现不行
- 复制图片连接,想看看文件路径,但是复制地址链接访问后会直接下载此文件
- 对URL进行分析,path参数传入如下
path=JTJGMjAyMyUyRjEyJTJGMTMlMkY1MGQxYjJlMThmMzM0ZmU2YjBlY2ZmMDY1M2VkYzEwYS5wbmc=
- 明显base64加密,尝试解密,发现出端倪
- 构造恶意payload测试,并用base64加密
../../../../etc/passwd
-
将加密结果作为参数值传入,成功下载/etc/passwd文件
案例2-白盒审计
此案例的意义在于下面两点:
1.重在理解文件下载功能的另一种代码实现逻辑:先通过传入一个参数值,定位到数据库,在数据库中取出文件路径,最后再去下载此文件。
2.如何通过下载功能抓包,定位文件代码段,并对代码进行分析绕过等操作。
案例源码
- phpearmusic
分析流程
- 从功能点出发抓包定位代码段,寻找文件下载功能点,如下:
-
通过点击下载时产生的数据包进行对代码段的定位:定位到audio.php?id=1
-
定位代码段如下:对此部分代码分析如下
1.首先传入值为id,通过id去数据库查询了一条sql语句得到了一行数据。
2.下面的一些if else判断似乎是对身份信息的验证,进行页面的跳转。
-
下面这部分代码则为下载文件的代码:分析如下
1,首先是调用geturl(),参数传入为sql搜索的得到某一列元素。
2.然后继续向下分析,可以看到调用readfile()函数。说明此段代码为下载功能 readfile()函数功能为读取一个文件,并写入到输出缓冲区中。
3.但是这个下载的路径$file是在geturl()这个函数得到的,继续追踪。
-
代码如下:通过其代码可以确定,该函数用来得到下载路径,其传入的参数决定了下载路径。那么这个传入路径是通过数据库中的值得到的。如果数据库中的值可以通过我们自定义,那么就可以实现任意文件下载。
-
对这个传入的参数进行分析,追溯数据库中的music表,观察该列元素,如下:可以看到下载的路径为in_audio这个字段决定
-
追溯代码段,看是否存在可以自定义in_audio这一列的功能:发现似乎存在前端代码可以控制这一字段
-
追溯代码如下:上传音频处存在可控制此字段,追溯功能
-
将代码段对应到功能段
-
在对应标签in_audio处进行填写,并观察数据库,发现成功可以外部控制此字段
-
写入恶意路径----如何知道他访问的路径在哪里?
随便输入,动态调式dbug,看$file的值是多少,通过动态调试发现,输入为xxs,则$file也为xxs。因此尝试输入绝对路径进行文件下载。
-
访问这个文件,发现数据库中内容不一致,考虑可能存在过滤
-
上述情况结果分析:似乎确实存在过滤
-
考虑追溯这段内容发送给了哪个数据包进行处理,但是如何判断此段内容走向?
-
答:可以通过抓取提交此段信息是的数据包,从而定位这段内容交给了谁?定位代码段
-
追溯代码段:/source/user/music/ajax.php?,发现接收之前有checkname()函数
-
追溯查看:发现存在正则过滤,反斜杠\被过滤了
-
通过绝对路径/,进行下载
-
点击下载,成功下载
思路总结
- 关键函数中没下载文件的函数,因此通过下载的功能点分析,找到下载地址
- 点击下载,通过产生的数据包,找到对应代码块
- 分析代码得到:文件下载路径由$file控制
- $file是由数据库中的字段得到,追溯该字段查看
- 发现该字段可以通过外部输入来控制,找到该输入处,构造恶意攻击
- 发现失败,再对输入处进行抓包分析,找到代码段
- 发现此代码对\进行了过滤,那么考虑绕过,构造绝对路径利用/构造,成功攻击。