zoukankan      html  css  js  c++  java
  • DVWA--全等级命令注入(Command Injection)

    我们这一次来介绍的命令注入:人对计算机的操纵方式,展现出来的无非是两个方面——数据,以及操作这些数据的指令。当数据和指令都是事先预设好的,各司其职,则天下太平——人们通过指令将输入的数据进行处理,获得期望的结果后通过特定的渠道输出。但随着IT技术的飞速发展,这两者混杂在一块,没有经过良好的组织,就会被黑客加以利用,成为一种典型的攻击方式——命令注入。命令注入攻击的常见模式为:仅仅需要输入数据的场合,却伴随着数据同时输入了恶意代码,而装载数据的系统对此并未设计良好的过滤过程,导致恶意代码也一并执行,最终导致信息泄露或者正常数据的破坏。其中最常见的一类攻击行为就是针对数据库系统的SQL(结构化查询语言)注入。常见的SQL语句构成为:对符合特定条件的数据(某些行的某些列)实施增、删、改、查等操作。

    开始之前,由于在实验中遇到了乱码的问题,在这里就直接先说明一下解决的办法:

    phpstudyWWWdvwaincludes目录下找到dvwaPage.inc.php文件中所有的”charset=utf-8”,修改”charset=gb2312”,即可。

     

     

    好了话不多说,我们进入正题吧!

    Command Injection

    我们来到这个模块里面,首先看到的是让我们输入一个ip地址,原来是一个ping的指令,那么到底是真怎么回事呐?我们应该怎么做呐。

    LOW

    我们先尝试ping一下自己主机的IP看看现象:

     我们再看一下源码,感觉会有思路的:

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

    是不是发现了很多的新东西,在这里我们先来将小知识先补习一下吧!

    函数知识补充:

    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参数并未做任何的过滤,导致了严重的命令注入漏洞

    命令知识补充:

    在操作系统中,"  &  、&& 、|  、 ||   "都可以作为命令连接符使用

    A&&B:先执行A,若成功的话就执行B,否则不会执行。

    A&B: 无论A是否成功,都执行B.

    A||B:只有执行A的时候失败了,才去执行B。

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

    &&  与 &  的区别:

    所以这些都知道了之后,那么就来实验一下吧!

    1、我们可以用“&”符号:127.0.0.1&net user来查看用户的系统:接下来我们就可以通过获取的信息来对用户内的信息进行操作。

     2、我们可以用指令127.0.0.1 & net user li /add 来进行用户的创建。

    Medium

    查看源代码:

     1 <?php
     2  
     3 if( isset( $_POST[ 'Submit' ]  ) ) {
     4     // Get input
     5     $target = $_REQUEST[ 'ip' ];
     6     // Set blacklist
     7     $substitutions = array(
     8         '&&' => '',
     9         ';'  => '',
    10     );
    11     // Remove any of the charactars in the array (blacklist).
    12     $target = str_replace( array_keys( $substitutions ), $substitutions, $target );
    13  
    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  
    27 ?> 

    通过源码分析,我们发现难度级别是真的增加了,对&&和;进行了过滤,但并未过滤&,|,||。所以破解点就出来了。

    输入192.168.24.140&net user,进行注入

     其实还有另外一种方法,因为会对命令进行单次过滤,所以我么可以用命令192.168.24.140&;&net user,最后过滤;就成为了192.168.24.140&&net user也会成功!

    High

    查看源代码:

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

    代码进一步完善了过滤名单,但是仔细观察‘| ’替换为空格,后面还有一个空格,所以‘|’就可以利用。

    192.168.24.140|net user      ”|”是管道符,意思是将前者处理后的结果作为参数传给后者    所以前面的ip不存在也可以!

    Impossible

    查看源码:

     1 <?php
     2 
     3 if( isset( $_POST[ 'Submit' ]  ) ) {
     4     // Check Anti-CSRF token
     5     checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
     6 
     7     // Get input
     8     $target = $_REQUEST[ 'ip' ];
     9     $target = stripslashes( $target );
    10 
    11     // Split the IP into 4 octects
    12     $octet = explode( ".", $target );
    13 
    14     // Check IF each octet is an integer
    15     if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {
    16         // If all 4 octets are int's put the IP back together.
    17         $target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];
    18 
    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 
    29         // Feedback for the end user
    30         echo "<pre>{$cmd}</pre>";
    31     }
    32     else {
    33         // Ops. Let the user name theres a mistake
    34         echo '<pre>ERROR: You have entered an invalid IP.</pre>';
    35     }
    36 }
    37 
    38 // Generate Anti-CSRF token
    39 generateSessionToken();
    40 
    41 ?> 

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

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

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

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

  • 相关阅读:
    LeetCode 275. H-Index II
    LeetCode 274. H-Index
    LeetCode Gray Code
    LeetCode 260. Single Number III
    LeetCode Word Pattern
    LeetCode Nim Game
    LeetCode 128. Longest Consecutive Sequence
    LeetCode 208. Implement Trie (Prefix Tree)
    LeetCode 130. Surrounded Regions
    LeetCode 200. Number of Islands
  • 原文地址:https://www.cnblogs.com/li2019/p/12617636.html
Copyright © 2011-2022 走看看