bWAPP——20201119

Server-Side Includes (SSI) Injection

SSI是英文Server Side Includes的缩写,翻译成中文就是服务器端包含的意思。从技术角度上说,SSI就是在HTML文件中,可以通过注释行调用的命令或指针。SSI具有强大的功能,只要使用一条简单的SSI 命令就可以实现整个网站的内容更新,时间和日期的动态显示,以及执行shell和CGI脚本程序等复杂的功能。SSI 可以称得上是那些资金短缺、时间紧张、工作量大的网站开发人员的最佳帮手。本文将主要结合Apache服务器介绍SSI的使用方法。

(ps:(Server-side Includes) 服务器端包含提供了一种对现有HTML文档增加动态内容的方法。apache和iis都可以通过配置支持SSI,在网页内容被返回给用户之前,服务器会执行网页内容中的SSI标签。在很多场景中,用户输入的内容可以显示在页面中,比如一个存在反射XSS漏洞的页面,如果输入的payload不是xss代码而是ssi的标签,服务器又开启了ssi支持的话就会存在SSI漏洞。)

function xss($data)
{

    switch($_COOKIE["security_level"])
    {

        case "0" :

            $data = no_check($data);
            break;

        case "1" :

            $data = xss_check_4($data);
            break;

        case "2" :

            $data = xss_check_3($data);
            break;

        default :

            $data = no_check($data);
            break;

    }       

    return $data;

}

low:
核心代码:

function xss_check_1($data)
{
    
    // Converts only "<" and ">" to HTLM entities    
    $input = str_replace("<", "&lt;", $data);
    $input = str_replace(">", "&gt;", $input);
    
    // Failure is an option
    // Bypasses double encoding attacks   
    // <script>alert(0)</script>
    // %3Cscript%3Ealert%280%29%3C%2Fscript%3E
    // %253Cscript%253Ealert%25280%2529%253C%252Fscript%253E
    $input = urldecode($input);
    
    return $input;
    
}

这里没有限制,可直接进行xss:

medium:

function xss_check_4($data)
{
  
    // addslashes - returns a string with backslashes before characters that need to be quoted in database queries etc.
    // These characters are single quote ('), double quote ("), backslash (\) and NUL (the NULL byte).
    // Do NOT use this for XSS or HTML validations!!!
    
    return addslashes($data);      //addslashes()在符号前加反斜线
    
}

这里执行xss依然可以

high:

function xss_check_3($data, $encoding = "UTF-8")
{

    // htmlspecialchars - converts special characters to HTML entities    
    // '&' (ampersand) becomes '&amp;' 
    // '"' (double quote) becomes '&quot;' when ENT_NOQUOTES is not set
    // "'" (single quote) becomes '&#039;' (or &apos;) only when ENT_QUOTES is set
    // '<' (less than) becomes '&lt;'
    // '>' (greater than) becomes '&gt;'  
    
    return htmlspecialchars($data, ENT_QUOTES, $encoding);
       
}

将预定义的字符装换为html实体字符
在实际的很多业务中,用户输入的内容会显示在页面中。比如,一个存在反射型XSS漏洞的页面,如果输入的payload不是XSS代码而是SSI的标签,同时服务器又开启了对SSI的支持的话就会存在SSI漏洞。因此,对于SSI注入的挖掘大概思路也同XSS的挖掘类似。
从定义中看出,页面中有一小部分是动态输出的时候使用SSI,比如:

  • 文件相关的属性字段

  • 当前时间

  • 访客IP

  • 调用CGI程序

XML/XPath Injection (Login Form)

  function xmli($data)
{
    
    if(isset($_COOKIE["security_level"]))
    {

        switch($_COOKIE["security_level"])
        {

            case "0" :

                $data = no_check($data);
                break;

            case "1" :

                $data = xmli_check_1($data);
                break;

            case "2" :

                $data = xmli_check_1($data);
                break;

            default :

                $data = no_check($data);
                break;

        }

    }

    return $data;

}

