DVWA系列(四)----Command Injection (命令行注入)

一、攻击模块2:Command Injection(命令注入)

命令注入攻击的常见模式为:仅仅需要输入数据的场合,却伴随着数据同时输入了恶意代码,而装载数据的系统对此并未设计良好的过滤过程,导致恶意代码也一并执行,最终导致信息泄露或者正常数据的破坏。

PHP命令注入攻击漏洞是php应用程序中常见的脚本漏洞之一,国内著名的Web应用程序Discuz!、DedeCMS等都曾经存在过该类型漏洞。

二、源码分析

1.Low(低)级别

[html] view plain copy

  1. <?php
  2. if( isset( $_POST[ ‘Submit‘ ]  ) ) {
  3. // Get input
  4. $target = $_REQUEST[ ‘ip‘ ];
  5. // Determine OS and execute the ping command.
  6. if( stristr( php_uname( ‘s‘ ), ‘Windows NT‘ ) ) {
  7. // Windows
  8. $cmd = shell_exec( ‘ping  ‘ . $target );
  9. }
  10. else {
  11. // *nix
  12. $cmd = shell_exec( ‘ping  -c 4 ‘ . $target );
  13. }
  14. // Feedback for the end user
  15. echo "<pre>{$cmd}</pre>";
  16. }
  17. ?>

相关函数介绍

stristr(string,search,before_search)

stristr函数搜索字符串在另一字符串中的第一次出现,返回字符串的剩余部分(从匹配点),如果未找到所搜索的字符串,则返回 FALSE。参数string规定被搜索的字符串,参数search规定要搜索的字符串(如果该参数是数字,则搜索匹配该数字对应的 ASCII 值的字符),可选参数before_true为布尔型,默认为“false” ,如果设置为 “true”,函数将返回 search 参数第一次出现之前的字符串部分。

php_uname(mode)

这个函数会返回运行php的操作系统的相关描述,参数mode可取值

”a” (此为默认,包含序列”s n r v m”里的所有模式)

”s ”(返回操作系统名称)

”n”(返回主机名)

”r”(返回版本名称)

”v”(返回版本信息)

”m”(返回机器类型)
可以看到,服务器通过判断操作系统执行不同ping命令,但是对ip参数并未做任何的过滤,导致了严重的命令注入漏洞。

漏洞利用

window和Linux系统都可以用&&来执行多条命令

127.0.0.1&&net user

命令连接符

command1 && command2   先执行command1后执行command2
command1 | command2     只执行command2
command1 & command2    先执行command2后执行command1

以上三种连接符在windows和linux环境下都支持

如果程序没有进行过滤,那么我们就可以通过连接符执行多条系统命令。

2.Medium(中)级别

[html] view plain copy

  1. <?php
  2. if( isset( $_POST[ ‘Submit‘ ]  ) ) {
  3. // Get input
  4. $target = $_REQUEST[ ‘ip‘ ];
  5. // Set blacklist
  6. $substitutions = array(
  7. ‘&&‘ => ‘‘,
  8. ‘;‘  => ‘‘,
  9. );
  10. // Remove any of the charactars in the array (blacklist).
  11. $target = str_replace( array_keys( $substitutions ), $substitutions, $target );
  12. // Determine OS and execute the ping command.
  13. if( stristr( php_uname( ‘s‘ ), ‘Windows NT‘ ) ) {
  14. // Windows
  15. $cmd = shell_exec( ‘ping  ‘ . $target );
  16. }
  17. else {
  18. // *nix
  19. $cmd = shell_exec( ‘ping  -c 4 ‘ . $target );
  20. }
  21. // Feedback for the end user
  22. echo "<pre>{$cmd}</pre>";
  23. }
  24. ?>

相比Low级别的代码,服务器端对ip参数做了一定过滤,即把”&&” ,”;”删除,本质上采用的是黑名单机制,因此依旧存在安全问题。

漏洞利用

1、127.0.0.1&net user

因为被过滤的只有”&&”与”    ;”,所以”&”不会受影响。

这里需要注意的是”&&”与”    &”的区别:

Command 1&&Command 2
先执行Command 1,执行成功后执行Command 2,否则不执行Command 2

Command 1&Command 2
先执行Command 1,不管是否成功,都会执行Command 2

2、由于使用的是str_replace把”&&”,”;”替换为空字符,因此可以采用以下方式绕过:

127.0.0.1&;&ipconfig

这是因为”127.0.0.1&;&ipconfig”中的” ;”会被替换为空字符,这样一来就变成了”127.0.0.1&& ipconfig” ,会成功执行。

3.High(高)级别 

