Thứ Hai, 7 tháng 9, 2015

[Writeup] MMA CTF 2015


Link CTF: http://score.mmactf.link

Lâu rồi mới có 1 CTF để thử xem trình độ của mình đang ở đâu.
Mình quyết định chơi solo. Một số bài bí quá thì nhờ sự hỗ trợ từ một số bạn team khác.

Nãy mình quay clip showup nhưng đang quay thì trang của MMACTF báo lỗi nên mình bỏ rồi.
Sau đây mình sẽ writeup một số bài mình đã làm được trong MMA CTF 2015.

Welcome!!

Quá đơn giản phải không?
Copy và paste MMA{Welcome_To_MMACTF!!} vào ô Flag và submit.
10 điểm đầu tiên :D


Pattern Lock
Bài này mình google chứ chịu thôi. Giờ cũng quên mất flag rồi :D





Smart Cipher System

Problem

Decrypt 4 flags.

Bài này có tới 4 flag để giải quyết.
OK Bắt tay vào làm nào:

crypt2:
Ta thử một vài trường hợp:
a => 4a
ab => 4a 4b
ba => 4b 4a
acb => 4a 4b 4c
OK vậy là với mỗi kí tự trong bảng ascii sẽ tương ứng với 1 hex
Flag của MMA có dạng MMA{something}
=> Ta nhập bộ charset là 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ{}
kết quả ta được:
1a 1b 1c 1d 1e 1f 20 21 22 19 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 64 66

Mỗi kí tự trong charset tương ứng với 1 hex trong cùng thứ tự với kết quả.
So sánh từng kí tự trong cipher đề cho để decrypt ra flag:
Mình code luôn cho nhanh: http://pastebin.com/GT7cr1bF
Flag: MMA{bba85b6768db240f8c4ae3c29f9928c74f6ca091}

crypt4:
Tương tự crypt2:
Charsets: 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ{}
Kết quả trả về:
c7 23 c3 18 96 05 9a 07 12 04 ef aa fb 43 4d 33 85 45 f9 02 7f 50 3c 9f a8 51 a3 40 8f 92 9d 38 f5 bc b6 da 83 2c 1a 1b 6e 5a a0 52 3b d6 b3 29 e3 2f 84 53 d1 00 ed 20 fc b1 5b 6a cb be 21 ff

Flag: MMA{f52da776412888170f282a9105d2240061c45dad}

