反射型XSS

反射型XSS,是服务器后端处理时,处理不当,把用户输入的内容输出到前端网页,导致用户浏览器执行恶意代码。

  1. <?php
  2. echo 'Hello '.$_GET['name'].'!';

如果输入的是一段html代码,则使用浏览器直接渲染。

  1. 攻击者输入: ?name=<script type="text/javascript">alert('XSS!');</script>
  2. 服务器返回 Hello <script type="text/javascript">alert('XSS!');</script>!
  3. 浏览器渲染 Hello ! script被作为html标签解析 执行其中的代码 弹出警告框XSS!

KKCMS

反射XSS

  1. <?php
  2. $flid1 = $_GET['m'];
  3. if ($flid1 == "") {
  4. $flid1 = '/dongman/list.php?rank=rankhot&page=1';
  5. }
  6. include 'system/360.php';
  7. ....
  8. ....
  9. <?php echo getPageHtml($page, $fenye, 'dongman.php?m=' . $yourneed . '&page='); ?><li><a><?php echo $fenye; ?></a></li>

传入:"><script>alert(/xss/)</script>没有经过什么过滤就直接回显在前端了。正好闭合前面的href=",然后后面的部分成功执行反弹xss经典弹窗。

【代码审计】XSS——PHP - 图1

弹窗效果

【代码审计】XSS——PHP - 图2

存储型XSS

先看一些知识

  1. /[\x7f-\xff]+(?:\s*[\x7f-\xff]+)*/
  2. # 这是一个正则表达式,它主要是匹配过滤掉中文字符,看下图

【代码审计】XSS——PHP - 图3

  1. //判断有一个空格以上但是又不能全部是空的字符串
  2. if (!ctype_space($_POST['content']) && !empty($_POST['content'])) {
  3. //匹配数字字母下划线空格中文 数量不能超过10个字
  4. if (!preg_match("/[\x7f-\xff]+(?:\s*[\x7f-\xff]+)*/", $_POST['content'])) {
  5. echo "<script>alert('内容填写不合法!');location.href='book.php'</script>";
  6. die;
  7. }
  8. } else {
  9. echo "<script>alert('内容填写不合法!');location.href='book.php'</script>";
  10. die;
  11. }

其中!ctype_space()

PHP中的ctype_space()函数检查空格字符。如果文本中的每个字符都产生某种空白,则返回TRUE,否则返回FALSE。除空白字符外,还包括制表符,垂直制表符,换行符,回车符和换页符。

意思即为输入的字符串在检查过后,可以存在空格,但是又不能全部是空格,同时又限制了必须输入不为空的内容。

【代码审计】XSS——PHP - 图4

所以逻辑是:昵称和留言内容必须是中文字符。但是使用的正则中。

【代码审计】XSS——PHP - 图5

只要存在中文字符就行,没有设置为全为中文字符。而且也没有了其他方式的过滤。

而且这个$sql = 'insert into xtcms_book ('.$str[0].') values ('.$str[1].')';还是将数据写入了数据库中,所以即为存储型XSS

防护处理

变量进行htmlspecialchars处理

htmlspecialchars() 函数把预定义的字符转换为 HTML 实体。

预定义的字符是:

  1. & (和号)成为 &
  2. " (双引号)成为 "
  3. ' (单引号)成为 '
  4. < (小于)成为 <
  5. > (大于)成为 >
  1. $message = htmlspecialchars( $message );
  2. $name = htmlspecialchars( $name );

标签事件白名单处理