DVWA-impossible-代码审计

impossible代码审计

代码

<?php

if( isset( $_POST[ 'Submit' ]  ) ) {
    // Check Anti-CSRF token
    checkToken( $_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 integer
    if( ( 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 user
        echo "<pre>{$cmd}</pre>";
    }
    else {
        // Ops. Let the user name theres a mistake
        echo '<pre>ERROR: You have entered an invalid IP.</pre>';
    }
}

// Generate Anti-CSRF token
generateSessionToken();

?>

1 isset

<?php
if( isset( $_POST[ 'Submit' ] ) )

<?php

是php语言的开始框架

这个if语句用于检查是否存在名为’Submit’的POST变量。如果存在,则继续执行下面的代码。

  1. 首先,它检查 $_POST 数组中是否有 ‘Submit’ 键。
    2. 如果 P O S T 包 含 ′ S u b m i t ′ 键,并且这个键对应的值不是 N U L L ,那么 ‘ i s s e t ( _POST 包含 'Submit' 键,并且这个键对应的值不是 NULL,那么 `isset( POSTSubmit键,并且这个键对应的值不是NULL,那么isset(_POST[‘Submit’])返回 true。 3. 如果isset($_POST[‘Submit’])` 返回 true,那么 if 语句就会执行,也就是它后面的代码会被执行。

isset使用示例:

isset() 函数用于检查一个变量是否已设置,并返回布尔值。如果变量存在且非 nullundefinedisset() 函数将返回 true,否则返回 false

以下是一个使用 isset() 函数的示例:

  1. 检查变量是否已设置
<?php

$var1 = "value1";

if (isset($var1)) {
  echo "$var1 ok";
} else {
  echo "$var1 bad";
}

?>

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2 checktoken

 // Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

这句代码是用来检查用户的 ‘user_token’ 是否匹配 ‘session_token’,以及检查请求的页面是否是 ‘index.php’。

checkToken() 函数用于检查传递给函数的三个参数。在这个例子中,第一个参数 ‘user_token’ 代表用户的令牌,第二个参数 ‘session_token’ 是当前会话的令牌,最后一个参数 ‘index.php’ 是当前请求的页面。

如果函数返回 TRUE,那么检查通过。否则,会发生错误。

checkToken使用示例:

checkToken 函数用于检查客户端传递的 HTTP 令牌(通常表示身份验证状态)是否有效。如果令牌有效,可以继续执行操作,否则需要要求用户进行身份验证或返回相应的错误信息。

以下是一个简单的 checkToken 函数使用示例:

<?php

function checkToken($url, $token, $checkUrl) {
    // 从客户端获取令牌
    $token = $_REQUEST['token'];

    // 如果令牌无效或未找到,则返回错误信息
    if (empty($token) || !isset($token) || $token != $_SESSION['auth_token']) {
        return false;
    }

    // 检查令牌是否过期
    $now = time();
    $token_expire = config('auth.token_expire');

    if ($now >= $token_expire) {
        // 如果令牌过期,返回错误信息
        return false;
    }

    // 检查令牌是否用于特定操作
    if (!empty($checkUrl) && !preg_match('/^(.*)$/', $checkUrl, $match)) {
        // 如果请求的 URL 不是已知的,返回错误信息
        return false;
    }

    // 如果令牌有效且未过期且请求的 URL 是已知的,返回 true
    return true;
}

// 设置令牌过期时间和需要检查的 URL
set_config('auth.token_expire', 3600);
set_config('auth.check_url', '***');

// 检查令牌是否有效,并执行后续操作
if (checkToken('***', 'token', '***')) {
    // 执行后续操作
    echo "Token is valid!";
} else {
    // 如果令牌无效,返回错误信息
    echo "Token is invalid!";
}
?>

在上述示例中,checkToken 函数被设置为一个处理令牌的公共函数。

3 $_REQUEST

// Get input
$target = $_REQUEST[ 'ip' ];

这句代码定义了一个名为target的变量,而它变动的值来源于请求用户输入的ip。

‘ip’ 可以是任何有效的 IPv4 或 IPv6 地址。如果 ‘ip’ 是一个字符串,那么这个字符串必须包含四个数字,每两个数字之间用 ‘.’ 分隔。

' R E Q U E S T [ ′ i p ′ ] ′ 可以被认为是一个变量,它代表了由 H T T P 请求发送的所有信息。这个数组可以通过 ‘ _REQUEST[ 'ip' ]' 可以被认为是一个变量,它代表了由 HTTP 请求发送的所有信息。这个数组可以通过 ` REQUEST[ip]可以被认为是一个变量,它代表了由HTTP请求发送的所有信息。这个数组可以通过_REQUEST G E T ‘ 、 ‘ _GET`、` GET_POST$_COOKIE` 等其他 PHP 数组来访问。

$_REQUEST使用示例:

<?php
// 获取所有表单参数
$data = array_column($_REQUEST, 'name');

// 打印所有参数
foreach ($data as $name => $value) {
  echo "Name: {$name}, Value: {$value}\n";
}
?>
$_REQUEST 示例 Name: Age:

4 stripslashes

$target = stripslashes( $target );

stripslashes-------反引用一个引用字符串

stripslashes使用示例:

stripslashes() 函数用于移除字符串中的反斜杠(\)。它可以确保在处理用户输入时,防止因反斜杠导致的潜在问题。

以下是一个使用 stripslashes() 函数的示例:

<?php

$str = "Hello, \\\\\\\\World!";

// 使用 stripslashes() 函数移除字符串中的反斜杠
$str = stripslashes($str);

echo $str; // 输出: Hello, World!
?>

在这个示例中,stripslashes() 函数将 "Hello, \\\\\\\\World!" 中的每个反斜杠都转换为 '\'。这使得 PHP 能够正确地解析和处理这个字符串。

5 explode

  // Split the IP into 4 octects
$octet = explode( ".", $target );

explode-----使用一个字符串分割另一个字符串

这句代码的意思是定义一个octet的变量执行将target这个变量用符号.进行分割

explode使用示例:

explode() 是一个 PHP 内置函数,用于将字符串分割为数组。它接受一个字符串和一个字符作为参数,并返回一个数组,其中包含由该字符串的分割点创建的子字符串。

以下是一个使用 explode() 函数的示例:

<?php

// 定义一个字符串,包含一个空格和一个逗号
$str = "Hello, World!";

// 使用 explode() 函数将字符串拆分为数组
$arr = explode(", ", $str);

// 输出拆分后的数组
echo "拆分后的数组: ";
foreach ($arr as $value) {
  echo "$value ";
}
echo "\n";

?>

在这个示例中,explode(", ", $str) 将字符串 "Hello, World!" 拆分为包含两个元素的数组。每个元素都是一个 $str 字符串中的字符。最后,使用 foreach 循环遍历数组并输出结果。

请注意,explode() 函数默认将分割点字符识别为单个空格。但是,如果需要在分隔符周围包含多个空格,可以使用以下方法:

<?php

// 定义一个字符串,包含一个空格和一个逗号
$str = "Hello, World!";

// 使用 explode() 函数将字符串拆分为数组,并在字符串周围添加多个空格
$arr = explode(", ", $str, true);

// 输出拆分后的数组
echo "拆分后的数组: ";
foreach ($arr as $value) {
  echo "$value ";
}
echo "\n";

?>

在这个示例中,explode(", ", $str, true) 将字符串 "Hello, World!" 拆分为一个包含两个元素的数组。每个元素都是一个 $str 字符串中的字符,并在其周围添加了多个空格。

6 is_numeric

// Check IF each octet is an integer
if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {

这段 PHP 代码的主要目的是检查输入的四个字节是否都是数字。这是在 PHP 中用来验证输入的常用方法。

这段代码的解析如下:

  1. $octet 是一个数组,包含了要检查的四个字节。
  2. sizeof($octet) == 4 检查数组的长度是否为 4。
  3. if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) 检查数组的每个元素是否都是数字。

如果所有的检查都通过了,那么就会执行 { echo "All the input bytes are numeric."; }

注意,PHP 数组的索引是从 0 开始的。因此, o c t e t [ 0 ] 将是第一个字节, octet[0] 将是第一个字节, octet[0]将是第一个字节,octet[1] 将是第二个字节,以此类推。“sizeof” 函数返回的是数组的元素个数,所以 $octet 的长度是 4。

is_numeric 使用示例:

is_numeric() 是一个 PHP 内置函数,用于检查一个变量是否为数字或数字字符串。如果是,则返回 true,否则返回 false

以下是一个使用 is_numeric() 函数的示例:

<?php

// 定义一个包含数字的变量
$num = 123;

// 检查变量 $num 是否为数字
if (is_numeric($num)) {
  echo "$num 是一个数字";
} else {
  echo "$num 不是一个数字";
}

?>

在这个示例中,is_numeric($num) 将检查变量 $num 是否为数字或数字字符串。如果是,则输出 “ n u m 是一个数字 " ;如果不是,则输出 " num 是一个数字";如果不是,则输出 " num是一个数字";如果不是,则输出"num 不是一个数字”。

sizeof使用示例:

sizeof() 是一个 PHP 内置函数,用于获取给定数据类型或变量的字节数。它返回一个整数值,表示该类型或变量所占用的字节数。

以下是一个使用 sizeof() 函数的示例:

<?php

// 定义一个包含整数的数组
$ints = array(1, 2, 3, 4, 5);

// 计算数组 $ints 的大小
$size = sizeof($ints);

// 输出数组 $ints 的大小
echo "数组 $ints 的大小为: " . $size . " 字节";

?>

在这个示例中,sizeof($ints) 将返回数组 $ints 的大小(即数组中元素的数量)。输出结果为:数组 $ints 的大小为:5 字节。

7 .

// If all 4 octets are int's put the IP back together. 
$target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];
  1. .就是拼接的意思。
  • $octet[0]:从数据流中读取第一个字节。
  • '.':如果第一个字节不是以"."开头,那么在其后面添加一个点。
  • $octet[1]:从数据流中读取第二个字节。
  • '.':如果第二个字节不是以"."开头,那么在其后面添加一个点。
  • $octet[2]:从数据流中读取第三个字节。
  • '.':如果第三个字节不是以"."开头,那么在其后面添加一个点。
  • $octet[3]:从数据流中读取第四个字节。
  • '.':如果第四个字节不是以"."开头,那么在其后面添加一个点。

8 stristr

 // Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
  • stristr(php_uname('s'), 'Windows NT')
  • 在这里,php_uname()函数被调用来获取系统的信息,
  • 其中s参数表示操作系统的名称。
  • 然后,stristr()函数用于查找与指定字符串匹配的子字符串。
  • 在这个例子中,查找的是操作系统名称是否包含字符串"Windows NT"。
  • {:表示一个条件语句的开始,它后面的代码块将根据stristr()函数的返回值执行相应的操作。

stristr使用示例:

stristr() 是一个 PHP 内置函数,用于查找字符串在另一字符串中的第一次出现。它不区分大小写。

以下是一个使用 stristr() 函数的示例:

<?php

$str1 = "Hello, World!";
$str2 = "Hello, World";

if (stristr($str1, $str2)) {
  echo "String $str1 contains string $str2";
} else {
  echo "String $str1 does not contain string $str2";
}

?>

在这个示例中,stristr($str1, $str2) 查找字符串 $str1 中是否包含字符串 $str2。如果找到,则输出 “String $str1 contains string $str2”;否则,输出 “String $str1 does not contain string $str2”。

9 shell_exec

 // Windows
$cmd = shell_exec( 'ping  ' . $target );

这句代码用于执行一个 ping 命令来检查指定的 URL 是否可访问。

shell_exec() 是一个 PHP 内置函数,用于执行 shell 命令

'ping ' . $target即是用小数点拼接前后两个动作,而变量$target = $_REQUEST[ 'ip' ];所以这句代码的意思就是ping一下ip。

当然这是针对windows的ping操作语法。

使用 shell_exec() 函数的示例:

<?php

// 定义一个包含目标 URL 的变量
$target = "***";

// 执行 ping 命令以检查目标 URL 是否可访问
$cmd = shell_exec( 'ping  ' . $target );

// 输出 ping 命令的结果
echo "Ping target at " . $target . ": " . $cmd;

?>

在这个示例中,shell_exec('ping ' . $target) 执行了一个 ping 命令,该命令将检查给定 URL(***)是否可访问。然后,使用 echo 语句输出 ping 命令的结果。

10 shell_exec

 // *nix
$cmd = shell_exec( 'ping  -c 4 ' . $target );

这句代码与上句代码有些细微的改变。就是多了一个参数-c 4

因为在linux中ping的语法不同,若是不限定ping的次数,会一直ping下去。所以这里针对*nux使用ping -c 4 来限定ping的次数。

11 echo

// Feedback for the end user
echo "<pre>{$cmd}</pre>"

输出包含 ping 命令结果的 HTML 格式的内容,其中 {$cmd}shell_exec() 函数返回的命令结果。

else {
        // Ops. Let the user name theres a mistake
        echo '<pre>ERROR: You have entered an invalid IP.</pre>';

else{

条件语句的另一条执行命令,若是不符合if的执行条件,即执行else里面的命令语句。

echo '<pre>ERROR: You have entered an invalid IP.</pre>';

这句代码执行后则是输出包含 ping 命令结果的 HTML 格式的内容You have entered an invalid IP。

// Generate Anti-CSRF token
generateSessionToken();

?>

?>是php的闭合框架

generateSessionToken()是用于在 PHP 中生成会话令牌的函数。它会将一个唯一的随机字符串(通常是一个十六进制的字符串)与当前时间戳一起返回。

使用 generateSessionToken() 函数的示例:

<?php

// 生成一个唯一的会话令牌
generateSessionToken();

function generateSessionToken() {
  // 生成一个随机字符串
  $random = rand(1, 16);

  // 将字符串转换为十六进制字符串
  $sessionToken = strtoupper(bin2hex($random));

  // 添加当前时间戳
  $sessionToken .= time();

  return $sessionToken;
}

?>

的内容You have entered an invalid IP。

// Generate Anti-CSRF token
generateSessionToken();

?>

?>是php的闭合框架

generateSessionToken()是用于在 PHP 中生成会话令牌的函数。它会将一个唯一的随机字符串(通常是一个十六进制的字符串)与当前时间戳一起返回。

使用 generateSessionToken() 函数的示例:

<?php

// 生成一个唯一的会话令牌
generateSessionToken();

function generateSessionToken() {
  // 生成一个随机字符串
  $random = rand(1, 16);

  // 将字符串转换为十六进制字符串
  $sessionToken = strtoupper(bin2hex($random));

  // 添加当前时间戳
  $sessionToken .= time();

  return $sessionToken;
}

?>

在这个示例中,generateSessionToken() 函数返回一个随机的十六进制字符串,表示当前的会话标识符。您可以将此字符串添加到会话中,以便在后续请求中引用。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值