PHP特性靶场(web89~web103)
后台-插件-广告管理-内容页头部广告(手机) |
1.web89
由代码可知我们所传入的参数中不能有数字但又要使intval($num)=1
intval() 的返回值是整型,1或者0 作用于数组时当数组为空,返回值是0,不为空则为1
所以我们可以使用数组进行绕过正则表达式也就是说我们不按规定去传一个数组而不是字符串就会返回false从而不会进入if语句,达到绕过的效果
输入:?num[]=1
回车如图:
2.web90
由代码可知传入的num参数既要绕过第一个if语句也应该满足第二个if语句这样才能输出flag
由第一个if语句可知我们不能直接传入4467这个数由第二个if语句中intval函数可知
intval($num, 0) 表示将变量 $num 转换为整数,根据 $num 的前缀来确定进制。如果转换后的整数值等于 4476,则可以尝试找到适合的前缀和进制
因此符合intval($num, 0)==4476 条件的输入方式有很多种可以通过进制转换 例:?num=0x117c
或者在数字后面加上字母或者加上小数(因为intval()函数只取整数部分且如果没有前缀会默认是十进制)
例:?num=4476.0 ?num=4476a
如图:
3.web91
由源代码可知此题需要得到一个名为cmd的参数
第一个大的if语句条件是要满足正则匹配(意思就是要在你传入的参数中匹配到正则表达式中的东西)
preg_match('/^php$/im', $a)此部分中 /i 表示匹配的时候不区分大小写 /m 表示多行匹配 ^$符号表示匹配每一行的开头结尾
第一个if的嵌套if语句条件preg_match('/^php$/i', $a)
对比以上两行代码可知第二个if条件中没有了 /m 不能进行多行匹配因此我们可以在传入的参数中第一行没有php第二行有只要符合这种形式均能得到flag 例:?cmd=q%0Aphp(在url中换行符为%0A因为不区分大小写所以对PHP的写法没有要求)
注意:在url中不要存在空格,因为在某些情况下,将空格字符(ASCII码为32)直接包含在URL中可能会导致问题。这是因为空格字符在URL中具有特殊的含义,用于分隔URL中的不同组件(例如路径、查询参数等)。
解的flag如图:
4.web92
此题和web90唯一的差别就是
web90 $num === "4476"
web92 $num==4476
全等比较 (===) 不会进行类型转换,而相等比较 (==) 会进行类型转换
因此在web92中4476.0不行
其它与web90的方法没有区别
如图:
5.web93
源码中共有三个过滤条件
我的解题思路:
if($num==4476){ die("no no no!"); }看到第一个条件是首先排除不能直接让参数等于4476
if(preg_match("/[a-z]/i", $num)){ die("no no no!"); } if(intval($num,0)==4476){ echo $flag; }else{ echo intval($num,0); }然后将第二三个条件结合起来看发现也不能通过其他进制的方法(因为不能有大小写字母)
如果考虑十进制且intval()函数只取整数部分所以我们可以通过在4476后加上小数部分来得到flag
如图:
也可以使用另一种方法换用八进制010574
6.web94
通过对代码的大致观察我们发现此关代码和上一关的区别是存在
strpos() 函数此函数用于在字符串中查找一个子串的第一次出现位置。如果找到了子串,则返回子串在字符串中的位置(索引)否则返回 false又因为在这行代码之前有!表示对结果取反所以说我们的参数中必须含有0但是需要注意的是我们的0不能出现在首位否则返回的位置可能为0取反条件为真就无法得到flag因此我们可以在八进制数010574基础上做处理可以在开头加上换行符%0a或空格
另一种方法:当我们仔细观察这段代码发现是全等比较因此我们可以输入4476.0来绕过
分别如图:
7.web95
源代码解析及思路
<?php include("flag.php"); highlight_file(__FILE__); if(isset($_GET['num'])){ $num = $_GET['num']; if($num==4476)//判断num是否等于4476;可以进行类型转换 { die("no no no!"); } if(preg_match("/[a-z]|\./i", $num))//用于判断在num中是否存在英文字母或小数点 { die("no no no!!"); } if(!strpos($num, "0"))//详解见web94解释 { die("no no no!!!"); } if(intval($num,0)===4476)//全等比较,无法进行类型转换 { echo $flag; } }根据对代码的解释我们可知我们要想得到flag传入的参数需要满足
相等比较不能等于4476且不能含有英文字母或小数点,要含有0且在首位不能是0
由上可得
num= 0101574或num=%0a010574
如图:
8.web96
由源代码可知我们需要传入参数u且u不能等于flag.php
highlight_file($_GET['u']由这行代码可知它会高亮显示参数u
的值所指的文件
但是我们又不能直接传入flag.php所以我们可以在flag.php之前加上当前目录./
即传入的值为./flag.php
如图:
或者也可以传入flag.php文件的绝对路径(flag.php文件的绝对路径的获取方法可以传入除了flag.php以外的其它任意值因为不存在所以会报错)如图:
然后我们就可以知道当前目录的路径(图中黑色加粗部分就是)在此基础上加上文件名flag.php即为此文件的绝对路径
如图:
9.web97
由代码可知此题是post传参要求满足a和b的值不同但是他们的md5加密结果必须完全相同
所以我们想到了使用两个不同的数组来绕过因为md5函数对于数组不能处理如果输入数组会返回空NULL
例:a[]=1&b[]=0
如图:
另一种方法:若两个字符经MD5加密后的值为 0exxxxx形式就会被认为是科学计数法,且表示的是0*10的xxxx次方则还是零都是相等的
下列的字符串的MD5值都是0e开头的:
QNKCDZO
240610708
s878926199a
s155964671a
s214587387a
s214587387a 如图:
10.web98
由代码可知这段代码主要使用了三目运算符? :来进行条件判断和赋值操作
$_GET ? $_GET = &$_POST : 'flag';由这段代码可知如果存在get传参则get所传的参数会被post参数覆盖
$_GET['flag'] == 'flag' ? $_GET = &$_COOKIE : 'flag'; $_GET['flag'] == 'flag' ? $_GET = &$_SERVER : 'flag';这两行代码对最后flag的输出没有影响因为最后源代码的显示主要看get参数HTTP_FLAG=flag是否成立
highlight_file($_GET['HTTP_FLAG'] == 'flag' ? $flag : __FILE__);
但是我们不能直接get传参HTTP_FLAG=flag因为如果get传参存在的话就会被post覆盖所以我们可以get传参任意一个数(随便传但是必须有)然后再post传参HTTP_FLAG=flag覆盖get所传参数的值便可以显示flag
如图:
11.web99
代码解析:
<?php highlight_file(__FILE__); $allow = array();//定义一个名为allow的空数组 for ($i=36; $i < 0x36d; $i++) { array_push($allow, rand(1,$i)); }//这是一个循环 i的范围是36~876(0x36d十进制是877)在这段代码中 rand(1, $i) 生成一个介于 1 和 $i 之间的随机整数 然后array_push() 函数将这个随机数添加到 $allow 数组中 if(isset($_GET['n']) && in_array($_GET['n'], $allow))//条件是get传参 参数n存在并且n的值再数组allow中存在 { file_put_contents($_GET['n'], $_POST['content']);//把content的值写入文件n 如果n不存在就新建文件n (注意:n和content均为参数且n是get传参content是post传参) } ?>由以上代码可知我们可以在当前目录新建一个文件并且在文件中写入任意的东西但是前提是传入n的值再随机数的数组中存在
因为数字随机生成的范围依次是:1~36;1~37;1~38;1~39 ···
所以我们可以猜测概率较大的数字比如:1,2,3 ···
因为可以新建文件并且可以在新建的文件中写入任意东西所以我们首先想到的就是新建php文件写入一句话木马这样就可以通过蚁剑连接来获取flag
(in_array()此函数一般情况下会把 "1.php" 视为数字 1,2.php同理
操作如图:
也可以得到文件名后直接在页面访问 如图:
12.web100
if ($v0) { if (!preg_match("/\;/", $v2)) { if (preg_match("/\;/", $v3)) { eval("$v2('ctfshow')$v3"); } } }以上代码表示只有$v0=1且v2中不能含有分号v3要有分号
$v0 = is_numeric($v1) and is_numeric($v2) and is_numeric($v3);在这段代码中只需要v1有数字即可因为赋值操作的优先级大于and
eval("$v2('ctfshow')$v3");这段代码会执行括号里的内容因此我们可以利用括号中的$v2('ctfshow')$v3来构造可以输出flag的函数
//flag in class ctfshow;由题目中的注释可知flag在ctfshow中因此我们只需要输出ctfshow即可
get传参传入?v1=1&v2=var_dump($ctfshow)/*&v3=*/;
回车即可如图:
13.web101
由代码可知这关和web100关的区别是禁用了许多符号这就说明我们无法使用注释来像上一关那样输出ctfshow
但是我们可以利用函数把类反射出来,就像是赋值一样这样直接输出这个反射类就能得到原来的类
输入:?v1=1&v2=echo new ReflectionClass&v3=;
ReflectionClass 是 PHP 中的一个内置类,用于获取类的反射信息
echo new ReflectionClass('ctfshow') 表示输出ctfshow的反射
如图:
根据以上题目所得到的flag可知此题的为flag{You have successfully completed web101}
14.web102
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=cc504438395948526859794171594473&v3=php://filter/write=convert.base64-decode/resource=1.php post: v1=hex2bin
回车然后
访问1.php后查看源代码获得flag
操作依次如图:
15.web103
103关的话加了一个php的过滤但是不起作用所以和web102一样
如图:
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。
在线投稿:投稿 站长QQ:1888636
后台-插件-广告管理-内容页尾部广告(手机) |