2018-10-22-BWAPP注入篇

一.HTML注入
注入原理:服务端未对用户输入进行严格过滤导致,只要在可以接收用户输入的地方输入html标签,由于服务端为进行html编码,导致html标签可被浏览器解析执行,导致出现问题.
1.GET类型注入
服务端代码如下:

if(isset($_GET["firstname"]) && isset($_GET["lastname"]))//isset函数检测变量是否为空
    {   
        $firstname = $_GET["firstname"];
        $lastname = $_GET["lastname"];    

        if($firstname == "" or $lastname == "")
        {
            //firstname和lastname有一个为空就输出这句话
            echo "Please enter both fields...";       
        }
        else            
        { 
            //firstname和lastname都不为空才输出过滤后的firstname和lastname
            echo "Welcome " . htmli($firstname) . " " . htmli($lastname);   
        }
    }

对应的过滤代码htmli函数如下:

function htmli($data)
{
    switch($_COOKIE["security_level"])
    {
         //对应security_level为low
        case "0" : 
            $data = no_check($data);            
            break;
        //对应security_level为medium
        case "1" :
            $data = xss_check_1($data);
            break;
        //对应security_level为high
        case "2" :            
            $data = xss_check_3($data);            
            break;
        default : 
            $data = no_check($data);            
            break;   
    }       
    return $data;
}

A: Level Low
对应的xss_check_0的源代码如下所示:

function no_check($data)
{    
    return $data;//不做任何检查直接原样返回
}

输入payload如下所示:

First name:vivo//marquee起到滚动作用
Last name:vivo

效果如下所示:


图一

黑体的vivo点击以后会直接跳到百度首页.

B:Level Medium
对应的xss_check_1的源代码如下所示:

function xss_check_1($data)
{
    // Converts only "<" and ">" to HTML entities    
    $input = str_replace("<", "<", $data);
    $input = str_replace(">", ">", $input);

    // Failure is an option
    // Bypasses double encoding attacks   
    // 
    // %3Cscript%3Ealert%280%29%3C%2Fscript%3E
    // %253Cscript%253Ealert%25280%2529%253C%252Fscript%253E
    $input = urldecode($input);
    return $input;
}

这段代码的意义在于把输入中的大于号以及小于号进行html实体编码变成<和>,但是问题的关键是最后他进行了url解码,这样就出现一个问题,先进行url解码,然后不会被html编码,后面又进行url解码就还原出来了.

payload:%3cscript%3ealert(1)%3c%2fscript%3e
图二

C:Level High
对应的xss_check_2源代码如下所示:

function xss_check_3($data, $encoding = "UTF-8")
{
    // htmlspecialchars - converts special characters to HTML entities    
    // '&' (ampersand) becomes '&' 
    // '"' (double quote) becomes '"' when ENT_NOQUOTES is not set
    // "'" (single quote) becomes ''' (or ') only when ENT_QUOTES is set
    // '<' (less than) becomes '<'
    // '>' (greater than) becomes '>'  
    return htmlspecialchars($data, ENT_QUOTES, $encoding);//ENT_QUOTES - 编码双引号和单引号,默认是不设置的,记得是 & , ' , " , < , >.
}

这种情况下很难绕过了,等以后知识再进一步丰富再来研究.

2.POST类型注入
服务端代码和html过滤函数代码都同GET类型一样,防御代码也一样,只是把参数传递方式换成post而已,其他做法没啥变化.

3.Current URL类型注入
服务端代码如下:

switch($_COOKIE["security_level"])
{
    case "0" :
        // $url = "http://" . $_SERVER["HTTP_HOST"] . urldecode($_SERVER["REQUEST_URI"]);
        $url = "http://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];               
        break;
    case "1" :
        $url = "";
        break;
    case "2" :
        $url = "http://" . $_SERVER["HTTP_HOST"] . xss_check_3($_SERVER["REQUEST_URI"]);
        break;
    default :
        // $url = "http://" . $_SERVER["HTTP_HOST"] . urldecode($_SERVER["REQUEST_URI"]);
        $url = "http://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];               
        break;
}

A:Level Low
Level Low是采用拼接的方式,从host字段中取出值并拼接成current_url,所以只要直接改了host字段就可以了.


图三

图四

B:Level Medium
Document.url返回当前文档的url,document.write可向文档中写入 HTML 表达式或 JavaScript 代码.

C: Level High
xss_check_3的代码如下所示:

