当前位置: 首页 > news >正文

DVWA靶场通关笔记-命令执行(Impossible级别)

目录

一、查看源码

二、功能分析

三、命令执行分析

1、CSRF令牌验证机制

2、输入清理与规范化处理

3、结构化输入验证体系

4、操作系统自适应命令构造


本系列为通过《DVWA靶场通关笔记》的命令执行关卡(low,medium,high,impossible共4关)渗透集合,通过对相应关卡源码的代码审计找到讲解渗透原理并进行渗透实践,本文为命令执行impossible关卡的原理分析部分,讲解相对于low、medium和high级别,为何对其进行渗透测试是Impossible的。

一、查看源码

进入DVWA靶场命令执行的源码目录,找到impossible.php源码,分析其为何能让这一关卡名为不可能实现命令执行渗透。

打开impossible.php文件,对其进行代码审计,代码的处理流程如下所示。

  • 检查是否点击了Submit按钮

  • 验证CSRF token

  • 获取并清理用户输入的IP地址

  • 将IP拆分为4个部分进行数字验证

  • 根据操作系统(Windows/*nix)执行不同的ping命令

  • 输出命令结果或错误信息

  • 生成新的CSRF token用于下一次请求

详细注释的impossible.php源码如下所示,实现了一个简单的IP ping功能,并包含了安全防护措施。

<?php
// 检查是否通过 POST 方法提交了名为 'Submit' 的表单数据
if( isset( $_POST[ 'Submit' ]  ) ) {// 检查 Anti - CSRF(跨站请求伪造)令牌// 调用 checkToken 函数,传入用户请求中的 'user_token'、会话中的 'session_token' 以及跳转页面 'index.php'// 目的是验证请求的合法性,防止跨站请求伪造攻击checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );// 从 $_REQUEST 超全局数组中获取用户输入的 'ip' 参数值$target = $_REQUEST[ 'ip' ];// 使用 stripslashes 函数去除 $target 字符串中的反斜杠转义字符$target = stripslashes( $target );// 将输入的 IP 地址按点号(.)分割成四个部分,存储在数组 $octet 中$octet = explode( ".", $target );// 检查分割后的数组中的每个元素是否为数字,并且数组元素数量是否为 4// is_numeric 函数用于判断一个变量是否为数字或数字字符串if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {// 如果四个部分都是数字且元素数量为 4,将 IP 地址重新组合成原始格式$target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];// 通过 php_uname('s') 获取当前操作系统的名称// stristr 函数进行不区分大小写的字符串搜索,判断是否为 Windows NT 系统if( stristr( php_uname( 's' ), 'Windows NT' ) ) {// 如果是 Windows 系统,使用 shell_exec 函数执行 ping 命令,将 $target 作为目标 IP 地址// shell_exec 函数用于执行系统命令,并返回命令的输出结果$cmd = shell_exec( 'ping  ' . $target );}else {// 如果是类 Unix 系统(如 Linux、macOS 等)// 使用 shell_exec 函数执行 ping 命令,并指定发送 4 个 ICMP 数据包$cmd = shell_exec( 'ping  -c 4 ' . $target );}// 将命令执行结果以 HTML 预格式化文本(<pre> 标签)的形式添加到 $html 变量中// 以便在页面上格式化显示命令执行结果$html .= "<pre>{$cmd}</pre>";}else {// 如果输入的 IP 地址格式不符合要求,给用户提示错误信息$html .= '<pre>ERROR: You have entered an invalid IP.</pre>';}
}
// 生成 Anti - CSRF 令牌, 调用 generateSessionToken 函数为当前会话生成一个新的 CSRF 令牌
generateSessionToken();
?>

二、功能分析

这段 PHP 代码实现了一个带有 CSRF 防护的 IP 地址 ping 功能:通过POST请求接收用户输入的IP地址,首先进行CSRF令牌验证防止跨站请求伪造,然后对输入进行格式检查确保其为4段数字组成的合法IPv4地址,接着根据服务器操作系统(Windows或Linux/Unix)执行相应的ping命令,最后将命令执行结果返回给用户。代码包含了输入清理、令牌验证和操作系统适配等安全措施,提供了一个基本的网络诊断工具界面。

  • CSRF 防护:当用户提交表单时,首先检查 Anti - CSRF 令牌,确保请求是合法的,防止跨站请求伪造攻击。
  • IP 地址处理:获取用户输入的 IP 地址,去除反斜杠转义字符,然后将其按点号分割成四个部分。
  • IP 地址验证:检查分割后的每个部分是否为数字,并且元素数量是否为 4。如果验证通过,重新组合 IP 地址。
  • 执行 ping 命令:根据当前服务器的操作系统类型(Windows 或类 Unix 系统)执行相应的 ping 命令,并将结果以格式化的形式显示在页面上。
  • 错误处理:如果输入的 IP 地址格式不符合要求,给用户显示错误提示信息。
  • 生成 CSRF 令牌:无论请求是否成功,都会为当前会话生成一个新的 CSRF 令牌

三、命令执行分析

代码中使用了如下四种方法进行防御,具体如下所示。

  • CSRF令牌验证机制
  • 输入清理与规范化处理
  • 结构化输入验证体系
  • 操作系统自适应命令构造

1、CSRF令牌验证机制

该机制通过对比用户提交令牌与服务器会话令牌来防御CSRF攻击。generateSessionToken()使用加密安全随机数生成32字节令牌,确保不可预测性;checkToken()严格验证令牌匹配性,失败则重定向到首页终止操作。这种双令牌验证方式有效阻止攻击者伪造请求,保护表单提交的安全性,是Web应用程序的基础防护层。

// 生成并存储会话令牌
function generateSessionToken() {$_SESSION['session_token'] = bin2hex(random_bytes(32));
}// 验证令牌有效性
checkToken($_REQUEST['user_token'], $_SESSION['session_token'], 'index.php');

2、输入清理与规范化处理

stripslashes()函数移除用户输入中的反斜杠字符,防止魔术引号或手动转义导致的异常解析。该处理能有效防御基础注入攻击,特别是当配置启用magic_quotes_gpc时,可避免转义字符破坏数据完整性。虽然现代PHP版本已弃用魔术引号,但此操作仍作为深度防御策略,确保输入数据规范化,为后续验证提供清洁数据源。

$target = $_REQUEST['ip'];
$target = stripslashes($target);

3、结构化输入验证体系

本部分将IP地址分解为四个字节段,分别检验是否为数字且总段数为4,确保符合IPv4格式标准。is_numeric()检查防止非数字字符注入,sizeof()验证防止段数篡改。这种白名单验证方式彻底杜绝了命令注入可能性,仅允许合规IP地址进入执行流程,是输入验证的最佳实践范例。

  • 将IP地址分解为4段:使用 explode() 函数将输入的 IP 地址按点号(.)进行分割,将分割后的每个部分存储在数组 $octet 中。因为标准的 IPv4 地址由四个以点号分隔的数字段(也称为 “八位组”)组成,这样分割便于后续对每个部分进行检查。
  • 检查每个八位组是否为数字:使用 is_numeric() 函数分别检查数组 $octet 中的四个元素是否为数字。该函数会判断一个变量是否为数字或者可以转换为数字的字符串。
  • 检查八位组数量:使用 sizeof() 函数检查数组 $octet 的元素数量是否为 4。因为合法的 IPv4 地址必须由四个八位组组成。
  • 合法性判断:如果上述两个条件都满足,说明输入的字符串在格式上符合 IPv4 地址的基本要求,程序会继续执行后续的 ping 命令;否则,会给用户显示错误提示信息,指出输入的 IP 地址无效。
$octet = explode(".", $target);
if( (is_numeric($octet[0])) && (is_numeric($octet[1])) && (is_numeric($octet[2])) && (is_numeric($octet[3])) && (sizeof($octet) == 4) ) {$target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];
}

举例,假设攻击payload为127.0.0.1; cat /etc/passwd,防御机制工作流程如下所示。

  • 输入接收:$target = "127.0.0.1; cat /etc/passwd"

  • 分割验证:$octet = explode(".", $target) → 得到 ["127", "0", "0", "1; cat /etc/passwd"]

  • 数字验证:is_numeric($octet[3]) → 检测到 "1; cat /etc/passwd" 包含非数字字符

  • 防御成功: 返回错误"ERROR: You have entered an invalid IP.",命令未执行

4、操作系统自适应命令构造

本部分代码在low级别、medium级别和High级别都存在,这段code通过php_uname()检测服务器操作系统类型,动态适配不同平台的ping命令语法:Windows使用无参数格式,Unix系使用-c指定次数。这种自适应机制避免因系统差异导致的命令执行失败或异常,同时限制命令参数为固定格式,防止参数注入攻击。

if( stristr(php_uname('s'), 'Windows NT') ) {$cmd = shell_exec('ping ' . $target);
} else {$cmd = shell_exec('ping -c 4 ' . $target);
}

尽管本关卡对命令执行攻击进行了安全防范,但是仍然存在一些小问题,这种检查 IP 合法性的方法存在一些局限性:

  • 范围检查不足:is_numeric() 只判断是否为数字,没有检查每个八位组的值是否在合法的范围(0 - 255)内。例如,输入 999.999.999.999 会被认为是合法的 IP 地址,而实际上它不是。
  • 缺乏对 IPv6 的支持:此方法仅适用于 IPv4 地址,无法处理 IPv6 地址。如果需要支持 IPv6,需要采用不同的验证逻辑。
http://www.dtcms.com/a/356207.html

相关文章:

  • 大数据毕业设计选题推荐:基于北京市医保药品数据分析系统,Hadoop+Spark技术详解
  • 多线程网络数据接收与处理框架设计
  • 软考-系统架构设计师 专家系统(ES)详细讲解
  • 【深度学习计算机视觉】02:微调
  • SpringBoot整合Spring WebFlux弃用自带的logback,使用log4j2,并启动异步日志处理
  • Cesium 入门教程(十二):时间动画实例
  • undefined和null
  • MySQL數據庫開發教學(三) 子查詢、基礎SQL注入
  • Maven安装、IDEA集成Maven、依赖管理、单元测试
  • 《开发避坑指南:从异常中读懂系统的“求救信号”》
  • 自动化Reddit 效率已ready
  • 使用 Dify 和 LangBot 搭建飞书通信机器人
  • Webrtc支持FFMPEG硬解码之Intel
  • 2025五天申请邓白氏编码成功
  • Python 轻量级 HTML 解析器 - lxml入门教程
  • Java研学-SpringCloud(十)
  • Android14 init.qcom.usb.rc详解
  • 设计模式之状态机模式
  • hive udf函数实现在sql查询网站价格
  • Vue3 中的 v-model 语法糖
  • (Nginx)基于Nginx+PHP 驱动 Web 应用(上):配置文件与虚拟主机篇
  • 基于SQL大型数据库的智能问答系统优化
  • 安卓开发---SimpleAdapter
  • 不同卷积不同的滤波效果
  • 如何将OFD文件转换为PDF?总结在线OFD转PDF方法
  • QT5.14.2、CMake 扩展openCV
  • GPT-5原理
  • 第二章 Vue + Three.js 实现鼠标拖拽旋转 3D 立方体交互实践
  • Python- Visual Studio Code配置Anaconda
  • WebIDEPLOY 赋能数字校园建设:智慧管理系统的效能升级与实践路径 —— 以校园资源协同优化构建高效教育生态的探索