渗透测试之xss漏洞从3个小实例入手

587 阅读2分钟
原文链接: bingyishow.top

前言

XSS攻击全称跨站脚本攻击,是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS,XSS是一种在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。

在本文中将涉及到 反射型 XSS、存储型 XSS、DOM XSS三个比较经典的小示例。如果有分析不对之处多多包涵。欢迎留言讨论。

反射型 XSS

0X01简介

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

0X02漏洞代码

<?php
  $username = $_GET['user'];
  echo " 用户名: ".$username;
?>
  • 分析:将用户输入的 user 内容直接输出到页面,未经过任何过滤。可导致 XSS 漏洞攻击。

修复建议:在接收输入后进行 htmlspecialchars 过滤,或者在输出前 htmlspecialchars 过滤

0X03修复代码

<?php
  $username = $_GET['user'];
  echo " 用户名: ".htmlspecialchars($username);
?>

存储型 XSS

0X01简介

存储型XSS,持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,加入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,用户访问该页面的时候触发代码执行。这种XSS比较危险,容易造成蠕虫,盗窃cookie等。

0X02漏洞代码

if(!empty($_POST['content']))
  {
      $content = addslashes($_POST['content']);
      if($mysqli->query("insert into test (content)values('$content')"))
    {
    echo ' 发言成功 ';
    }else{
    echo ' 发言失败 ';
    }
  }
  $data = $mysqli->query("select content from test");
if($data->num_rows !== '0')
  {
      $arr = $data->fetch_all();
      foreach($arr as $a)
    {
      echo ' 发言: '.$a[0].'<br>';
    }
  }
  • 分析:用户发言的内容未进行字符串编码,直接存储到数据库中,并取出数据库中带有恶意代码的内容输出到网页中,导致 XSS 攻击

修复建议:在接收输入后进行 htmlspecialchars 过滤,或者在输出前 htmlspecialchars 过滤

0X03修复代码

echo ' 发言: '.htmlspecialchars($a[0]).'<br>';

DOM XSS

此漏洞有两个小示例进行分析。

0X01简介

与反射型XSS、存储型XSS的区别就在于xss代码并不需要服务器解析响应的直接参与,触发XSS靠的是浏览器端的DOM解析。

0X02漏洞代码

<?php
    $img = isset($_GET['img']) ? htmlspecialchars($_GET['img']) : 'default.jpg';
?>
<img src="" id="image">
<script>
    var test = document.getElementById('image');
    test.src = '<?php echo $img;?>';
</script>
  • 分析:使用了 htmlspecialchars 进行过滤,但单引号没有过滤,导致 DOM XSS

修复建议:在接收输入后进行 htmlspecialchars 过滤,并且还有对单引号和反斜杠进行转义

0X03修复代码

$img = isset($_GET['img']) ? htmlspecialchars(addslashes($_GET['img'])) : 'default.jpg';

0X04漏洞代码

<?php
    $content = isset($_GET['content']) ? htmlspecialchars($_GET['content']) : ' 无内容 ';
    $content = str_replace("'","\'",$content);
?>
<div id="content">
    这是测试内容
</div>
<script>
    var test = document.getElementById('content');
    test.innerHTML = '<?php echo $content;?>';
</script>
  • 分析:innerHTML 、 documen.write 这种直接修改 html 内容的方法,应对其内容进行严格过滤,否则通过 8 进制或 16 进制编码可绕过 htmlspecialchars 过滤.

修复建议:和上一个大致相同

0X04修复代码

$content = isset($_GET['content']) ? htmlspecialchars(addslashes($_GET['content'])) : ' 无内容 ';