一.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://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 '
如下:
至此,注入篇就到这里结束了....
然后写点总结吧
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你都看不懂...
访问控制篇见了~~~