crypt5:
Ta đã biết flag có dạng MMA{something}
và something có charsets là: 0123456789abcdef
Nên ta nhập 4 kí tự đầu của flag và thử thêm 1 số trường hợp:
MMA{    =>    49 00 0c 3a
MMA{a    =>    48 00 0c 3a 1a
MMA{b    =>    48 00 0c 3a 19
MMA{c    =>    48 00 0c 3a 18
MMA{aa    =>    4b 00 0c 3a 1a 00
MMA{ab    =>    4b 00 0c 3a 1a 03
MMA{bb    =>    4b 00 0c 3a 19 00
MMA{f52da776412888170f282a9105d2240061c45dad} => 60 00 0c 3a 1d 53 07 56 05 56 00 01 02 05 03 0a 00 00 09 06 07 56 54 0a 0a 53 58 08 01 05 51 56 00 06 04 00 06 07 52 57 01 51 05 05 19 (flag crypt4)
Ta thấy hex đầu tiên liên quan tới độ dài của chuỗi ta nhập vào.
Từ hex thứ 2 trở đi thì mỗi hex tương ứng 1 kí tự ta nhập vào.
Ở tại mỗi vị trí thì hex trả về khác với hex ở ví trị khác. (ở trên ta thấy MM nhưng hex trả về là 00 và 0c)
OK vậy bruteforce thôi.
Với mỗi vị trí ta thử với 1 kí tự trong charsets sao cho hex trả về tương ứng hex với cipher (tạm bỏ qua hex đầu liên quan tới số độ dài flag)

Mình cũng code luôn: http://pastebin.com/pAVLNY9z (yêu cầu cài thư viện selenium http://selenium-python.readthedocs.org/)
Flag: MMA{e75fd59d2c9f9c227d28ff412c3fea3787c1fe73}

crypt6:
Bài này cần tìm ra quy luật của nó mới giải được.
Nó khá khác với những bài trên.
Test:
MMA{0123456789abcdef0123456789abcdef01234567}    =>    64 a9 cc 28 a1 81 53 64 c6 a1 cd c6 1c 1c 39 c2 c2 8d c4 56 8d 0c 23 a9 56 31 cc 53 0c 39 31 23 64 31 cc cc a1 c4 53 f6 c6 cc cd cd be
MMA{1123456789abcdef0123456789abcdef01234567}    =>    64 a9 cc 28 a1 89 53 64 c6 a1 cd c6 1c 1c 39 c2 c2 8d c4 56 8d 0c 23 a9 56 62 cc 53 0c 39 31 23 64 31 cc cc a1 c4 53 f6 c6 cc cd cd be
MMA{112345a789abcdef0123456789abcdef01234567}    =>    64 a9 cc 28 a1 89 53 64 c6 a1 cd 2c 1c 1c 39 c2 c2 8d c4 56 8d 0c 23 a9 56 62 cc 53 0c 39 31 23 64 31 cc cc a1 c4 53 f6 c6 cc cd 6e be

=> Mỗi kí tự sẽ tác động tới hex tại 2 vị trí
Hướng giải quyết: Ta thu thập tất cả các vị trí mà hex bị thay đổi, sau đó tìm những kí tự có liên quan vị trí hex của những kí tự MMA{ và } để fix cho giống với hex của cipher tại vị trí tương ứng

Vị trí flag tác động lên kí tự trong chuỗi hex trả về như sau:
pos[0]=[3, 4, 69, 70]
pos[1]=[9, 10, 69, 70]
pos[2]=[9, 10, 117, 118]
pos[3]=[15, 16, 117, 118]
pos[4]=[15, 16, 75, 76]
pos[5]=[21, 22, 75, 76]
pos[6]=[21, 22, 105, 106]
pos[7]=[27, 28, 105, 106]
pos[8]=[27, 28, 81, 82]
pos[9]=[33, 34, 81, 82]
pos[10]=[33, 34, 129, 130]
pos[11]=[39, 40, 129, 130]
pos[12]=[39, 40, 87, 88]
pos[13]=[45, 46, 87, 88]
pos[14]=[45, 46, 111, 112]
pos[15]=[51, 52, 111, 112]
pos[16]=[51, 52, 93, 94]
pos[17]=[57, 58, 93, 94]
pos[18]=[57, 58, 123, 124]
pos[19]=[63, 64, 123, 124]
pos[20]=[63, 64, 99, 100]
pos[21]=[0, 1, 99, 100]
pos[22]=[0, 1, 6, 7]
pos[23]=[6, 7, 12, 13]
pos[24]=[12, 13, 18, 19]
pos[25]=[18, 19, 24, 25]
pos[26]=[24, 25, 30, 31]
pos[27]=[30, 31, 36, 37]
pos[28]=[36, 37, 42, 43]
pos[29]=[42, 43, 48, 49]
pos[30]=[48, 49, 54, 55]
pos[31]=[54, 55, 60, 61]
pos[32]=[60, 61, 66, 67]
pos[33]=[66, 67, 72, 73]
pos[34]=[72, 73, 78, 79]
pos[35]=[78, 79, 84, 85]
pos[36]=[84, 85, 90, 91]
pos[37]=[90, 91, 96, 97]
pos[38]=[96, 97, 102, 103]
pos[39]=[102, 103, 108, 109]
pos[40]=[108, 109, 114, 115]
pos[41]=[114, 115, 120, 121]
pos[42]=[120, 121, 126, 127]
pos[43]=[126, 127, 132, 133]

Ta fix từ vị trí thứ 4 trở đi sau MMA{
Tại vị trí thứ 4 của flag ta thử từng ký tự trong charsets 0123456789abcdef  để vị trí kí tự của hex trả về tại 15,16 giống với các kí tự tại vị trí 15,16 của cipher

Rồi tiếp tục các kí tự thứ 5,6,7,...
Mình cũng code nốt: http://pastebin.com/N9bJFBsh

Flag: MMA{f9cf7a3ddd5710e85116814fef01c907f4df35ce}
Vậy là hoàn thành 4 bài crypto :D
======================


Login as admin!
 
Flag là mật khẩu admin
OK. Test thôi
Thử admin:admin nhưng invalid username or password
Thử tiếp: user:user
You are test user.
logout
OK. Vậy ta phải login = admin.
Test bypass login:
Query: username=admin'-- -&password=XXX
Congratulations!!
You are admin user.
The flag is your password!
logout
OK vậy dính lỗi sql rồi.
Bài này nó không xuất thông tin cho chúng ta ngoài việc login thành công thì xuất You are ... và sai tài khoản hoặc mật khẩu thì invalid username or password
Vậy ta nghĩ ngay tới blind sql injection.
query: username=test' and password='test'-- -&password=XXX 
=>  You are test user.
Vậy có column password trong table.
Blind password admin thôi :D

query: username=admin' and substr(password,1,1)='a'-- -&password=XXX
result: invalid username or password

Ta biết flag (password của admin) có định dạng MMA{something} nên thử chữ M
query: username=admin' and substr(password,1,1)='M'-- -&password=XXX
result:
Congratulations!!
You are admin user.
The flag is your password!
logout
OK vậy mình code thôi :D
http://pastebin.com/kUNkkPbr
Flag: MMA{cats_alice_band}


======================
stream...  Forensics

Đề cho: http://assets.score.mmactf.link/attachments/stream-ae909d8550c45e47b3c888c3c35ce5a6699de5390968e91b53a718d73c237718


Nếu chưa biết định dạng gì thì cho vào hex editor coi có string Dumpcap 1.12.7 => open với wireshark coi thôi
Ubuntu nó tự nhận diện file type rồi nên mình mở được ngay

Đa phần packet liên quan tới GET HTTP request ở packet thứ 21.

Follow tcp stream:
Cái này khá lạ với mình nên mình sẽ bắt đầu tìm một số thông tin.
Bắt đầu từ cái User-Agent: NSPlayer/9.0.0.4503
Google ta được: https://github.com/gshutler/useragent/blob/master/lib/user_agent/browsers/windows_media_player.rb 
# Windows XP with Windows Media Player 9::
#   NSPlayer/9.0.0.4503
#   NSPlayer/9.0.0.4503 WMFSDK/9.0
#   Windows-Media-Player/9.00.00.4503
=> Đoán ngay nó stream video qua Windows Media Player
Một số thông tin trong http header khác mình đã tìm nhưng không có gì đặc biệt.
Tiếp theo mình tìm header $H xem là file gì hay cái gì đó
https://msdn.microsoft.com/en-us/library/cc251289.aspx

Lúc đầu mình nghĩ ngay là phải dựng con server cho nó stream video cho thằng Windows Media Player nhưng google mãi không biết cách tạo. Cuối cùng mình đành dùng cách là code socket giả lập lại y hệt những gì nó gửi cho WMP.


Lưu lại thành stream.bin

Code: http://pastebin.com/jPFcKDKi
Mình run code python trên Win 7. Sau đó vô WMP
Nhập http://127.0.0.1:8080 vào và OK

Flag: MMA{windows_xp_is_too_old_to_create_problem!!}
==============
Splitted forensic

Đề cho: http://assets.score.mmactf.link/attachments/splitted.7z-68ad844f2aab26d3d358ae9fa6c598a2727b0c0056567a288ffcd9414229121c

splitted.7z => extract file ta được 1 file splitted.pcap => Mở với wireshark
Đập ngay vào mắt là /flag.zip
OK export http object ngay và luôn
File => Export Objects => HTTP
Lắm flag.zip thế này :v
Save all về xem xét
Quăng hết vô hexeditor coi nào (mình dùng Bless Hex Editor)

File ZIP có file signature (magic number) là PK mà trong đâu không có PK ?
Mở sang file flag(1).zip:

PK đây rồi. File bị nén là flag.psd
Thử extract xem sao: 
  
 Ố ồ. Vậy là ta cần ghép các file flag.zip lại thành 1 file zip hoàn chỉnh nhưng... thứ tự các file này đã bị thay đổi.
Nếu thử sắp xếp rồi extract thì ta có tổ hợp quá trời là trường hợp.
Vậy sao đây? 
Đề cho mỗi 1 file pcap thì vô file đó tìm thêm thông tin thôi :D
Follow 1 HTTP stream:

Bingo... Thứ tự của nó là đây :D
OK ta chỉ cần coi range và đổi lại tên file cho đúng với range sau đó gộp các file lại là được 1 file ZIP hoàn chỉnh

Giải nén file zip: ta được file flag.psd
A .PSD file is a layered image file used in Adobe PhotoShop. PSD, which stands for Photoshop Document, is the default format that Photoshop uses for saving ...
Mình không có cài PhotoShop. Làm sao giờ?
PhotoShop online thôi :D
http://vforum.vn/photoshop/ 

Trắng như ô mô thế này
Để ý ta thấy có tới 2 layers.
Ẩn layer 1 đi bằng cách unstick.

Done! Flag: MMA{sneak_spy_sisters}
==============
Mình tạm dừng tại đây có thời gian mình sẽ writeup hoặc showup tiếp một số bài nữa!

Thứ Sáu, 10 tháng 7, 2015

[Hướng dẫn] Giải 1 số bài CTF coding trong CTF, wargame

Ví dụ: https://www.hackthis.co.uk/levels/coding/1

Đọc yêu cầu của đề nào: Các từ bị xếp lộn xộn. Nhiệm vụ là sắp xếp lại các từ theo thứ tự alphabet. Sau đó submit kết quả với cùng định dạng. Thời gian để hoàn thành là 5 giây.

Phân tích: với thời gian 5 giây thì với thao tác thủ công ta không thể nào hoàn thành kịp nhiệm vụ này. Vì vậy ta cần phải giải bài này bằng code.
Các bước: Lấy danh sách các từ bị sắp xếp lộn xộn => sắp xếp chúng lại theo thứ tự => Submit kết quả

Bài này sử dụng http request. Với python ta có thể sử dụng thư viện có sẵn như requests (http://docs.python-requests.org/en/latest/) nhưng mình đã code 1 hàm sẵn rất đơn giản và tiện dụng (http://pastebin.com/e7CueNfU)
Cách sử dụng:
Bạn cần 3 param (url, post_data, cookie) nếu sử dụng get thì post_data = "", nếu không cần cookie thì gán cookie = ""
OK. Lấy cookie, url
Sử dụng add-on livehttpheader ta được thông tin request như sau:

OK.
Giao thức là GET
url = https://www.hackthis.co.uk/levels/coding/1
Cookie = _ga=GA1.3.1205173578.1433484176; member=1; km_ai=x2PU%2FQmuZkE0OR%2F2qGxqE6N7Jqo%3D; km_uq=; km_lv=x; autologin=o-%01%98%7F%09%D3%EBW%22w%FBGc%B5%8C%5C%EC%1E%24%B4n%E7%25%93%E7%02%8F%AC%BB%E2V4%BE%C0%9C%A6%E7%A7%16%7BFc+%8B%C4%D1h%A3%B5%F5s%D9jUs%08J_Z%A1%A1%C1o; PHPSESSID=j0k3ihv246vdijl3om5f7f8a87

OK. Đưa vào hàm requests lấy dữ liệu về thôi.


Run:

Đoạn bôi trắng là đoạn ta cần quan tâm.
Làm sao để lấy được các từ ra?
Suy nghĩ đơn giản thôi nào. Biến res của ta chỉ là string thôi nên ta chỉ việc phân tích chuỗi là có thể lấy được các từ ra.
Ta có thể sử dụng tới Regular expression operations (https://docs.python.org/2/library/re.html) nhưng RE có thể gây tốn thời gian. Vì form này có format như nhau sau mỗi lần request nên ta chỉ cần sử dụng các hàm xử lý chuỗi đơn giản nhằm tránh mất thời gian.
Trước các từ cần quan tâm là chuỗi "<textarea>" và sau các từ cần quan tâm ta có "</textarea>" mà trong chuỗi res ta chỉ có duy nhất 1 chuỗi "<textarea>" trong đó. OK simple rồi. Lấy chuỗi từ sau "<textarea>" và trước "</textarea>" là được chuỗi các từ cần tìm.
Run:
OK. Việc tiếp theo là tách chuỗi này thành các từ riêng lẻ.
Giữa các từ được phân cách bằng chuỗi ", " vì vậy ta có thể sử dụng hàm split để tách ra.
Run:
OK. Vậy ta được 1 list các từ.
Tiếp theo là sắp xếp các từ. Vì đây là list nên ta có thể sử dụng hàm sorted (https://docs.python.org/2/library/functions.html#sorted)

Như vậy ta thấy list words trên chưa được sắp xếp nhưng list answer dưới đã được sắp xếp theo alphabet.
Nhiệm vụ bây giờ là biến list thành string theo đúng format ban đầu (cách mỗi từ là chuỗi ", ") và submit.
Để biến chuỗi thành đúng format ban đầu ta dùng hàm join.

OK. Ta có chuỗi answer đúng format và đã được sắp xếp.
Nhiệm vụ bây giờ là submit.
Ta coi http request bằng livehttpheader:
Giao thức: POST
Url: https://www.hackthis.co.uk/levels/coding/1
Cookie: như cũ
Post_data: answer = chuỗi_các_từ_đã_được_sắp_xếp


OK. tiếp tục :D
OK. Level Completed

Còn một số dạng nữa khi nào rảnh mình sẽ cập nhật

Bạn nào chưa hiểu thì có thể comment hoặc liên hệ facebook mình:
https://www.facebook.com/xxvicon

Chủ Nhật, 28 tháng 6, 2015

OnePiece at UIT & ATTT

Từ phải qua: Trần Anh Khoa, Lê Huy Hoàng, Tạ Đình Sung, Nguyễn Thành Nguyên


Trước khi bắt đầu cuộc thi

Quá trình giải đề. Tiêu tốn 2 lon bò húc, 1 chai 0 độ và 1 vài chai Sting

 Kết quả :D

Cờ và cúp vô địch

OnePiece và pwn_the_world (trái), CLAY (Phải)

OnePiece và BTC Cuộc thi

Chúc mừng các đội và cảm ơn UIT đã tạo ra 1 cuộc thi vô cùng hay cho mình và các bạn sinh viên.

Thứ Sáu, 29 tháng 5, 2015

[Malware Analysis] BOTNET-NEW

Tình hình là tập tành phân tích Malware nên xin anh Phạm Việt Hòa (Levis) share cho vài mẫu Malware đơn giản.
Anh share cho mẫu trong tool ddos của 1 người post trên forum CEH.
Link: http://www.mediafire.com/download/dx8di7t24515w46/BOTNET-NEW.exe

OK. Download về tiến hành dịch ngược xem thế nào :D

Quăng vào IDA thì nhận được thông tin sau:
.NET :D Thật là tuyệt vời. .NET thì dễ xem source rồi

Quăng vào ILSpy tiến hành xem source code thôi :D


Như ta thấy trong Form1
Có 1 string khá lạ lùng là apha: tại sao lại có những ký tự loằng ngoằng mì tôm thế kia? Mục đích là gì?
Ta tiến hành xem xét tiếp các hàm trong Form1.
Hàm buttonAttack_Click_1 không có gì khả nghi. Chỉ là cho WebBrowser dùng bot tấn công vitim.
Tới hàm buttonBrowser_Click ta thấy có đoạn liên quan tới chuỗi apha ở trên:
string value = string.Concat(new string[]
    {
        this.apha[9].ToString(),
        this.apha[44].ToString(),
        this.apha[9].ToString(),
        this.apha[44].ToString(),
        this.apha[9].ToString(),
        this.apha[34].ToString(),
        this.apha[34].ToString(),
        this.apha[39].ToString(),
        this.apha[36].ToString(),
        this.apha[33].ToString(),
        this.apha[23].ToString(),
        this.apha[26].ToString(),
        this.apha[9].ToString(),
        this.apha[2].ToString(),
        this.apha[29].ToString(),
        this.apha[43].ToString(),
        this.apha[8].ToString(),
        this.apha[24].ToString(),
        this.apha[26].ToString()
    });
Vậy value sẽ được gán là gì?

Gmail ?
LOADBOT để ddos thôi tại sao có gmail ở đây?

Tiếp luôn.


Sau khi value được gán thì nó được đưa vào class mtp và gửi đi.
Ta coi tiếp hàm Send() của mtp:

Đã rõ. Như ở trên ta thấy danh sách bot được đưa vào chuỗi text. chuỗi text được đưa vào mtp gửi đi qua email ở trên.

Như vậy, chủ con malware này tung tool này để người ta đem bot đi ddos người khác nhưng hắn lại được cái list bot đó và có thể điều khiển đám bot đó đi tấn công người khác.

Sau khi phân tích xong thì thử google tìm ra cái link này:
http://forum.ceh.vn/Tool-load-bot-cua-KymLjnk-ko-biet-share-co-bi-gi-ko-thread-7156-post-26848.ceh#pid26848
Trong đó đã có một vài thím phân tích con này trước rồi :D

Cảm ơn anh Việt Hòa đã giúp đỡ em.

Thứ Tư, 6 tháng 5, 2015

[Writeup] Camsctf - Helix

Đề cho
Helix - 20
Hmmm, I wonder who Lord Helix is and what he wants with you.
Hint: TweakPNG may not be your friend sometimes.
Một số bạn coi writeup của camsctf trên: https://github.com/dannyqiu/camsctf-in-s-ane nhưng thật sự có một số writeup khá khó hiểu. Bài Helix chỉ có 20 điểm. Dễ nhưng số lượng team giải được là rất ít.
Sau đây là writeup cách mình giải:

Download về đưa vào TweakPNG kiểm tra các chunk

Dùng notepad đếm số zTXt chunk:
12136 chunks. Coi hết chắc đuối.

Kiểm tra sơ qua ta thấy hầu như các chunk giống hệt nhau. => Ta tiến hành loại bỏ các chunk giống nhau.

Đưa ảnh vào HxD:

Đoạn bôi đen là 1 chunk zTXT có key là Helix
Tiến hành Replace: Ctrl R (Search -> Replace)
Chú ý copy hex để replace chứ copy binary thì sẽ lỗi. Chọn All thay vì Forward để replace toàn bộ. Sau đó chọn Replace all.
Kết quả:
12136 chunks mà đã bỏ đi 12134 chunks. Ta còn lại 2 chunks.
OK save rồi qua TweakPNG reopen lại:
OK. Mở thử 2 chunk này thì phát hiện ở chunk thứ 2 có đoạn:

Flag là:
 {5p3nc3r_no0o0_st0p}

Thứ Ba, 5 tháng 5, 2015

[Writeup] UITCTF 2014 - Magic Hat

Vừa có thím quăng cho cái file magic_hat.rar kêu giải bài này. Chưa biết format flag nhưng cũng thử xem qua phát đã.
Giải nén ra ta được 1 file ảnh PNG

Vì là file PNG nên cứ đưa vào TweakPNG xem các chunk đã :D (Có thể sử dụng fotoforensic.com cũng được)
http://fotoforensics.com/analysis.php?id=5f14471a586479fdbcd66d42f842476831ab5aca.797660
Tham khảo về chunk của PNG tại đây: http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html


Khá nhiều chunk nhưng đa phần toàn chunk liên quan tới ảnh. Để ý cái chunk iTXt ta thấy có 1 đoạn base64 (vì có = ở cuối. Xem thêm ở đây để hiểu vì sao có dấu = trong base64 http://en.wikipedia.org/wiki/Base64 )

eJwL9QxxDnGrzjVJz0yOh5CuZalFleUZqUWpirUAsEsLdQ==
Đưa vào hackbar trên firefox decode base64 thử thì được như sau:

Nhìn rối chả biết đằng nào mà lần.
Thôi thì ghi vào file rồi binwalk thử.



Ố ồ. Gzip decode thôi :D http://i-tools.org/gzip

UITCTF{m4gic_m4gic_Everywhere!}

Chủ Nhật, 3 tháng 5, 2015

[Writeup] VolgaCTF 2015 - Captcha