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变量。如果存在,则继续执行下面的代码。
- 首先,它检查 $_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( POST包含′Submit′键,并且这个键对应的值不是NULL,那么‘isset(_POST[‘Submit’])返回 true。 3. 如果
isset($_POST[‘Submit’])` 返回 true,那么 if 语句就会执行,也就是它后面的代码会被执行。
isset
使用示例:
isset()
函数用于检查一个变量是否已设置,并返回布尔值。如果变量存在且非 null
或 undefined
,isset()
函数将返回 true
,否则返回 false
。
以下是一个使用 isset()
函数的示例:
- 检查变量是否已设置
<?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";
}
?>
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 中用来验证输入的常用方法。
这段代码的解析如下:
$octet
是一个数组,包含了要检查的四个字节。sizeof($octet) == 4
检查数组的长度是否为 4。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];
- .就是拼接的意思。
$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()
函数返回一个随机的十六进制字符串,表示当前的会话标识符。您可以将此字符串添加到会话中,以便在后续请求中引用。