涉及的函数功能:
$ 符号是PHP语言中用来表示变量的标识符
整形变量:
$age = 25;
字符串变量:
$name = "John";
⚪include('flag.php'):
执行结果:包含并运行指定的外部文件 'flag.php'。
返回值:无。如果文件不存在或者包含失败,它会产生一个警告,但不会终止脚本执行。
⚪isset($variable):
执行结果:检查变量是否已设置并且非NULL。如果变量已设置且非NULL,返回true,否则返回false。
⚪md5($string):
执行结果:计算输入字符串的MD5散列值,返回一个32字符的十六进制散列字符串。
返回值: 字符串,表示MD5散列值。
⚪$_GET['parameter']:
执行结果:从GET请求中获取指定参数的值,通过URL传递的参数(在URL中使用问号后面的参数)。
返回值:如果参数不存在,返回null。
⚪$_POST['parameter']:
执行结果:用于获取通过HTTP POST方法传递的参数(通常在表单提交时使用)。
返回值:如果参数不存在,返回null。
⚪is_numeric($variable):
执行结果:检查变量是否是数字或者数字字符串。
返回值:如果变量是数字或数字字符串,返回true;否则返回false。
⚪echo($string):
执行结果:输出一个或多个字符串。
返回值:无。
⚪die($message):
执行结果:输出指定的消息并退出当前脚本的执行。
返回值:无。die 函数终止脚本的执行,不返回任何值。
解析页面代码
// 包含外部文件 'flag.php',该文件可能包含敏感信息
include 'flag.php';
// 定义一个变量 $flag,包含一个字符串
$flag = 'MRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}';
// 检查是否存在名为 'gg' 和 'id' 的 GET 参数
if(isset($_GET['gg']) && isset($_GET['id'])) {
// 获取 GET 参数 'id' 和 'gg' 的值
$id = $_GET['id'];
$gg = $_GET['gg'];
// 检查 $id 和 $gg 的 MD5 散列值是否相等,并且它们的值不相等,强比较
if (md5($id) === md5($gg) && $id !== $gg) {
// 输出 'You got the first step'
echo 'You got the first step';
// 检查是否存在名为 'passwd' 的 POST 参数
if(isset($_POST['passwd'])) {
// 获取 POST 参数 'passwd' 的值
$passwd = $_POST['passwd'];
// 检查 $passwd 是否为数字
if (!is_numeric($passwd)) {
// 如果 $passwd 等于 1234567,则输出 'Good Job!',显示 'flag.php' 的内容,然后终止脚本执行
if($passwd == 1234567) {
echo 'Good Job!';
highlight_file('flag.php');
die('By Retr_0');
} else {
// 如果 $passwd 不等于 1234567,则输出 'can you think twice??'
echo "can you think twice??";
}
} else {
// 如果 $passwd 是数字,则输出 'You can not get it !'
echo 'You can not get it !';
}
} else {
// 如果不存在 POST 参数 'passwd',则输出 'only one way to get the flag'
die('only one way to get the flag');
}
} else {
// 如果 $id 和 $gg 的 MD5 散列值不相等,或者它们的值相等,则输出 'You are not a real hacker!'
echo "You are not a real hacker!";
}
} else {
// 如果不存在 'gg' 和 'id' 的 GET 参数,则输出 'Please input first'
die('Please input first');
}
注意点:
"==="与"==":在PHP中,===
和 ==
是用于比较两个值是否相等的运算符,它们之间的主要区别在于比较的严格程度:
⚪===
(严格相等运算符),===
用于比较两个值的数值和数据类型是否完全相等。只有当两个值的数值和数据类型都相等时,===
才会返回 true
。
$a = 5; // 整数
$b = '5'; // 字符串
var_dump($a === $b); // 输出 false,因为整数和字符串的数据类型不同
⚪==
(相等运算符):==
用于比较两个值的数值是否相等。它在比较时会进行类型转换,将操作数转换为相同的类型,然后再进行比较。如果转换后的数值相等,==
就会返回 true
。
$a = 5; // 整数
$b = '5'; // 字符串
var_dump($a == $b); // 输出 true,因为在进行类型转换后,整数5等于字符串'5'
"!=="与"!=":!==
和 !=
是用于比较两个值是否不相等的运算符
⚪!==
(不全等运算符):这是严格不相等运算符,它不仅会比较两个值的数值是否相等,还会比较它们的数据类型是否相等。只有在数值和数据类型都不相等的情况下,!==
才会返回 true
。
$a = 5; // 整数
$b = '5'; // 字符串
var_dump($a !== $b); // 输出 true,因为整数和字符串不全等
⚪!=
(不等运算符):这是非严格不相等运算符,它只会比较两个值的数值是否相等,不会考虑数据类型。只要数值不相等,不论数据类型是否相同,!=
都会返回 true
。
$a = 5; // 整数
$b = '5'; // 字符串
var_dump($a != $b); // 输出 false,因为在不考虑数据类型的情况下,整数和字符串相等
if (!is_numeric($passwd)) {
if($passwd == 1234567)
要求输入的$passwd不是数字或者纯数字字符串(带有字母或特殊符号),但是$passwd
的值与 1234567比较要相等。
如果 $passwd
的值是字符串 '1234567a'
,则is_numeric($passwd)返回false,!is_numeric($passwd)则为true,满足第一个条件。第二个if条件,PHP 会尝试将 $passwd
的值和 1234567
进行比较。由于 ==
比较运算符会尝试将操作数转换为相同的类型,它会尝试将字符串 '1234567a'
转换为整数。在这种情况下,$passwd
的字符串值 '1234567a'
会被尝试转换为整数 1234567
。因为字符串开头的数字部分是 1234567
,所以转换成功。最终,比较的结果是两个整数的比较,1234567
等于 1234567
,因此条件 $passwd == 1234567
会返回 true
。
若为弱比较:
md5加密后为0e开头的会被识别为科学记数法,结果均为0
例如:para1=QNKCDZO ,para2=aabg7XSs
md5(para1)=0e830400451993494058024219903391
md5(para2)=0e087386482136013740957780965295
此时MD5(para1)== MD5(para2)
若为强比较:
如果传入的两个参数不是字符串,而是数组,md5()函数无法解出其数值,并且不会报错,就会得到===强比较的值相等
例如:para1[]=111 , para2[]=222
此时md5(para1)=== md5(para2)
1.先通过GET请求发送id和gg参数,采用数组绕过md5强比较,发送数据
得到的回显中显示通过第一步
2.采用POST方式提交passwd,并将passwd设置为"1234567a",得到flag