输入参数后,在url中显示http://127.0.0.1/bwapp/bWAPP/xmli_1.php?login=bee%27&password=bug&form=submit现在抓包来看看


查看源码得知是通过读取heroes.xml文件的内容, 并且通过xpath寻找用户的账户和密码来验证登录:

根据xpath语句:/heroes/hero[login='$login' and password='$password']
在没有对login和password参数作任何防护的情况下, 可以构造xpath语句进行注入
这里注入点选择login参数, 将$login前面的单引号闭合, 加入永真条件1=1, 构造一个万能登录的payload:

medium和high

function xmli_check_1($data)
{

    // Replaces dangerous characters: ( ) = ' [ ] : , * / WHITESPACE
    $input = str_replace("(", "", $data);
    $input = str_replace(")", "", $input);
    $input = str_replace("=", "", $input);
    $input = str_replace("'", "", $input);
    $input = str_replace("[", "", $input);
    $input = str_replace("]", "", $input);
    $input = str_replace(":", "", $input);
    $input = str_replace(",", "", $input);
    $input = str_replace("*", "", $input);
    $input = str_replace("/", "", $input);
    $input = str_replace(" ", "", $input);
   
    return $input;
    
}

中级和高级做了严格的过滤

XML/XPath Injection (Search)

if(isset($_REQUEST["genre"])) 
{
    
    $genre = $_REQUEST["genre"];
    $genre = xmli($genre);
   
    // Loads the XML file
    $xml = simplexml_load_file("passwords/heroes.xml");
     
    // XPath search
    // $result = $xml->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);    

low:

通过url更改参数注入单引号, 从得到报错信息得知: 服务端是用了xml的解析
查看源码, 看到的确是读取了一个包含电影信息的xml文件, 然后再利用xpath提取信息

关键xpath语句如下:
//hero[contains(genre, '$genre')]/movie
大概表示所有属性值genre为$genre的hero标签下的movie元素值
这里的genre参数是可控的, 攻击者可以构造恶意xpath语句来获取整个xml文档的信息:
比如, 通过闭合$genre前面的单引号, 然后在后面选取hero的password元素值; 最后用一个 | 运算符将movie闭合好:
horror')]/password | hack[contains(a,'
注入后的xpath语句为:
//hero[contains(genre, 'horror')]/password | hack[contains(a,'')]/movie

medium/high:

function xmli_check_1($data)
{

    // Replaces dangerous characters: ( ) = ' [ ] : , * / WHITESPACE
    $input = str_replace("(", "", $data);
    $input = str_replace(")", "", $input);
    $input = str_replace("=", "", $input);
    $input = str_replace("'", "", $input);
    $input = str_replace("[", "", $input);
    $input = str_replace("]", "", $input);
    $input = str_replace(":", "", $input);
    $input = str_replace(",", "", $input);
    $input = str_replace("*", "", $input);
    $input = str_replace("/", "", $input);
    $input = str_replace(" ", "", $input);
   
    return $input;
    
}

中级和高级做了严格过滤

Broken Auth. - Forgotten Function


Email用了mysqli_real_escape_string进行过滤进行暴力破解即可

Broken Auth. - Insecure Login Forms

low:

if(isset($_POST["form"]))   
{ 
        
    if($_POST["login"] == "tonystark" && $_POST["password"] == "I am Iron Man")
    {
        
        $message = "<font color=\"green\">Successful login! You really are Iron Man :)</font>";
        
    }
    
    else        
    {

        $message = "<font color=\"red\">Invalid credentials!</font>";

    }
    
}

用tonystark和I am Iron Man进行登陆,登陆成功

medium:

<form>   

        <p><label for="name">Name:</label><font color="white">brucebanner</font><br />
        <input type="text" id="name" name="name" size="20" value="brucebanner" /></p> 

        <p><label for="passphrase">Passphrase:</label><br />
        <input type="password" id="passphrase" name="passphrase" size="20" /></p>

        <input type="button" name="button" value="Unlock" onclick="unlock_secret()" /><br />

    </form>

找到unlock_secret()

function unlock_secret()
{

    var bWAPP = "bash update killed my shells!"

    var a = bWAPP.charAt(0);  var d = bWAPP.charAt(3);  var r = bWAPP.charAt(16);
    var b = bWAPP.charAt(1);  var e = bWAPP.charAt(4);  var j = bWAPP.charAt(9);
    var c = bWAPP.charAt(2);  var f = bWAPP.charAt(5);  var g = bWAPP.charAt(4);
    var j = bWAPP.charAt(9);  var h = bWAPP.charAt(6);  var l = bWAPP.charAt(11);
    var g = bWAPP.charAt(4);  var i = bWAPP.charAt(7);  var x = bWAPP.charAt(4);
    var l = bWAPP.charAt(11); var p = bWAPP.charAt(23); var m = bWAPP.charAt(4);
    var s = bWAPP.charAt(17); var k = bWAPP.charAt(10); var d = bWAPP.charAt(23);
    var t = bWAPP.charAt(2);  var n = bWAPP.charAt(12); var e = bWAPP.charAt(4);
    var a = bWAPP.charAt(1);  var o = bWAPP.charAt(13); var f = bWAPP.charAt(5);
    var b = bWAPP.charAt(1);  var q = bWAPP.charAt(15); var h = bWAPP.charAt(9);
    var c = bWAPP.charAt(2);  var h = bWAPP.charAt(2);  var i = bWAPP.charAt(7);
    var j = bWAPP.charAt(5);  var i = bWAPP.charAt(7);  var y = bWAPP.charAt(22);
    var g = bWAPP.charAt(1);  var p = bWAPP.charAt(4);  var p = bWAPP.charAt(28);
    var l = bWAPP.charAt(11); var k = bWAPP.charAt(14);
    var q = bWAPP.charAt(12); var n = bWAPP.charAt(12);
    var m = bWAPP.charAt(4);  var o = bWAPP.charAt(19);

    var secret = (d + "" + j + "" + k + "" + q + "" + x + "" + t + "" +o + "" + g + "" + h + "" + d + "" + p);

    if(document.forms[0].passphrase.value == secret)
    { 
              
        // Unlocked
        location.href="<?php echo($_SERVER["SCRIPT_NAME"]); ?>?secret=" + secret;

    }
    
    else
    {
        
        // Locked
        location.href="<?php echo($_SERVER["SCRIPT_NAME"]); ?>?secret=";
                
    }

}	


将其执行后得到secret,输入后通过

Broken Auth. - Logout Management

low:

<div id="main">
    
    <h1>Broken Auth. - Logout Management</h1>

    <p>Click <a href="ba_logout_1.php" onclick="return confirm('Are you sure?');">here</a> to logout.</p>

</div>

medium:
进入ba_logout_1.php后销毁了cookie,安全

   case "1" :            
        
        // Destroys the session        
        session_destroy();       
        
        break;

high:

 case "2" :            
                       
        // Unsets all of the session variables
        $_SESSION = array();
        
        // Destroys the session    
        session_destroy();
                
        break;

Broken Auth. - Password Attacks

low:
可直接进行爆破

medium:

这里加salt不能爆破
$salt = random_string();
$_SESSION["salt"] = $salt;

high:
使用了验证码

Broken Auth. - Weak Passwords

考察了弱密码

$login = "test";
  
switch($_COOKIE["security_level"])
{

    case "0" : 

        $password = "test";
        break;

    case "1" :

        $password = "test123";
        break;

    case "2" :

        $password = "Test123";
        break;

Session Mgmt. - Administrative Portals

low:
直接将0改为1即可
medium/high:
修改存储中admin的值修改为1即可

posted @ 2020-11-19 21:58  WANGXIN_YU  阅读(389)  评论(0)    收藏  举报