【CTFshow】Web入门-php特性(一)(89-115) wp
前言
感觉了解php特性是基础,所以决定先做这部分。
Web89(preg_match和intval)
两步,绕过正则,intval不为0。采取传入数组的方式绕过:
preg_match()只能处理字符串,如果处理数组会返回false;intval如果传入数组,会返回1。payload:
?num[]=1
Web90(intval)
intval处理开头是数字的字符串时,返回值为开头的数,这个大家都比较熟悉了。payload:
?num=4476a
Web91(正则匹配多行模式)
本题中的正则:^表示表达式开头,$表示表达式结尾,i表示不区分大小写,m表示多行模式,这个多行模式具体是什么意思呢,看一下下面的结果:
上面两幅图中,左边的输出结果是no,右边的输出结果是success。所以多行模式的意思是每一行都进行正则匹配。右侧图中,第一行末尾为php,所以返回了true;左侧没开启多行,虽然有\n但也只有一行。所以本题的第一个正则是要求分行后至少有一行是字符串"php",第二个正则只能匹配字符串"php",所以传一个:
?cmd=php%0aphp //或aaa%0aphp,php%0abbb都可
这里还要说一下,URL的换行符是%0a,\n不起换行作用,因为URL编码中斜杠并不是转义字符,\n只是普通的字符串而已。
Web92(intval)
第一个判断变成弱类型比较,所以不能用4476a绕过。重点是intval的第二个参数base,base=0时,intval会自动探测num的进制:
如果num以0x开头,那么按16进制转换;如果num以0开头,默认按8进制转换;否则使用10进制。
所以这个题用16进制绕过即可,payload:
?num=0x117c
第一个弱类型会把0x117c转成0,绕过比较,第二个会进行进制转换,判断通过。
Web93(intval)
和上一题相比,这道题加了个正则匹配,不能出现字母,使用8进制绕过即可。在进行弱类型比较的时候,'010574'==10574。
Web94(intval)
时刻要注意num是个字符串,只要在4476后面用字符截断,即可绕过弱类型比较。关键是多了个strpos,这个函数的位置很巧妙,它要求num中必须有0,但还不能在开头,所以传入一个浮点数:
?num=4476.0
强类型比较通过,正则通过,含0且不在头部,intval转换后是4476,拿到flag。
Web95(intval)
多过滤了一个点,可以用8进制前面加个+绕过。在反序列化绕过正则时也有相似应用。intval接收'+4476'还是会转为4476。
关于intval的常见输出
Web96(按路径读取文件)
想办法读取flag.php,但还不能直接传flag.php,这里我们利用路径问题来读,传入payload:
?u=./flag.php
利用路径绕过比较。
Web97(md5函数漏洞)
md5函数是不能处理数组的,处理数组会返回null,所以传两个数组进去,null===null,成功绕过。
Web98(审计,传参,取址运算符)
什么卵代码,搜一下。
php中取值运算符"&"表示引用,比如$b=&$a表示变量b是变量a的一个引用,相当于同一个变量两个名字,一个变化另一个也跟着变化。通常的赋值语句$b=$a相当于copy了一个a的副本给b,b变化a不变化。取址就相当于把根刨了。
第一句:如果传入get参数,则get参数变成post的参数。
第二句:如果get的flag参数等于字符串"flag",那么get的参数变成cookie的参数。
第三句:如果get的flag参数等于字符串"flag",那么get的参数变成server的参数。
第四句:如果get传入HTTP_FLAG参数的值是字符串"flag",那么高亮显示$flag变量对应的文件,否则就是当前文件。
分析完之后发现很简单,只要get一个HTTP_FLAG变量就好了,但是get会变成post啊,所以保证post一个HTTP_FLAG=flag。至于get就随便get一个,不能不get,不get不能触发第一条语句的。
Web99(审计,in_array)
先了解一下这些个函数:
- array():创建一个数组
- array_push():将一个或多个元素插入数组末尾(入栈)
- in_array():检查数组中是否存在指定元素,第三个参数strict不指定默认为宽松比较
- file_put_contents():将数据写入文件中,相当于fopen()+fwrite()+fclose()
这里就要用到in_array的漏洞了,如果我们传递n=1.php,那么根据宽松比较'1.php'==1,是可以绕过的。get一个n=1.php,向其中写入一句话木马<?php @eval($_POST[1]);?>,蚁剑连接即可。
php中关于array的函数可以参考:https://www.w3school.com.cn/php/php_ref_array.asp
Web100(逻辑运算符优先级)
又添新知识了,最开始我一直以为考点在绕过is_numeric,后来发现自己错了,考点在这里:
逻辑运算符的优先级:"&&" > "||" > "=" > "and",等号的优先级高于and,所以v0只跟v1有关系,v2和v3是干扰。
然后就是怎么构造eval内部的语句,我们不能直接输出字符串,应该输出$ctfshow的值,所以利用v2和v3的位置把给的这个括号注释掉,payload:
?v1=1&v2=var_dump($ctfshow)/*&v3=*/;
Web101(反射API)
什么东西一大片,不会。求助hint和wp,得知php有个反射类(我对面向对象不是很熟悉)。
反射,通俗来讲就是可以通过一个对象来获取所属类的具体内容,php中内置了强大的反射API:
- ReflectionClass:一个反射类,功能十分强大,内置了各种获取类信息的方法,创建方式为new ReflectionClass(str 类名),可以用echo new ReflectionClass('className')打印类的信息。
- ReflectionObject:另一个反射类,创建方式为new ReflectionObject(对象名)。
本题中继续传入v1=1,v2=echo ReflectionClass来获取类的信息,v3=;闭合语句。
Web102(回调函数,短标签内敛执行)
call_user_func():把第一个参数作为回调函数使用,后面的参数是这个函数的参数。返回调用函数的返回值。其实就是一种特殊的调用函数的方式。
file_put_contents():把一个字符串写入文件,如果文件不存在则创建之。
payload:
GET:
?v2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=1.php
POST:
v1=hex2bin
php短开标签
<?=(表达式)?>等价于<?php echo (表达式)?>
Web103(回调函数,短标签内敛执行)
多了一个正则过滤,但是用上一题的payload就可以。
Web104(Hash函数)
你有没有发现,这里没有要求v1和v2不相等......
Web105(变量覆盖,$$可变变量)
这里涉及到两个美元符$$,这种变量叫可变变量,最直观的理解:
输出结果是world,$$a就相当于是$($a)=$hello。
我们可以发现要想输出最终的flag变量,要满足两个foreach和一个if,先看一下这个if,它要求post的flag值与已知flag变量相等,这显然是无法做到的。因为一旦flag值被传入,第二个foreach就会执行$$key=$$value,使得$flag发生改变,这样flag就输不出来了。
所以最终的解决办法是触发if条件,修改error,也就是将error修改为flag。但注意我们无法直接传入error=flag,因为get和post都限制了值,所以需要转换一下:
GET: ?suces=flag POST: error=suces
搞定。
Web106(Hash函数)
居然是接104的,这回限制了v1和v2不相等,像md5一样找0e吧。用104的hint:
aaK1STfY 0e76658526655756207688271159624026011393 aaO8zKZF 0e89257456677279068558073954252716165668
Web107(parse_str函数)
首先介绍parse_str(string, array)函数:string字符串会传入一组或多组键值对,将其解析并保存到array中。eg:
parse_str("a=1&b=2", $arr)
此时arr数组就是{"a"=>1, "b"=>2}这种字典对应。
所以这个题非常简单了,payload:
GET:
v3=1
POST:
v1=flag=c4ca4238a0b923820dcc509a6f75849b
搞定。
Web108(ereg截断漏洞)
ereg函数存在00截断漏洞,可以用a%00匹配正则,之后需要翻转化整数,0x36d的十进制是877,倒转传入即可,payload:
?c=a%00778
Web109(内置类 _toString方法)
能直接echo类,说明这个类一定有_toString方法,找到符合条件的异常类Exception以及反射类ReflectionClass。
php有类似于python的函数式编程,$a='phpinfo',那么$a()就相当于phpinfo(),进行函数调用。
v2这里传个语句进去会先执行再报错。payload:
?v1=Exception&v2=system(ls)
?v1=ReflectionClass&v2=system(ls)
Web110(内置类 FilesystemIterator)
还是这样的过滤,这回用FilesystemIterator类,析构方法的参数是目录,我们用getcwd方法获取当前目录传入FilesystemIterator遍历当前目录下文件。
除此之外可以用DirectoryIterator遍历目录。发现目录下有个fl36dga.txt文件,事实上我们可以直接访问这个文件,不需要千方百计去读取它的内容。
Web111(超全局变量)
看着getFlag就像是个赋值并输出,v1要有ctfshow,那就传一个ctfshow,主要是输出v2的值,题目中也没有任何明显提示,就只能GLOBALS把所有全局变量全输出来,正好var_dump是可以输出数组的。
?v1=ctfshow&v2=GLOBALS
Web112(is_file函数)
有个过滤器filter,过滤掉了一些东西,先不管它,主要是后面的is_file判断,要求传入的file不是文件,但还能highlight_file,这就要说明is_file和highlight_file对于文件的判断:is_file认为伪协议不是文件,highlight_file认为伪协议是文件,所以这里传入filter伪协议即可。至于flag具体在哪,就试一试吧,比如flag.php。
Web113(is_file函数)
过滤了filter,放出了input,那就input。可以去查一查各种php封装和包含的协议,挨个看看能不能用,实际上这里使用zlib可以输出。Hint给出的目录溢出会使is_file判断其不是文件,而highlight_file会正常识别。
Web114(is_file函数)
又把filter放出来了,直接读即可。
Web115(trim函数)
filter让我们没法转进制绕过,这道题的关键在于如何绕过trim,推测需要特殊字符,所以我们写个脚本fuzz一下:
payload:?num=%0c36
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现