[Write-up] Framgia CTF - Beyond Human (2016/06/17)

Intro

Thay mặt BTC, mình xin được phép đưa ra phần write-up ngắn gọn cũng như gợi ý cho phần CTF của cuộc thi. Phần game logic, bạn @bs90 là người phụ trách.

Survey

BTC rất hi vọng mọi người bớt chút thời gian đóng góp ý kiến cho cuộc thi thông qua bản khảo sát sau: https://docs.google.com/forms/d/1l3LYMdLmRHPkwIpeD5Pef0shsGCL3I_kgf1aDmgsDw4/viewform

Write up

SPOILER ALERT: nếu bạn muốn tự mình làm thì có thể dừng đọc tại đây, chỉ đọc khi đã hoàn thành các task.

Funny Code (80pt)

http://ctf.framgia.vn/task/5

I have no clue. My Chineses send me this xn--{letgo}-5t3ktcr2es67cc94b.io. Can you help me ?

Đây là Puny Code ((https://en.wikipedia.org/wiki/Punycode)[https://en.wikipedia.org/wiki/Punycode]) dùng để encode các domain có chứa kí tự Unicode. Sử dụng trang https://www.punycoder.com/ ta giải ra được:

旗{一二三四letgo}.io -> Flag{1234letgo}

Dont You Know About JS ? (300pt)

http://ctf.framgia.vn/task/10

Sẽ có một bài write-up riêng cho task này. Coming soon...

Hidden Flag (100pt)

http://ctf.framgia.vn/task/6

Flag ẩn trong file font: http://ctf-framgia-objs.surge.sh/CloisterBlack.ttf của task trên.

The Message (150pt)

http://ctf.framgia.vn/task/7

http://ctf.framgia.vn/static/files/message.txt

Đây là 1 file được viết bằng các emoji của điện thoại. Lấy chữ cái đầu tiên tên tiếng Anh của các emoji ghép lại ta sẽ có:

iloveemojidottheflagisuppercaseflagcurlybracketemojiunderscoreisunderscoresounderscorefunnycurlybracket

The Encryptor (200pt)

http://ctf.framgia.vn/task/8

http://ctf.framgia.vn/static/files/encrypted.txt

http://ctf.framgia.vn/static/files/encryptor.rb

Ta biết là flag được mã hoá bằng các shift các ký tự theo vòng tròn (mã hoá Caesar) hoặc là encode base64 tuỳ vào giá trị random ra. Ta có thể làm ngược lại như sau:

  • Thử giải mã base64, nếu được thì OK
  • Nếu giải mã bị lỗi, ta tiến hành thử shift từng kí tự rồi lại thử giải mã base64 đến khi được thì thôi
  • Lặp lại 2 bước trên đến khi xuất hiện chữ "Flag" thì dừng.

Code: (python3)

import base64
import random
import string

alphabet = string.ascii_letters + string.digits

cipher = 'QjF5alRsSUN5MWEyQ0M2QkYxRzl5MkNhRktZUkNCTXJDSXlEdW11QnpBeXlWMnFkQjFZOXoxTWFHbFV6eW5lOUNENnF0MnFiR0tZQUMxNUlCQWkxU21tOEIxNkNTbXFzRjJ5NUMzcTh0Q3VDdGxIZkJKYTFVQzZFQjBtWlNBbW5CMHFMQzN5RkJBaVlDSEdvQkNZRFREQzd6QXF6QzJHZ0dtR3J0bXViU2wyeUNsTTlGSk16eEl1Q0IxQ3VEbUNMQ0FpdnptNkN5RVUwQ2xHQkJFNlJSbXFseDF5Q1NsTWtCMGlyeUNtRVJLWTJSS2lIRENDeVYyeUZTbHl1Q0FtNkIxeW56bUM5ekU2MnlJNWRCMVRlRDNDQ1JncVpSSTZtQklHckJJcW9WbmFDdG95RENEYXZBbkNtUmxVdnltMkxCM2F6VW1xcFNLNkFEb2hkQklZblNtcGZ1QjZ6dEMyTENtVE16bnFtR2tDQ3RsMWVCSENHVm1VQkIyVVpSSE1nR0J5bkMycGdCRTYxQ0V5bUIxVURVQ0dtQTJHekMxTWJHQ3luQ25wZlNvQ3l0bEdMR25NZFVEeUV2Q0NaUkpkZUdDQzR0M0M4QkUyRERvaW9CRTZEUzJDYXVCTXp0Qk1tQ0hDNXltdUNBM2FDdG5hTURDR1JVM3FDeTBpdXRKZTVCMGlyQzIxZ0JFMjBDbllDRjNlbVZtQzd5NFlZdGwyTUMyWXJ1M3FFdGt5Q3QwQ3ZDRE15dG1HQ1VsWVl0M2FMQ0RIZXltbTl6NENHQ0R5QkIxRzlSbW03QTE2d0NCMk1BMlVSem5wZ0MwR3l0bllwRjNhR1VKcUZEMnl5dEhxOUdENnZSbUM5QTFDMkNLeWtCSmE4dURDQkExeVpDMU1mR21HOXRtdXB5MHV6eWw2bEIxWWR6M3FFeTBHdnptR2pDRGFIRDFRQ0RFWURDMTZEQUF1OHVDR290a3F5dEJNbEEzSE15bElOREFDQ3RtcUxGMG12VW5DRFNseUFTM2VOQjF5anRCSURBMXl2U0JHQUYzNlJ1M3lvdkVpR3RueUlEMnk1Q0hIZlZuSXp0NFlEQ0RlcnozdW1TbEN1dDFHQUNBcElVbFFEQjR1R0MxNUlCSXlHdW1xbUExWTBTbXFIQTJVUkMydGVDRVl5dG45ZkYwaXZUSUdCeTBDdUNEWWFCMHBJejJVYlNsZVlDQk1vQkFpMXVDRzd6MXl6UkhJTkNtWURDSElCRDMyeVIxTTlEMVk1ejFJN1JseXZ5MkZlR0NDSFRtQzhCMUNCQ0NxQkFEZUR5SkNseTE2MVNsTW1HQ0NueEltRnkwcXp5bExlRjJHelVDeUZUbHlBQ21HOUJDeWpUbEluREVZQUNDR2pBQ0MxQklDOFJsMlJSSDJNQkU2OXlucUJDM0l5UjE2REdtWTl6Qk03QzF1WkRuWThHa3U0dkNpeXdBSD0='

def try64(cipher):
	cached = cipher
	try:
		cipher = base64.b64decode(cipher)
		cipher = cipher.decode('utf8')
		for c in cipher:
			if c not in string.ascii_letters + " {}_=" + string.digits + "\n":
#				print('fail character !')
				return True, cached
		return False, cipher
	except:
#		print('fail to decode base64')
		return True, cached

while True:
	print(repr(cipher[:50]))
	bad, cipher = try64(cipher)
	if bad:
		for shift in range(1, len(alphabet)):
			tmp = cipher
			alphabet_shift = alphabet[shift:] + alphabet[:shift]
			tmp = tmp.translate(str.maketrans(alphabet, alphabet_shift))
			if 'Flag' in tmp:
				print('OK', tmp[:50])
				input()
			#print('shift', shift, tmp)
			bad, tmp = try64(tmp)
			if bad:
				pass
			else:
				print('OK', shift, tmp[:50])
				cipher = tmp
				break

The Wire (200pt)

http://ctf.framgia.vn/task/9

Somebody caught KhanhLD is transferring the flag and recorded some infos !!! Check it out now : captured.pcapng

http://ctf.framgia.vn/static/files/captured.pcapng

Đây là một file có các gói tin giữa máy tính và phần mềm AirDroid. Vì AirDroid đơn giản là 1 web server nên dử dụng tính năng Export HTML Objects của Wireshark, ta sẽ lấy được các file PNG được cắt ra từ ảnh QR code của flag. Ghép lại ta có:

flag.jpg

Pairs (150pt)

http://ctf.framgia.vn/task/11

 HuyND found this strange note !? It took him so many times but he still can figure out its meaning...
May be you can ?

http://ctf.framgia.vn/static/files/pairs

Đây là các cặp số, ta có thể nghĩ đến ngay là toạ độ điểm ảnh. Viết 1 chút code để vẽ các điểm ảnh này vào 1 file ta sẽ có flag.

flag.png

Easy Math (200pt)

http://ctf.framgia.vn/task/12

netcat aicontest.framgia.vn 2015
   ___  ____  _______ __      ___ ___  ____ ______ __ __
  /  _]/    |/ ___/  |  |    |   |   |/    |      |  |  |
 /  [_|  o  (   \_|  |  |    | _   _ |  o  |      |  |  |
|    _]     |\__  |  ~  |    |  \_/  |     |_|  |_|  _  |
|   [_|  _  |/  \ |___, |    |   |   |  _  | |  | |  |  |
|     |  |  |\    |     |    |   |   |  |  | |  | |  |  |
|_____|__|__| \___|____/     |___|___|__|__| |__| |__|__|

If you fast enough, I may tell you something interesting...
11584 * M + 74667 * N = 345004
59994 * M + 19507 * N = 318004

Result?:

Hai phương trình 2 ẩn, ta có thể tính được M, N. Too easy ?

Excelent ! I told you everything. Now go submit your flag :D

Where's flag ? Nhìn lại vào các kết quả. Ta đều thấy M, N trong khoảng từ 0 -> 4, kèm với gợi ý 5 x 5 -> toạ độ điểm trên hình vuông ví dụ:

@@#@@
@##@@
@@#@@
@@#@@
#####

1. Tương tự cho các chữ cái sau.

What Go Around Come Around (200pt)

http://ctf.framgia.vn/task/13

netcat aicontest.framgia.vn 1990
               ___     __   __           __   __             __      __   __         ___          __   __             __
|  | |__|  /\   |     / _` /  \     /\  |__) /  \ |  | |\ | |  \    /  ` /  \  |\/| |__      /\  |__) /  \ |  | |\ | |  \
|/\| |  | /~~\  |     \__> \__/    /~~\ |  \ \__/ \__/ | \| |__/    \__, \__/  |  | |___    /~~\ |  \ \__/ \__/ | \| |__/

|  E  |  1< |  2v |
|  1^ |  1< |  1< |
|  1^ |  1^ |  1^ |

Pick a point to start, and take exactly 5 steps to the End !
 Coordinate row col ?:

Hướng giải quyết là bruteforce tất cả các vị trí trên bàn xem có phải là điểm xuất phát thoả mãn yêu cầu hay không.

Impossibru Encrypt (380pt)

It's impossibru to recovery the flag. Don't you dare to try, hur ?
Source: impossibru_encrypt.zip

http://ctf.framgia.vn/static/files/impossibru_encrypt.zip

Sẽ có một bài write-up riêng cho task này. Coming soon...

Burn It Down (250pt)

http://ctf.framgia.vn/task/15

Flag in this QR code. However, it doesn't have format Flag{some_snake_case_string}

burn_baby_burn.jpg

QR code lưu dữ liệu như sau.

qr_data

Nên các phần dữ liệu vẫn còn nguyên, chúng ta có thể dùng tool https://github.com/waidotto/strong-qr-decoder để recovery lại dữ liệu hoặc làm bằng tay nếu bạn muốn. Tham khảo thêm ở đây

y0u 5h0uld 533 7h15 (50pt)

Name of one of softwares that got installed in 2_d3bug ? (input as lowercase)

hãy xem tập 3 của series Mr.Robot để tìm flag nhé 😄

Final

Xin cám ơn mọi người đã nhiệt tình tham gia, hẹn gặp mọi người vào lần CTF tới (bye).

Good Game ! Well Played !

ctf5_final.png

All Rights Reserved