1.web89
分析这段代码
它通过检查 GET 请求中的参数 num
是否只包含非数字字符来决定是否输出 flag
变量的值。以下是详细的解释:
首先,代码通过 include("flag.php")
引入了一个外部 PHP 文件 flag.php
。这个文件应该包含了变量 flag
的定义。
然后,使用 highlight_file(__FILE__)
函数将当前 PHP 文件的内容以高亮的形式输出,这通常用于调试目的,方便查看代码结构。
接下来,代码通过 if (isset($_GET['num']))
检查是否存在名为 num
的 GET 参数。如果存在,则将该参数的值赋给变量 $num
。
然后,通过正则表达式 preg_match("/[0-9]/", $num)
检查 $num
是否只包含数字。如果 $num
只包含数字,则执行 die("no no no!")
函数,输出 "no no no!" 并终止脚本的执行。这是为了防止直接访问和输出 flag
变量的值。
如果 $num
不只包含数字,即通过了数字验证,代码会进一步检查是否能够将 $num
转换为整数。如果可以转换(即 $num
是一个整数),则执行 echo $flag;
语句,输出 flag
变量的值。
综上所述,这段代码通过限制对 flag
变量的访问来提供一种基本的安全机制,只有当 GET 请求中的参数 num
不只包含数字时才允许访问该变量。这样可以防止未经授权的访问和潜在的安全风险。
解法:
输入num,以数组方式,避开检查
解出flag
2.web90
分析代码:
首先,通过 include("flag.php")
引入了一个名为 flag.php
的文件。这个文件应该包含了变量 flag
的定义。
然后,使用 highlight_file(__FILE__)
函数将当前 PHP 文件的内容以高亮的形式输出,这通常用于调试目的,方便查看代码结构。
接下来,检查是否存在名为 num
的 GET 参数。如果存在,则将该参数的值赋给变量 $num
。
然后,通过条件判断 if ($num === "4476")
检查 $num
是否等于字符串 "4476"。如果是,执行 die("no no no!")
函数,输出 "no no no!" 并终止脚本的执行。
如果 $num
不等于 "4476",则进一步使用条件判断 if (intval($num, 0) === 4476)
检查 $num
是否等于整数 4476。如果是,则输出变量 flag
的值。
如果 $num
不等于整数 4476,则执行 echo intval($num, 0)
,输出 $num
的整数值。
解法:
将4476转换进制:
整形常量通常用十进制、八进制、十六进制,而十进制不可使用,所以可以输入:
?num=010574
或
?num=0x117c
3.web91
分析代码:
<?php
show_source(__FILE__); // 显示当前文件的源代码。
include('flag.php'); // 包含外部文件 flag.php,它可能定义了变量 $flag。
$a=$_GET['cmd']; // 从 GET 请求中获取名为 'cmd' 的参数,并将其值赋给变量 $a。
// 使用 preg_match 函数检查 $a 是否严格匹配字符串 'php'(不区分大小写,并且使用多行模式,尽管这里多行模式没有意义)。
if(preg_match('/^php$/im', $a)){
// 如果外部条件为真,再次检查相同的条件,但这次没有使用多行模式。
if(preg_match('/^php$/i', $a)){
echo 'hacker'; // 如果内部条件也为真,输出 'hacker'。
}
else{
echo $flag;
}
}
else{
echo 'nonononono'; // 如果 $a 不匹配 'php',输出 'nonononono'。
}
preg_match('/^php$/im', $a)
的目的是检查 $a
是否完全由不区分大小写的 "php" 字符串组成。如果是,preg_match
函数返回 1;如果不是,返回 0。m代表多行模式。
preg_match('/^php$/i', $a)
的意思是:匹配一个完全由 "php" 组成的字符串(不区分大小写)。如果是 ,那么 preg_match('/^php$/i', $a)
将返回 1
,表示匹配成功。如果 $a
包含任何其他内容,函数将返回 0
,表示匹配失败。
解法:
参数为cmd
要想办法满足两个条件,所以要有多行,每行以php(不区分大小写)开头
所以需要转行符%0
输入:?cmd=%0aphp
4.web92
include("flag.php");
:包含外部文件 flag.php
。这通常意味着 flag.php
文件中定义了一些变量或函数,其中可能包括 $flag
变量,这是一个常见的在 CTF(Capture The Flag)挑战中使用的模式。
highlight_file(__FILE__);
:使用 PHP 的 highlight_file
函数来高亮显示当前文件的源代码。__FILE__
是一个魔术常量,它包含当前文件的完整路径和文件名。
if(isset($_GET['num']))
:检查是否设置了名为 num
的 GET 参数。
$num = $_GET['num'];
:如果 num
参数存在,将其值赋给变量 $num
。
if($num==4476)
:检查 $num
是否严格等于 4476。如果是,则执行 die("no no no!");
,终止脚本执行并输出 "no no no!"。
if(intval($num,0)==4476)
:使用 intval
函数将 $num
转换为整数。intval
函数的第二个参数是基数,但这里设置为 0,意味着基数将根据 $num
的格式自动确定。如果转换后的整数值等于 4476,则输出 $flag
变量的值。
else{ echo intval($num,0); }
:如果转换后的整数值不等于 4476,则输出转换后的整数值。
解法:
如web90,使用十六进制或八进制
5.web93
分析代码,如web92,但会识别字符串中是否存在字母,所以只能使用八进制
解法:
输入:?num=010574
6.web94
注:strpos()
是 PHP 中的一个字符串函数,用于查找一个字符串在另一个字符串中首次出现的位置。如果找到了该字符串,则返回其首次出现的位置的索引值(基于0的索引);如果没有找到,则返回 false
。
所以,字符串加一个空格就会躲过函数识别
解法:
输入:?num= 010574
7.web95
对比上题,区别为preg_match函数内的"/[a-z]|\./i"
preg_match("/[a-z]|\./i", $num)
和 preg_match("/[a-z]/i", $num)
的区别在于所匹配的内容:
-
preg_match("/[a-z]|\./i", $num)
:- 这个模式会匹配
$num
中的任何一个小写字母(不区分大小写,因为使用了i
修饰符)或一个句点(.
)。 - 使用了管道符
|
,意味着它将匹配[a-z]
或.
中的任何一个。 - 注意,这里的
.
字符在正则表达式中通常是一个特殊字符,表示匹配任何单个字符(换行符除外)。但在这个例子中,.
被放在了一个字符类中(在方括号内),所以它表示的就是字面意义上的句点字符。
- 这个模式会匹配
-
preg_match("/[a-z]/i", $num)
:- 这个模式只会匹配
$num
中的任何一个小写字母(不区分大小写,因为使用了i
修饰符)。 - 它不会匹配句点(
.
)或其他任何字符。
- 这个模式只会匹配
因此,两个表达式的区别在于第一个还会匹配句点(.
),而第二个只匹配小写字母。
解法:
如web94
8.web96
分析代码:
-
if(isset($_GET['u']))
:检查 URL 中是否存在名为u
的 GET 参数。 -
如果
u
参数存在:
a. if($_GET['u']=='flag.php')
:检查 u
参数是否等于 'flag.php'
。如果是,则执行 die("no no no");
,终止脚本执行并输出 "no no no"。
b. 如果 u
参数不是 'flag.php'
,则执行 highlight_file($_GET['u']);
,高亮显示用户指定的文件内容。
解法:
输入:?u=./flag.php
9.web97
if (isset($_POST['a']) and isset($_POST['b']))
: 检查是否通过 POST 方法提交了 a
和 b
两个参数。
if ($_POST['a'] != $_POST['b'])
: 确保 a
和 b
是两个不同的字符串。
if (md5($_POST['a']) === md5($_POST['b']))
: 检查 a
和 b
的 MD5 哈希值是否完全相同(使用严格比较 ===
)。
echo $flag;
: 如果上述条件都满足,输出 $flag
的内容。
else print 'Wrong.';
: 如果 MD5 哈希值不相同,输出 "Wrong."。
哈希值:
哈希值是一个十进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,模拟出来的地址,不是数据实际存储的物理地址)。哈希值又称哈希函数,指将哈希表中元素的关键键值映射为元素存储位置的函数。以下是哈希值的几个特点:
- 同一个对象多次调用哈希值计算函数获取哈希值,结果肯定是一样的。
- 默认情况下,不同对象的哈希值是不同的,但可以通过方法重写,实现让不同对象的哈希值也相同。
- 哈希值是一个对象对应的编号,同一个对象的哈希值肯定相同,不同对象的哈希值一般不同,有可能出现相同的情况,但应尽量避免。
- 哈希算法将任意长度的二进制值映射为固定长度的较小二进制值,这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该段落的一个字母,随后的哈希都将产生不同的值。要找到散列为同一个值的两个不同的输入,在计算上是不可能的。
哈希值在实际应用中有多种用途,例如在数据结构中用于快速查找,在密码学中用于保证数据完整性,以及在软件分发中用于验证文件未被篡改等。
解法:
使用POST方法输入
a[]=1&b[]=2
10.web98
分析代码:
$_GET ? $_GET = &$_POST : 'flag';
:这行代码试图检查 $_GET
超全局数组是否为空。如果不为空,它将 $_GET
变量设置为 $_POST
的引用。
$_GET['flag'] == 'flag' ? $_GET = &$_COOKIE : 'flag';
:这行代码检查 $_GET['flag']
是否等于字符串 'flag'
。如果等于,则将 $_GET
设置为 $_COOKIE
的引用。
$_GET['flag'] == 'flag' ? $_GET = &$_SERVER : 'flag';
:再次检查 $_GET['flag']
是否等于 'flag'
,如果等于,则将 $_GET
设置为 $_SERVER
的引用。
11.web99
分析代码:
-
使用
highlight_file(__FILE__);
来高亮显示当前 PHP 文件的内容。 -
创建一个空数组
$allow
。 -
使用一个
for
循环,循环变量$i
从 36(十进制)开始,直到 0x36d(十六进制,等于十进制的 877)。在每次循环中,生成一个介于 1 和$i
之间的随机整数,并将其添加到$allow
数组中。 -
检查是否通过 GET 方法设置了一个名为
使用'n'
的参数,并且这个参数的值是否存在于$allow
数组中。如果是,则执行以下操作:file_put_contents
函数将 POST 方法提交的'content'
参数的内容写入到文件名为$_GET['n']
的文件中。这意味着用户可以控制写入的文件名,只要文件名是一个之前被添加到$allow
数组中的随机数。
12.web100
-
highlight_file(__FILE__);
:这行代码会高亮显示当前 PHP 文件的内容 -
include("ctfshow.php");
:这行代码包含了一个名为 "ctfshow.php" 的外部文件。我们无法看到 "ctfshow.php" 的内容,但根据注释,ctfshow
是一个类,并且 flag 存在于这个类中。 -
$ctfshow = new ctfshow();
:这里创建了一个ctfshow
类的实例。 -
$v1
,$v2
,$v3
:这三个变量分别从 URL 查询字符串中获取用户输入的值。 -
$v0 = is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
:这里检查三个变量是否都是数字或数字字符串。但是,使用and
运算符意味着只要有一个变量不是数字,$v0
就会是false
。这可能不是预期的行为,因为通常你可能想要确保所有变量都是数字。 -
接下来的条件语句首先检查
$v2
是否不包含分号 (;
),然后检查$v3
是否包含分号。如果这两个条件都满足,代码将执行eval("$v2('ctfshow')$v3");
。
13.php101
分析代码:
使用 highlight_file(__FILE__);
来高亮显示当前 PHP 文件的内容。
实例化 ctfshow
类,创建一个对象 $ctfshow
。
从 GET 参数中获取三个变量 $v1
、$v2
和 $v3
。
使用 is_numeric
函数检查 $v1
、$v2
和 $v3
是否都是数字或数字字符串,并将结果存储在 $v0
中。如果它们都是数字,$v0
将为 true
,否则为 false
。
如果 $v0
为 true
,则执行以下操作:
使用 preg_match
函数检查 $v2
是否不包含一系列的特殊字符和数字。如果 $v2
不包含这些字符,则继续执行下一个 preg_match
检查。
再次使用 preg_match
函数检查 $v3
是否不包含类似的特殊字符和数字。如果 $v2
和 $v3
都通过了检查,则执行 eval("$v2('ctfshow')$v3");
。它执行由 $v2
和 $v3
构成的 PHP 代码,其中 'ctfshow'
作为 $v2
函数的参数。
14.php102
分析代码:
-
使用
highlight_file(__FILE__);
高亮显示当前 PHP 文件的内容。这常用于教学或演示目的。 -
从
$_POST
数组中获取变量$v1
的值。这意味着$v1
的值是通过 POST 方法提交的。 -
从
$_GET
数组中获取变量$v2
和$v3
的值。这意味着$v2
和$v3
的值是通过 URL 查询字符串传递的。 -
使用
is_numeric
函数检查$v2
和$v3
是否都是数字或数字字符串,并将逻辑与操作的结果存储在$v4
中。如果$v2
和$v3
都是数字,则$v4
为true
,否则为false
。 -
如果
$v4
为true
,执行以下操作:- 使用
substr
函数从$v2
字符串中提取从第 3 个字符开始的所有字符,并将结果存储在$s
中。 - 使用
call_user_func
函数调用$v1
变量指定的函数,并将$s
作为参数传递给它。函数的返回值存储在$str
中。 - 使用
echo
输出$str
的内容。 - 使用
file_put_contents
函数将$str
的内容写入到$v3
指定的文件中。
- 使用
-
如果
$v4
为false
,则执行die('hacker');
终止脚本执行并输出 "hacker"。
15.php103
-
使用
highlight_file(__FILE__);
来高亮显示当前 PHP 文件的内容。 -
从
$_POST
数组中获取变量$v1
的值,它应该是用户通过 POST 方法提交的一个函数名。 -
从
$_GET
数组中获取变量$v2
和$v3
的值,它们分别应该是用户通过 URL 查询字符串传递的两个参数。 -
使用
is_numeric
函数检查$v2
和$v3
是否都是数字或数字字符串,并将结果存储在$v4
中。如果$v2
和$v3
都是数字,$v4
为true
,否则为false
。 -
如果
$v4
为true
,则执行以下操作:- 使用
substr
函数从$v2
字符串中提取从第 3 个字符开始的所有字符,并将结果存储在$s
中。 - 使用
call_user_func
函数调用$v1
指定的 PHP 函数,将$s
作为参数传递,并将返回结果存储在$str
中。 - 使用
echo
输出$str
的内容。 - 使用
preg_match
函数检查$str
是否包含字母 "p"、"h" 和另一个 "p"(不考虑顺序和大小写)。如果匹配到该模式,则执行die('Sorry');
终止脚本执行。 - 如果没有匹配到该模式,则使用
file_put_contents
函数将$str
的内容写入到$v3
指定的文件中。
- 使用
-
如果
$v4
为false
,则执行die('hacker');
终止脚本执行并输出 "hacker"
顺利完成!