Google CTF 2017 - Notes

> Published On June 25, 2017

> By hoangdoan


Cuối tuần rồi hóng Google CTF 2017 rồi note lại, giờ mới rảnh để post, too late =]]

MindReader

Truy cập vào https://mindreader.web.ctfcompetition.com/

mindreader_desc.png

Cần nhập cái gì đó để đọc dữ liệu, theo quán tính cứ /ect/passwd mà gõ :D

Có vẻ là kiểu Challenge truyền thống, bug cho phép đọc source-code, trong source-code sẽ chứa thông tin về nơi dấu FLAG. Cảm nhận cá nhân, hầu hết Challenge của Google mình thấy đều dùng Google App Engine + Python, nên cứ gõ tiếp :3

mindreader_main.py.png

Source-code đọc dô là hiểu liền, challenge này xếp vào loại Easy quả nhiên có lý do :3 * FLAG dấu trong biến môi trường * Blacklist hết các input có chứa ‘proc|random|zero|stdout|stderr’

Theo mình biết có thể đọc được biến môi trường của process tại /proc/self/environ, mà “proc” đã bị blacklist. Trí nhớ mách bảo trong /dev có một mớ symlink có liên quan tới proc :D

mindreader_proc_symlink.png

Nhìn qua thử thì có thằng /dev/fd -> /proc/self/fd thỏa điều kiện vừa là folder để traversal lên /proc/self/, vừa không nằm trong blacklist

mindreader_flag.png

Ghi bàn :3

mindreader_submit.png

A7 ~ Gee cue elle

p/s: Challenge này mình chỉ tìm ra hướng giải nhưng lúc đó chưa có thời gian hiện thực :(

a7_Gee_cue_elle_desc.png

Thú thật không suy diễn được gì từ Challenge Name =]]

Tập tin start.html có nội dung ngắn gọn như sau:

html <script> location.replace('http://'+parseInt(Math.random()*1e15)+'-abuse.web.ctfcompetition.com/login'); </script>

Đoạn mã trên đơn giản sẽ chuyển hướng Browsers đến một random URL

http://[random_number]-abuse.web.ctfcompetition.com/login

Server sẽ return về một URL có cấu trúc

http://qu0t45 + base64(random_12_bytes) + www-abuse.gctf2017.lab/login

Lúc mình xem Challenge là đã thấy Hint .yaml~

Ý đồ của Hint chắc là Challenge được code bằng mấy Editor như nano, vi,… sẽ tự động có các tập tin backup có tên kết thúc với dấu ‘~’

Thử kiểm tra phát ra source luôn

A7_Gee_cue_elle app.yaml

Nhìn đoạn

- url: /login script: main.app

–> Code của /login sẽ là main.py

A7_Gee_cue_elle_mainpy.png

Full source tại https://lab.infosec.xyz/assets/main.py

Theo source-code thì FLAG FORMAT là

python flag = "CTF{\%s-\%s}" % ( hostname, base64.b64encode(hmac.new( self.key, hostname, hashlib.sha512 ).digest()[:(6*FLAG_LENGTH/8)], "-_"))

Túm váy lại thì FLAG = CTF{qu0t453lzcgiej7s1v5qeywww-XXXXBase64}

Với ‘qu0t453lzcgiej7s1v5qeywww-‘ là subdomain_prefix có yếu tố random nên không cần quan tâm đến, chỉ cần tìm đoạn XXXXBase64 là ra FLAG

Kiểm tra login từ dữ liệu POST lên được xử lý bởi

python def post(self): sql = "SELECT password FROM UserModel WHERE ANCESTOR IS :1 AND user = 'admin'" query = ndb.gql(sql % self.request.get("user"), self.quota.key) result = query.fetch(1) if not result: self.redirect("/index.html?e=%s" % urllib.quote("Wrong username")) elif result[0].password != self.request.get("password"): raise Exception("Wrong password") else: self.response.write(self.request.get("password"))

Nhận xét: * FLAG cũng chính là Password của ‘admin’ * Blind Injection trong câu truy vấn GQL

"SELECT password FROM UserModel WHERE ANCESTOR IS :1 AND user = '%s'"

Buồn thay đây là GQL, bộ cú pháp rất ư là ngắn gọn súc tích, không quyến rũ như SQL, như thiếu %LIKE%, không thể lấy SUBSTR,không cho phép so sánh = hoặc != đối với các column đã được SELECT

May mắn thay vẫn có thể sử dụng >, <, >=, <= thay thế khi so sánh String (Ref: https://stackoverflow.com/questions/47786/google-app-engine-is-it-possible-to-do-a-gql-like-query)

Nên có thể Blind Injection đoạn XXXXBase64 tương tự Blind SQLi:

"SELECT password FROM UserModel WHERE ANCESTOR IS :1 AND user = 'admin' AND 'password' > ‘CTF{qu0t453lzcgiej7s1v5qeywww-Đoán_từng_ký_tự_Base64]}’"

Điều kiện kiểm tra: - Password Đúng: Response chứa ‘Wrong Password’ - Password Sai: Response chứa ‘Wrong Username’

Ví dụ: POST[Username] = admin' AND 'password' >= ‘CTF{qu0t453lzcgiej7s1v5qeywww-Z]}’" ==> Wrong Password --> True POST[Username] = admin' AND 'password' >= ‘CTF{qu0t453lzcgiej7s1v5qeywww-Za]}’" --> Wrong Username --> False POST[Username] = admin' AND 'password' >= ‘CTF{qu0t453lzcgiej7s1v5qeywww-Zb]}’" --> Wrong Username --> False POST[Username] = admin' AND 'password' >= ‘CTF{qu0t453lzcgiej7s1v5qeywww-Zc]}’" --> Wrong Password --> True

Khi Blind Injection có thể bị block vì quá Quota, rate requests quá 13 req / 90 seconds / subdomain_prefix (nhìn lướt qua hình như là vậy :sexy:). Vì Quota sử dụng (subdomain_prefix + random(12_bytes)) để làm key cho bộ đếm, ta có thể bypass Quota này bằng cách random URL theo đúng định dạng như sau trong lúc Auto Blind Inject:

python https://qu0t45%swww-%s/login" % (base64.b64encode(os.urandom(6 * 16 / 8), "__"), "abuse.web.ctfcompetition.com"))

=========

Chưa ra FLAG nhưng End Game CTF ở đây, tiếp tục sấp mặt với mớ công việc dồn ứ cuối tuần =((. Dù sao thì mỗi lần giải được một CTF Challenge thì cảm giác vẫn lâng lâng như ngày nào ^^


Tags: ctf hacking security fun

Comments:

comments powered by Disqus
Next →

© 2018 - Security Researchers Team. All rights reserved
Built using Jekyll