function xss_check_3($data, $encoding = "UTF-8")
{
    // htmlspecialchars - converts special characters to HTML entities    
    // '&' (ampersand) becomes '&' 
    // '"' (double quote) becomes '"' when ENT_NOQUOTES is not set
    // "'" (single quote) becomes ''' (or ') only when ENT_QUOTES is set
    // '<' (less than) becomes '<'
    // '>' (greater than) becomes '>'  
    
    return htmlspecialchars($data, ENT_QUOTES, $encoding);//进行了html实体编码,对',",<,>,&符号进行编码,ENT_QUOTES设置了',"同样有效.
}

4.HTML Injection Blog
服务端代码如下所示:

function htmli($data)
{
    include("connect_i.php");
    switch($_COOKIE["security_level"])
    {
        case "0" :
            $data = sqli_check_3($link, $data);
            break;
        case "1" :
            $data = sqli_check_3($link, $data);
            // $data = xss_check_4($data);
            break;
        case "2" :
            $data = sqli_check_3($link, $data);
            // $data = xss_check_3($data);
            break;
        default :
            $data = sqli_check_3($link, $data);
            break;
    }
    return $data;
}

这服务端代码有点奇怪,不论那个安全等级都是由sqli_check_3进行过滤,所以直接补上sqli_check_3代码如下:

 function sqli_check_3($link, $data)
 {    
     return mysqli_real_escape_string($link, $data);     
 }//该函数对SQL 语句中使用的字符串中的特殊字符进行转义,以下字符收到影响, \x00, \n, \r, \, ', ", \x1a

但是经过实测发现,low level并没有任何防御,而medium以及high等级应该是mysqli_real_escape_string函数过滤了,不存在啥可以绕过的条件.

二.SMTP注入
先直接上服务端源代码如下

