【web安全】php代码审计(二)

  漏洞简介

  跨站脚本攻击是指恶意攻击者往 Web 页面里插入恶意 Script 代码,当用户浏览该页之时,嵌入其中 Web 里面的 Script 代码会被执行,从而达到恶意攻击用户的目的。xss 漏洞通常是通过 php 的输出函数将 javascript 代码输出到 html 页面中,通过用户本地浏览器执行的,所以 xss 漏洞关键就是寻找参数未过滤的输出函数。

  常见的输出函数有:echo、printf、print、print_r、sprintf、die、var_dump、var_export

  分类

  反射型XSS:<非持久化> 攻击者事先制作好攻击链接, 需要欺骗用户自己去点击链接才能触发 XSS 代码(服务器中没有这样的页面和内容),一般容易出现在搜索页面。

  存储型XSS:<持久化> 代码是存储在服务器中的,如在个人信息或发表文章等地方,加入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,每当有用户访问该页面的时候都会触发代码执行,这种 XSS 非常危险,容易造成蠕虫,大量盗窃 cookie(虽然还有种 DOM 型 XSS,但是也还是包括在存储型 XSS 内)

  原理

  我们首先要寻找带参数的输出函数,接下来通过输出内容回溯到输入参数,观察是否过滤即可。 无案例不足以求真,这里我们选用 echo() 函数作为实例来分析

  <html>

  <head>

  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

  <title>XSS</title>

  </head>

  <body>

  <form action="" method="get">

  <input type="text" name="input">

  <input type="submit">

  </form>

  <br>

  <?php

  $XssReflex = $_GET['input'];

  echo 'output:<br>'.$XssReflex;

  ?>

  </body>

  </html>

  P.S:变量 $XssReflex 获取 get 方式传递的变量名为 input 的变量值(值为一个字符串),然后直接通过 echo() 函数输出,注意这中间并未对用户输入进行任何过滤。

  当我们输入 hello 时返回为 hello

  当我们插入比如我们输入

  <script>alert('xss')</script>

  可以成功弹窗,说明我们输出的 JavaScript 代码成功被执行了。

  这时发现在 output:

  <br><script>alert(‘xss’)</script>

  这个弹窗并没有什么实际的意义,但通过它我们知道输入 javascript 代码是可以被执行的,当我们输入一些其他函数,比如 document.cookie 就可以成功盗取用户的 cookie 信息

  存储型XSS

  和反射性 XSS 的即时响应相比,存储型XSS则需要先把利用代码保存在比如数据库或文件中,当 web 程序读取利用代码时再输出在页面上执行利用代码。但存储型 XSS 不用考虑绕过浏览器的过滤问题,屏蔽性也要好很多

  代码如下:

  <span style="font-size:18px;"><meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>

  <html>

  <head>

  <title>XssStorage</title>

  </head>

  <body>

  <h2>Message Board<h2>

  <br>

  <form action="XssStorage.php" method="post">

  Message:<textarea id='Mid' name="desc"></textarea>

  <br>

  <br>

  Subuser:<input type="text" name="user"/><br>

  <br>

  <input type="submit" value="submit" onclick='loction="XssStorage.php"'/>

  </form>

  <?php

  if(isset($_POST['user'])&&isset($_POST['desc'])){

  $log=fopen("sql.txt","a");

  fwrite($log,$_POST['user']."\r\n");

  fwrite($log,$_POST['desc']."\r\n");

  fclose($log);

  }

  if(file_exists("sql.txt"))

  {

  $read= fopen("sql.txt",'r');

  while(!feof($read))

  {

  echo fgets($read)."</br>";

  }

  fclose($read);

  }

  ?>

  </body>

  </html></span>

  功能描述:这个页面采用 POST 提交数据,生成、读取文本模拟数据库,提交数据之后页面会将数据写入 sql.txt,再打开页面时会读取 sql.txt 中内容并显示在网页上,实现了存储型 xss 攻击模拟。

  随意输入一些信息发现返回的还是我们随意输入的信息,我们加入

  <script>alert('xss')</script>

  时,页面成功弹窗,并且我们重启浏览器之后再加载该页面,页面依然会弹窗,这是因为恶意代码已经写入数据库中,每当有人访问该页面时,恶意代码就会被加载执行

  反射型防御手段

  A.PHP 直接输出 html 的,可以采用以下的方法进行过滤:

  htmlspecialchars函数

  htmlentities函数

  HTMLPurifier.auto.php插件

  RemoveXss函数

  B.PHP输出到JS代码中,或者开发Json API的,则需要前端在JS中进行过滤:

  1.尽量使用innerText(IE)和textContent(Firefox),也就是jQuery的text()来输出文本内容

  2.必须要用innerHTML等等函数,则需要做类似php的htmlspecialchars的过滤

  C.其它的通用的补充性防御手段

  1.在输出html时,加上Content Security Policy的Http Header

  (作用:可以防止页面被XSS攻击时,嵌入第三方的脚本文件等)

  (缺陷:IE或低版本的浏览器可能不支持)

  2.在设置Cookie时,加上HttpOnly参数

  (作用:可以防止页面被XSS攻击时,Cookie信息被盗取,可兼容至IE6)

  (缺陷:网站本身的JS代码也无法操作Cookie,而且作用有限,只能保证Cookie的安全)

  3.在开发API时,检验请求的Referer参数

  (作用:可以在一定程度上防止CSRF攻击)

  (缺陷:IE或低版本的浏览器中,Referer参数可以被伪造)

  这里我们选用htmlentities()函数进行测试(htmlentities() 函数把字符转换为 HTML 实体)

  代码如下:

  <html>

  <head>

  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

  <title>XSS</title>

  </head>

  <body>

  <form action="" method="get">

  <input type="text" name="input">

  <input type="submit">

  </form>

  <br>

  <?php

  $XssReflex = $_GET['input'];

  echo 'output:<br>'.htmlentities($XssReflex);#仅在这里对变量 $XssReflex 做了处理.

  ?>

  </body>

  </html>

  当我们输入<script>alert('xss')</script>,页面并没有弹窗可以看到htmlentities()函数对用户输入的<>做了转义处理,恶意代码当然也就没法执行了。 还有其他过滤函数

  存储型xss漏洞防范

  存储型XSS对用户的输入进行过滤的方式和反射型XSS相同,这里我们使用htmlspecialchars()函数进行演示

  P.S:htmlentities() :把预定义的字符 "<" (小于)和 ">" (大于)转换为 HTML 实体

  htmlspecialchars和htmlentities的区别:htmlspecialchars 只转义 & 、" 、' 、< 、> 这几个html代码,而htmlentities 却会转化所有的html代码,连同里面的它无法识别的中文字符也会转化

  代码如下:

  <span style="font-size:18px;"><meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>

  <html>

  <head>

  <title>XssStorage</title>

  </head>

  <body>

  <h2>Message Board<h2>

  <br>

  <form action="Xss_htmlspecialchars_Storage.php" method="post">

  Message:<textarea id='Mid' name="desc"></textarea>

  <br>

  <br>

  Subuser:<input type="text" name="user"/><br>

  <br>

  <input type="submit" value="submit" onclick='loction="XssStorage.php"'/>

  </form>

  <?php

  if(isset($_POST['user'])&&isset($_POST['desc'])){

  $log=fopen("sqlStorage.txt","a");

  fwrite($log,htmlspecialchars($_POST['user'])."\r\n"); # 在此对用户输入数据$_POST['user']进行过滤

  fwrite($log,htmlspecialchars($_POST['desc'])."\r\n"); # 在此对用户输入数据$_POST['desc']进行过滤

  fclose($log);

  }

  if(file_exists("sqlStorage.txt"))

  {

  $read= fopen("sqlStorage.txt",'r');

  while(!feof($read))

  {

  echo fgets($read)."</br>";

  }

  fclose($read);

  }北京代孕威信15023219993 广州代孕威信15023219993 深圳代孕威信15023219993 昆明代孕威信15023219993 上海代孕威信15023219993 天津代孕威信15023219993 成都代孕威信15023219993 北京代孕威信15023219993 重庆代孕威信15023219993 重庆代孕威信15023219993

  ?>

  </body>

  </html></span>

  当我们在 Message 中输入 <script>alert('xss')</script> 可以看到页面并没有弹窗,可以看到 htmlspecialchars() 函数对用户输入的<>做了转义处理

  XSS进阶

  假设现在有个博客,并且有 xss,你也知道删除文章的链接,但是要有文章id才可以删除,

  现在条件时 GET 请求

  我们只需要插入一个图片来发 get 请求

  Payload:

  Payload:vae img=document.createElement(“img”);

  Img.src=”url”

  Document.body.appendChild(img)

  如果是正常请求我们要构造一个from表单,这里就略了

  绕过方法

  JS编码、  Html实体编码、  url编码

猜你喜欢

转载自www.cnblogs.com/ipengrui2/p/12303004.html