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

dvwa-command injection 代码审计(超详细逐行审计)

dvwa-command injection 代码审计

low

<?phpif( isset( $_POST[ 'Submit' ]  ) ) {// Get input$target = $_REQUEST[ 'ip' ];// Determine OS and execute the ping command.if( stristr( php_uname( 's' ), 'Windows NT' ) ) {// Windows$cmd = shell_exec( 'ping  ' . $target );}else {// *nix$cmd = shell_exec( 'ping  -c 4 ' . $target );}// Feedback for the end userecho "<pre>{$cmd}</pre>";
}?>

isset( $_POST[ 'Submit' ]此代码判断接受的post参数是否为空

$target = $_REQUEST[ 'ip' ];request方式接受ip参数

stristr( php_uname( 's' ), 'Windows NT' 此参数为真时,执行ping命令(意为在windows系统中执行ping命令)

否则执行ping命令4次(意为在unix或linux中执行ping4次)

其中的stristr函数如下

stristr()函数在PHP中用于在字符串中查找子字符串,并返回第一个匹配的子字符串及其后面的部分,而且不区分大小写

示例

$str = "Hello, World!";
$substring = "world";
$result = stristr($str, $substring);
echo $result; // 输出 "World!"

php_uname()函数如下,此代码中即为查看系统信息是否为Windows NT

在PHP中,php_uname()函数用于获取操作系统的信息。该函数返回一个包含系统信息的字符串,包括操作系统名称、主机名、内核版本、发布版本等

  • “a”:默认值,返回所有系统信息
  • “s”:返回操作系统名称
  • “n”:返回主机名
  • “r”:返回内核版本
  • “v”:返回发布版本
  • “m”:返回机器类型

最后则返回执行结果

medium


<?phpif( isset( $_POST[ 'Submit' ]  ) ) {// Get input$target = $_REQUEST[ 'ip' ];// Set blacklist$substitutions = array('&&' => '',';'  => '',);// Remove any of the charactars in the array (blacklist).$target = str_replace( array_keys( $substitutions ), $substitutions, $target );// Determine OS and execute the ping command.if( stristr( php_uname( 's' ), 'Windows NT' ) ) {// Windows$cmd = shell_exec( 'ping  ' . $target );}else {// *nix$cmd = shell_exec( 'ping  -c 4 ' . $target );}// Feedback for the end userecho "<pre>{$cmd}</pre>";
}?>

该级别代码几乎和low一致,仅添加两个过滤

关键代码部分

$substitutions = array( '&&' => '', ';' => '', );

此代码为使用array函数快速定义一个数组,并将其值赋给substitutions

$target = str_replace( array_keys( $substitutions ), $substitutions, $target );

array_keys( $substitutions )该函数为获取变量中的 键 即key

<?php$substitutions = array('&&' => '',';'  => '',);var_dump($substitutions);print("<br/>");$a=array_keys($substitutions);var_dump($a);
?>

输出结果

image-20231121170431441

然后使用srt_replace()函数进行字符串替换

该函数如下

str_replace()函数用于在字符串中替换指定的子字符串。它可以用于执行简单的字符串替换操作,例如将一个子字符串替换为另一个子字符串

str_replace (mixed $search , mixed $replace , mixed $subject [, int &$count ]) : mixed

search是要搜索的字符串或字符串数组,replace是要替换为的字符串或字符串数组,subject是被搜索的原始字符串,count是一个可选参数,用于存储替换操作的次数

示例

$string = "Hello, World!";
$new_string = str_replace("World", "PHP", $string);
echo $new_string;

输出结果即为 Hello, PHP!

此处即,搜索输入的target的值,将其中substitutions数组中的键替换成substitutions变量中该键所对应的值,从而达成将输入的&&或者;进行置空过滤

high


<?phpif( isset( $_POST[ 'Submit' ]  ) ) {// Get input$target = trim($_REQUEST[ 'ip' ]);// Set blacklist$substitutions = array('&'  => '',';'  => '','| ' => '','-'  => '','$'  => '','('  => '',')'  => '','`'  => '','||' => '',);// Remove any of the charactars in the array (blacklist).$target = str_replace( array_keys( $substitutions ), $substitutions, $target );// Determine OS and execute the ping command.if( stristr( php_uname( 's' ), 'Windows NT' ) ) {// Windows$cmd = shell_exec( 'ping  ' . $target );}else {// *nix$cmd = shell_exec( 'ping  -c 4 ' . $target );}// Feedback for the end userecho "<pre>{$cmd}</pre>";
}?>

相较上一关,该难度差别在如下代码

$target = trim($_REQUEST[ 'ip' ]);// Set blacklist$substitutions = array('&'  => '',';'  => '','| ' => '','-'  => '','$'  => '','('  => '',')'  => '','`'  => '','||' => '',);

增加了过滤项,但是原理不变

除此之外添加了trim()处理输入的内容

trim()函数用于删除字符串开头和结尾处的空白字符(空格、制表符、换行符等)或者其它指定字符

string trim ( string $str [, string $character_mask = " \t\n\r\0\x0B" ] )

str是要处理的字符串,character_mask是一个可选参数,用于指定要删除的字符。如果不指定$character_mask参数,默认会删除空格、制表符、换行符、回车符、空字符和垂直制表符

示例

$str = "   Hello, World!   ";
$new_str = trim($str);
echo $new_str;

输出结果为 Hello, World!

impossible


<?phpif( isset( $_POST[ 'Submit' ]  ) ) {// Check Anti-CSRF tokencheckToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );// Get input$target = $_REQUEST[ 'ip' ];$target = stripslashes( $target );// Split the IP into 4 octects$octet = explode( ".", $target );// Check IF each octet is an integerif( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {// If all 4 octets are int's put the IP back together.$target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];// Determine OS and execute the ping command.if( stristr( php_uname( 's' ), 'Windows NT' ) ) {// Windows$cmd = shell_exec( 'ping  ' . $target );}else {// *nix$cmd = shell_exec( 'ping  -c 4 ' . $target );}// Feedback for the end userecho "<pre>{$cmd}</pre>";}else {// Ops. Let the user name theres a mistakeecho '<pre>ERROR: You have entered an invalid IP.</pre>';}
}// Generate Anti-CSRF token
generateSessionToken();?>

checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

将三个参数传递给checktoken函数,checktoken函数一般用于验证匹配用户token和用户session是否匹配,如不匹配则跳转到index.php

$_REQUEST[ 'user_token' ]:这是一个 PHP 超全局数组,用于获取 HTTP 请求中的参数。在这里,$_REQUEST['user_token'] 用于获取名为 user_token 的参数的值。

$_SESSION['session_token']:这是 PHP 的会话(Session)变量,用于在用户会话之间存储数据。在这里,$_SESSION['session_token'] 用于获取名为 session_token 的会话变量的值

index.php:这是一个字符串,表示一个重定向页面的 URL。如果 checkToken 函数判断验证失败,用户将被重定向到这个页面

$target = stripslashes( $target );该行代码为过滤输出内容

stripslashes() 函数用于去除由 addslashes() 函数添加的反斜杠。在 PHP 中,addslashes() 用于在特定字符前添加反斜杠,以防止 SQL 注入和其他安全漏洞。而 stripslashes() 则用于将这些反斜杠去除,恢复原始的字符串

$octet = explode( ".", $target );该行explode函数通过 点 将输入的内容分段,被分割的部分会以数组的形式存储在变量中

if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {该行代码使用is_numeric函数判断该分割后的数组中的每个元素是否为数字,当全部都为数字时判断为真,才会向下执行,is_numric函数会将十六进制也视为数字,可以考虑将代码编程16进制,但是由于有分段组合成ip的这一步,所以该方法也不能实现

$target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];重新将该数组拼接,然后剩下的代码就与之前一样了

可以说是限制了所有字符和字母

numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {`该行代码使用is_numeric函数判断该分割后的数组中的每个元素是否为数字,当全部都为数字时判断为真,才会向下执行,is_numric函数会将十六进制也视为数字,可以考虑将代码编程16进制,但是由于有分段组合成ip的这一步,所以该方法也不能实现

$target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];重新将该数组拼接,然后剩下的代码就与之前一样了

可以说是限制了所有字符和字母

http://www.lryc.cn/news/239323.html

相关文章:

  • hadoop 配置历史服务器 开启历史服务器查看 hadoop (十)
  • Java注解(Annotation)的基本知识
  • ssh远程连接不了虚拟机ubuntu
  • 文心一言 VS 讯飞星火 VS chatgpt (140)-- 算法导论11.4 5题
  • 代码随想录Day51 完结篇 LeetCode T84 柱状图的最大矩形
  • 对接苹果支付退款退单接口
  • 合肥中科深谷嵌入式项目实战——基于ARM语音识别的智能家居系统(三)
  • Web前端—移动Web第四天(vw适配方案、vw和vh的基本使用、综合案例-酷我音乐)
  • 报错注入 [极客大挑战 2019]HardSQL1
  • 【MATLAB源码-第83期】基于matlab的MIMO中V-BALST结构ZF和MMSE检测算法性能误码率对比。
  • Android13 新增 Stable AIDL接口
  • Postman API Enterprise 10.18.1 Crack
  • 电脑内存升级
  • ExcelBDD PHP Guideline
  • C++静态链接库的生成以及使用
  • 【2024系统架构设计】 系统架构设计师第二版-未来信息综合技术
  • JavaFX修改软件图标
  • Linux ps -ef|grep去除 grep --color=auto信息
  • jQuery的学习(一篇文章齐全)
  • 注塑行业各类业务流程图(系统化)
  • Android Studio 安装及使用
  • 计算机网络的OSI七层模型
  • 如何一次性解压多个文件
  • 类和对象学习笔记
  • Linux程序之可变参数选项那些事!
  • 【1day】泛微e-office OA系统user_page接口未授权访问漏洞学习
  • Midjourney绘画提示词Prompt参考教程
  • Altium Designer学习笔记6
  • 【问题解决】Maven密码加密
  • vue3基于vite打包