$email = "";
$recipient = $smtp_recipient;
$subject = "bWAPP - Mail Header Injection (SMTP)";
$message = "";
// $debug = "false";
if(isset($_POST["form"]))
{
    // E-mail validation if the security level is MEDIUM or HIGH
    if(!email_check_2($_POST["email"]) && ($_COOKIE["security_level"] == "1" || $_COOKIE["security_level"] == "2"))
    {
        $message = "Enter a valid e-mail address!";
    }
    else
    {
        // If the SMTP server is blank, then the default SMTP server is set (php.ini)
        if($smtp_server != "")
        {
            ini_set( "SMTP", $smtp_server);
            //Debugging
            // $debug = "true";
        }
        // HIGH security level
        if($_COOKIE["security_level"] == "2")
        {
            $email = maili_check_2($_POST["email"]);
            // Debugging
            // $email = "[email protected]\r\nCc:[email protected]";
        }
        else
        {       
            $email = $_POST["email"];
            // Debugging
            // $email = "[email protected]\r\nCc:[email protected]";
        }
        // Formatting the message body
        $content =  "Content:\n\n";
        $content .= "Name: " . $_POST["name"] . "\n";
        $content .= "E-mail: " . $email . "\n";
        $content .= "Remarks: \n";
        $content .= $_POST["remarks"] . "\n\n";
        $content .= "Greets from bWAPP!";
        // Sends the e-mail
        $status = @mail($recipient, $subject, $content, "From: $email");
        if($status != true)
        {
            $message = "An e-mail could not be sent...";
            // Debugging
            // die("Error: mail was NOT send");
            // echo "Mail was NOT send";
        }
        else
        {
            $message = "Your message has been sent to our master bee!";
            // Debugging
            // echo "e-mail: ".$email;
            // echo "
"; // echo "SMTP server: ". $debug; } } }

这里介绍一个参考链接:http://www.freebuf.com/articles/web/14918.html

A: Level Low
这个等级没有进行任何的过滤措施,因此可以直接注入smtp,其实也就是改变发件人,主题,正文等等而已.


图五

Level medium以及Level High找不到过滤部分的源代码,经测试实践中是没经过过滤的.

三.命令注入
1.系统命令注入
先上服务端代码如下所示:

function commandi($data)
{
    switch($_COOKIE["security_level"])
    {
        case "0" :
            $data = no_check($data);
            break;
        case "1" :
            $data = commandi_check_1($data);
            break;
        case "2" :
            $data = commandi_check_2($data);
            break;
        default :
            $data = no_check($data);
            break;
    }
    return $data;
}
?>

A:Level Low
根据服务端代码可知道没有进行任何防御,因此直接上&&符号执行代码就行了.


图六

B:Level Medium
防御代码如下所示:

function commandi_check_1($data)
{
    
    $input = str_replace("&", "", $data);
    $input = str_replace(";", "", $input);
    
    return $input;
    //显然把&符号以及;给过滤掉了,没事,还有|符号
}
图七

C:Level High
防御代码如下所示:

function commandi_check_2($data)
{    
    return escapeshellcmd($data);     
}//该函数把所有可能造成命令注入的符号进行转义,而在win平台上,则是被空格代替

2.命令注入盲注
先上服务端代码如下:

function commandi($data)
{
    switch($_COOKIE["security_level"])
    {
        case "0" :
            $data = no_check($data);
            break;
        case "1" :
            $data = commandi_check_1($data);
            break;
        case "2" :
            $data = commandi_check_2($data);
            break;
        default :
            $data = no_check($data);
            break;
    }
    return $data;
}
?>

A:Level Low
Level Low的命令注入方法和前面并无不同,差别在于完全没有任何返回信息,因此命令执行了没有你是不知道的,需要通过一些手段来判别.这里有一种根据返回时间来判别的方法.https://www.cnblogs.com/hongren/p/7169083.html
其他的我觉得可以用netcat反弹以及bash反弹来尝试有没有执行成功,但是发现并没有反弹回来,其他命令执行了也没任何回显,网上别人的文章都是能反弹成功的...这就尴尬了.....

Level medium以及Level high的防御代码和前面是一样的,就不重复了.

四.php代码注入
服务端代码如下:

}//低等级执行命令,将message之后的代码打印出来 // If the security level is MEDIUM or HIGH else {

//高等级和中等级要进行特殊字符的html实体编码 } } ?>

从代码中可以看出他接收message的值,然后echo,echo这里用了eval函数,低等级没进行过滤,从而存在问题.


图八

Level Medium以及Level High进行编码,虽然没啥卵用,但是由于没出现eval函数,就没问题了.

五.server-side includes injection (ssi)
废话少说,服务端代码如下:

Hello ' . $firstname . ' ' . $lastname . ',

Your IP address is:' . '

'; // Writes a new line to the file $fp = fopen("ssii.shtml", "w"); fputs($fp, $line, 200); fclose($fp); header("Location: ssii.shtml");//header() 函数向客户端发送原始的 HTTP 报头 exit; } } ?>

该段代码接收了用户输入的用户名和密码以后,直接根据安全等级过滤输入,然后把输入写入html文件中,再从html文件取出消息头部向客户端发送响应.

A:Level Low
低等级没有进行任何的防护,因此直接加上

//sqli_8-2.php源代码如下所示:
login;
    $secret = $xml->secret;//获取xml中的内容
    if($login && $login != "" && $secret)
    {
        $sql = "UPDATE users SET secret = '" . $secret . "' WHERE login = '" . $login . "'";//注入点就在这里
        // Debugging
        // echo $sql;      
        $recordset = $link->query($sql);
        if(!$recordset)
        {
            die("Connect Error: " . $link->error);
        }
        $message = $login . "'s secret has been reset!";
    }
    else
    {
        $message = "An error occured!";
    }
}
// If the security level is MEDIUM or HIGH
else
{
    // Disables XML external entities. Doesn't work with older PHP versions!
    // libxml_disable_entity_loader(true);
    $xml = simplexml_load_string($body);
    
    // Debugging
    // print_r($xml);
    $login = $_SESSION["login"];
    $secret = $xml->secret;
    if($secret)
    {
        $secret = mysqli_real_escape_string($link, $secret);//中高等级上转义函数
        $sql = "UPDATE users SET secret = '" . $secret . "' WHERE login = '" . $login . "'";
        // Debugging
        // echo $sql;      
        $recordset = $link->query($sql);
        if(!$recordset)
        {
            die("Connect Error: " . $link->error);
        }
        $message = $login . "'s secret has been reset!";
    }
    else
    {
        $message = "An error occured!"; 
    }
}
echo $message;
$link->close();
?>

所以感觉这个也没啥,其实sql注入的根本点是出现查询或者插入等其他sql语句的地方,所以没啥大改变,上一张burp的图就好了.


图十六

8.SQL Injection (Blind)
源代码如下所示:

    Incorrect syntax detected!");
            // die("Error: " . mysql_error());
        }
        if(mysql_num_rows($recordset) != 0)
        {
            echo "The movie exists in our database!";
        }
        else
        {
            echo "The movie does not exist in our database!";
        }
        mysql_close($link);
    }
    ?>

