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("<", "<", $data);
$input = str_replace(">", ">", $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 '&'
// '"' (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实体字符
在实际的很多业务中,用户输入的内容会显示在页面中。比如,一个存在反射型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即可


浙公网安备 33010602011771号