[html] view plain copy

  1. <?php
  2. if( isset( $_POST[ ‘Submit‘ ]  ) ) {
  3. // Get input
  4. $target = trim($_REQUEST[ ‘ip‘ ]);
  5. // Set blacklist
  6. $substitutions = array(
  7. ‘&‘  => ‘‘,
  8. ‘;‘  => ‘‘,
  9. ‘| ‘ => ‘‘,
  10. ‘-‘  => ‘‘,
  11. ‘$‘  => ‘‘,
  12. ‘(‘  => ‘‘,
  13. ‘)‘  => ‘‘,
  14. ‘`‘  => ‘‘,
  15. ‘||‘ => ‘‘,
  16. );
  17. // Remove any of the charactars in the array (blacklist).
  18. $target = str_replace( array_keys( $substitutions ), $substitutions, $target );
  19. // Determine OS and execute the ping command.
  20. if( stristr( php_uname( ‘s‘ ), ‘Windows NT‘ ) ) {
  21. // Windows
  22. $cmd = shell_exec( ‘ping  ‘ . $target );
  23. }
  24. else {
  25. // *nix
  26. $cmd = shell_exec( ‘ping  -c 4 ‘ . $target );
  27. }
  28. // Feedback for the end user
  29. echo "<pre>{$cmd}</pre>";
  30. }
  31. ?>

相比Medium级别的代码,High级别的代码进一步完善了黑名单,但由于黑名单机制的局限性,我们依然可以绕过。

漏洞利用

黑名单看似过滤了所有的非法字符,但仔细观察到是把”| ”(注意这里|后有一个空格)替换为空字符,于是    ”|” 就有用了。

127.0.0.1|net user

Command 1 | Command 2

“|”是管道符,表示将Command 1的输出作为Command 2的输入,并且只打印Command 2执行的结果。

4.Impossible(不可能的)级别

[html] view plain copy

  1. <?php
  2. if( isset( $_POST[ ‘Submit‘ ]  ) ) {
  3. // Check Anti-CSRF token
  4. checkToken( $_REQUEST[ ‘user_token‘ ], $_SESSION[ ‘session_token‘ ], ‘index.php‘ );
  5. // Get input
  6. $target = $_REQUEST[ ‘ip‘ ];
  7. $target = stripslashes( $target );
  8. // Split the IP into 4 octects
  9. $octet = explode( ".", $target );
  10. // Check IF each octet is an integer
  11. if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {
  12. // If all 4 octets are int‘s put the IP back together.
  13. $target = $octet[0] . ‘.‘ . $octet[1] . ‘.‘ . $octet[2] . ‘.‘ . $octet[3];
  14. // Determine OS and execute the ping command.
  15. if( stristr( php_uname( ‘s‘ ), ‘Windows NT‘ ) ) {
  16. // Windows
  17. $cmd = shell_exec( ‘ping  ‘ . $target );
  18. }
  19. else {
  20. // *nix
  21. $cmd = shell_exec( ‘ping  -c 4 ‘ . $target );
  22. }
  23. // Feedback for the end user
  24. echo "<pre>{$cmd}</pre>";
  25. }
  26. else {
  27. // Ops. Let the user name theres a mistake
  28. echo ‘<pre>ERROR: You have entered an invalid IP.</pre>‘;
  29. }
  30. }
  31. // Generate Anti-CSRF token
  32. generateSessionToken();
  33. ?>

相关函数介绍

stripslashes(string)

stripslashes函数会删除字符串string中的反斜杠,返回已剥离反斜杠的字符串。

explode(separator,string,limit)
把字符串打散为数组,返回字符串的数组。参数separator规定在哪里分割字符串,参数string是要分割的字符串,可选参数limit规定所返回的数组元素的数目。

is_numeric(string)
检测string是否为数字或数字字符串,如果是返回TRUE,否则返回FALSE。

可以看到,Impossible级别的代码加入了Anti-CSRF token,同时对参数ip进行了严格的限制,只有诸如“数字.数字.数字.数字”的输入才会被接收执行,因此不存在命令注入漏洞。

时间: 2024-08-08 13:17:28

DVWA系列(四)----Command Injection (命令行注入)的相关文章

安全性测试入门(二):Command Injection命令行注入攻击和防御

安全性测试入门(二):Command Injection命令行注入攻击和防御 本篇继续对于安全性测试话题,结合DVWA进行研习. Command Injection:命令注入攻击. 1. Command Injection命令注入 命令注入是通过在应用中执行宿主操作系统的命令,来达到破坏目的的一种攻击方式.如果我们的应用程序将不安全的用户输入传递给了系统命令解析器(shell),那么命令攻击就有可能发生. 通常来说,由应用程序传递操作系统命令会赋有和应用一样的权限,所以如果没有合理防御机制会给系

dvwa全等级命令行注入

1.LOW等级命令行注入 在低等级的命令行注入没有任何的过滤,通过查看源码可以得知, step1:使用ping 127.0.0.1&&dir可以得出如下结果 step2:使用 ping127.0.0.1&net user可以得到如下运行结果 step3:使用ping 127.0.0.1|dir可以得到如下结果 ps:在这里有必要说一下逻辑运算符“&”和“|”都是什么意思 &&:代表首先执行命令a在执行命令b,但是前提条件是命令a执行正确才会执行命令b,在a执

(二)NS3如何编译、运行脚本和 Command Line命令行参数设置

二.编译.运行脚本和Command Line命令行参数设置 7. 编译和运行脚本主要步骤 1) 将编写的脚本复制到ns-3.22/scratch目录下(可以在ubuntu窗口界面直接复制) 进入ns3目录: /ns-3.22 $ cp examples/tutorial/first.cc  scratch/myfirst.cc将脚本复制到scratch目录下 2) 构建(编译) $ ./waf 3) 运行 $ ./waf --run scratch/myfirst (可能会有运行权限问题,可在r

Command Injection(命令行注入)

实战部分: 说明:这里我用的是OWASP的一个平台和DVWA 下面简单说一下安装方法(windows下):     先下载webscarab-current.zip(这个自带tomcat,还有一个下载方式是war文件,需要自己安装tomcat,建议使用第一个),地址为http://www.owasp.org/index.php/Category:OWASP_WebGoat_Project,解压到一个文件夹,运行webgoat.bat即可启动其自带的tomcat,通过访问http://localh

[Android] 基于 Linux 命令行构建 Android 应用(四):命令行构建

谷歌提供的 Android SDK 支持 Ant 自动构建[1],你可以使用调试和发行两种模式进行构建,两种模式不同之处在于调试模式 Ant 会调用内置的调试密钥,而发行模式调用你提供的私钥. 首先安装 Ant,并且将它添加到你的执行路径 PATH 里[2]. 调试模式构建 在调试模式下,Ant 会自动使用一个调试密钥对你的安卓应用进行签名,并且使用 zipalign 进行优化. 要进行调试模式下的构建,首先在命令行进入安卓项目根目录,然后使用 Ant 启动调试模式构建: $ ant debug

Golang系列文章:打印命令行参数

记得最早在学校机房学习Java时,写一个最简单main方法,当程序运行并在屏幕上打印出hello world时,内心还有些小激动呢,相信很多人都有这种经历吧.今天想借助命令行程序,总结一下Go语言的基础知识点. 首先,来一个Go语言版的hello world: // hello.go package main import "fmt" func main() { fmt.Println("hello world") } 我们可以直接在命令行执行下面的命令来运行该程序

DVWA系列之2 low级别SQL注入

将Security level设为on,在左侧列表中选择"SQL Injection",然后在右侧的"User ID"文本框中输入不同的数字就会显示相应的用户信息. 我们首先需要判断这里所传输的参数是文本型还是数字型,分别输入3和1+2,观察它们显示的结果并不一致,因而就判断出参数类型是文本型. 点击页面右下角的"View Source"可以查看源代码,其中最重要的是如下图所示的两行语句: 第一行是以GET方式获取用户通过id参数传来的值并赋值给

设计模式之(Command)命令行模式

1.需求 为一个开关设计程序,这个开关有N按钮,同时对应N个插槽,要求可以接入任何电器厂商的API,从而可以控制任何电器.目前只有电灯和电视两种电器,要求写一个Demo程序,按钮1可以打开电灯.按钮2可以打开电视并且切换到上一次打开的频道.打开电视换频道需要打开机顶盒并且对机顶盒切换频道. 2. 分析 每个厂商的API不一致,且每个电器的打开流程都不一样,我们需要将这些差异封装起来,才可以实现新增电器时不需要修改开关程序. 3. 类图 4. 总结 上面的例子主要通过Command模式将执运算块(

DVWA系列之3 medium级别SQL注入

将"DVWA Security"设置为medium中等级别,首先点击右下角的"View Source"查看此时的网页源码,主要观察与low级别的区别. 可以发现,这里对用户输入的id参数进行了过滤,主要方法是使用了mysql_real_escape_string()函数,这个函数可以将$id变量中的单引号'.双引号".斜杠\等字符进行转义,因而我们再输入之前的"'or 1=1 #"就会报错了,从错误提示中可以发现单引号'已经被转义成了\