典型注入,未进行过滤,从源代码来看他只会显示语法错误或者电影存在不存在,没有其他显示了.
Level Low的注入点在title这里,也就是输入的东东.
输入指令为

Iron Man' and if(ascii(substr((select database()),1,1))<120,sleep(10),1)#

效果


图十七

9.SQL Injection - Blind (WS/SOAP)
先上主要源代码如下:

call("get_tickets_stock", array("title" => sqli($_REQUEST["title"])));
    echo "We have " . $tickets_stock . " movie tickets available in our stock.";
}
?>

这里简单介绍一下SOAP的内容.
SOAP 是基于 XML 的简易协议,可使应用程序在 HTTP 之上进行信息交换。
或者更简单地说:SOAP 是用于访问网络服务的协议。
所以注入点应该是存在于sqli函数这里
sqlmap结果如下所示:


图十八

Level High以及Level Medium应该做了addslashes还有htmlspecialchars转换,基本就不存在问题了.

9.XML/XPath注入
源代码如下所示

xpath("//hero[genre = '$genre']/movie");
    $result = $xml->xpath("//hero[contains(genre, '$genre')]/movie");
    
    // Case insensitive search
    // $result = $xml->xpath("//hero[contains(translate(genre, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), translate('$genre', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'))]/movie");
    
    // $upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ";
    // $lower = "abcdefghijklmnopqrstuvwxyzæøå";
    
    // $result = $xml->xpath("//hero[contains(translate(genre, '$upper', '$lower'), translate('$genre', '$upper', '$lower'))]/movie");
    // Debugging
    // print_r($result);  
    // echo $result[0][0];  
    // echo $result[0]->login;
    if($result)
    {    
        foreach($result as $key => $row)       
        {
            // print_r($row);    
?>

在学习之前请先学习一些一些xml的语法知识,然后再学习人家为啥这样注入.
链接如下:https://www.cnblogs.com/backlion/p/8554749.html
从源代码可以看出主要是一个xpath注入,接收了genre变量输入以后就直接生成xml路径进去搜索,在这个时候用到了xpath注入.
注入的payload如下所示:')] | //* | //* [('
')]是用来闭合前面的函数以及查询条件,中间的//* | //用来查询当下文档里面所有子元素.
构成的查询语句如下所示:
//hero[contains(genre, '')] | //
| //* [('')]/movie
这样就完成了一次xml注入.
前面博主介绍了一款xml盲注工具,叫xcat,可以在python3下面运行的命令行工具,本来想试试,但是发现老是包ipgetter出错无法下载,所以只能这样了.

10.XML/Xpath injection (login form)
源代码如下:

xpath("/heroes/hero[login='" . $login . "' and password='" . $password . "']");
    // Debugging
    // print_r($result);
    // echo $result[0][0];
    // echo $result[0]->login;
    if($result)
    {
        $message =  "

Welcome " . ucwords($result[0]->login) . ", how are you today?

Your secret: " . $result[0]->secret . "

"; } else { $message = "Invalid credentials!"; } ?>

这道题目答案怪怪的,比如正常应该是下处理双引号,但是结果却发现答案是先处理单引号,而且单引号比坏人的方式也和以前不太一样,是用or'来闭合成or' '
payload如下:whatever' or 1=1 or '
如下:


图十九.png

至此,注入篇就到这里结束了....

然后写点总结吧
BWAPP里面的注入一共有HTML注入,SMTP注入,命令注入,php代码注入,ssii,SQL注入,xml/xpath注入
这里的话,写一点各种注入的形式总结....

HTML注入主要是往服务端注入各种html代码,但不一定会存储在服务端,可能只是反弹回来而已,主要以你注入的HTML代码为准.

SMTP注入有点鸡肋,就是改变一下邮件发件人,邮件的标题,内容等等而已....特定场合才用得上吧.

命令注入就不用说了,这个和DVWA很像,没啥新玩意.

php代码注入,这个eval函数应该是其他的语言也有的,例如get给参数到他的title里面,你就可以试试一个phpinfo()等等.

ssii其实没太大高大上的地方,就是server-side include injection,怎么说呢,就是你把代码注入到服务器文件里面,然后服务端再把文件包含起来.所以试试什么xss代码都是可以的.

SQL注入做了这么多,就一句话:有sql语句的地方都可以试试.

XML注入,主要是你要理解好xml/xpath是用来干嘛的,然后搞动xml的基本语法,不然注入的payload你都看不懂...

访问控制篇见了~~~


Gakki.jpg

你可能感兴趣的:(2018-10-22-BWAPP注入篇)