审计5 文件包含漏洞
1 <?php 2 require_once('sys/config.php'); 3 require_once('header.php'); 4 ?> 5 <div class="row"> 6 <?php 7 if (isset($_GET['module'])){ 8 include($_GET['module'].'.inc'); 9 // phar:// 10 }else{ 11 ?> 12 <div class="jumbotron" style="text-align: center;"> 13 <h1><b>VAuditDemo</b></h1> 14 <p>一个简单的Web漏洞演练平台</p><br /> 15 </div> 16 <div class="col-lg-12"> 17 <h2>用於演示講解PHP基本漏洞</h2> 18 <p></p> 19 </div> 20 <?php 21 } 22 ?> 23 </div> 24 25 <?php 26 require_once('footer.php'); 27 ?>
在第一节发现了第8行可能存在漏洞,但是并没有利用成功。今天继续研究
再次审计发现这可以利用的有两种方法:
1.00截断 (仅限于php4.3以下版本) 2.php伪协议(phar 关于压缩包的协议)
1 function is_pic( $file_name ) { 2 $extend =explode( "." , $file_name ); 3 $va=count( $extend )-1; 4 if ( $extend[$va]=='jpg' || $extend[$va]=='jpeg' || $extend[$va]=='png' ) { 5 return 1; 6 } 7 else 8 return 0; 9 }
在sys/lib.php中发现文件上传只对文件名的后缀进行了检验。因此感觉利用php伪协议
搜索和文件上传有关的全局变量
1 if (isset($_POST['submit']) && isset($_FILES['upfile'])) { 2 3 if(is_pic($_FILES['upfile']['name'])){ 4 5 $avatar = $uploaddir . '/u_'. time(). '_' . $_FILES['upfile']['name']; 6 7 if (move_uploaded_file($_FILES['upfile']['tmp_name'], $avatar)) { 8 //更新用户信息 9 $query = "UPDATE users SET user_avatar = '$avatar' WHERE user_id = '{$_SESSION['user_id']}'"; 10 mysql_query($query, $conn) or die('update error!'); 11 mysql_close($conn); 12 //刷新缓存 13 $_SESSION['avatar'] = $avatar; 14 header('Location: edit.php'); 15 } 16 else { 17 echo 'upload error<br />'; 18 echo '<a href="edit.php">返回</a>'; 19 } 20 }else{ 21 echo '只能上傳 jpg png gif!<br />'; 22 echo '<a href="edit.php">返回</a>'; 23 } 24 }
发现文件路径的命名规则是 $avatar = $uploaddir . '/u_'. time(). '_' . $_FILES['upfile']['name'];
$uploaddir='../uoloads' 文件头有定义 time() 当前时间的字符串 $_FILES['upfile']['name'] 上传的文件名字
然后搜索 $_SESSION['avatar'] 发现 全文都没有将上传路径输出出来
现在的难点就是不知道time()生成的具体时间
但是可以写脚本,去把response的时间转换成当前时间的字符串,可以在此字符串上下几个试出真实的上传路径。毕竟返回包的时间和上传文件成功的时间差不多。
1 //转换时间格式字符串脚本 2 <?php 3 data_default_timezone_set('UTC'); 4 echo strtotime('待转换的时间字符串'); 5 ?>
源码研究的差不多了,开始构造压缩包
构造一个一句话木马,然后将其名称改为cc.inc (inc的原因是因为首页固定了文件后缀所以要构造成inc)
然后因为要用phar伪协议 (该协议主要是读取压缩包中的文件)
所以要将cc.inc压缩成cc.zip 然后又因为上传文件对文件后缀进行了验证,所以将压缩包后缀改为cc.jpg绕过上传
在用户界面编辑个人资料,上传头像。
截取上传成功后的response数据包:
将Date格式进行转换,用刚写的脚本
转换成功后
和uploads的文件比较
发现只差4位,也就是更换1502547352前5个后5个就基本可以便利到自己真实上传路径。
构造payload:
phar://uploads/u_1502547346_cc.jpg/cc.inc (没有包含.inc 因为 已经有了.inc)
利用成功!