SVATTT 2020

Giới thiệu

Mình là Trung, đến từ team “HCMUS.Twice”. Tên này được thầy và các anh em chọn sau khi thầy phát hiện có 1 ổ fan KPOP trong group CTF của câu lạc bộ trường :v.

Team mình có 4 người: mình (RE), anh Ân và anh Lâm (web) và anh Hy (crypto).

Kì thi sơ khảo

Đây là lần đầu tiên 4 người tụi mình chơi CTF cùng nhau. Trước đó, trường có tổ chức nội bộ một kỳ CTF để chọn người đi thi SVATTT, và lúc đó chỉ có mình và anh Ân chung một đội, còn anh Lâm và anh Hy ở đội khác. Nhưng dù sao thì team mình vẫn phối hợp khá ăn ý trong đợt thi sơ khảo.

Về phần của mình, mình đã giải được hai câu RE.

Findme

Câu đầu tiên: “findme”: trong lúc thi, mình đã mở bài này ra xem đầu tiên, tuy nhiên có rất nhiều hàm “lạ”, nên mình đã đóng IDA lại ngay luôn để làm bài “crypt”. Khi đang làm được 1 nửa bài “crypt” rồi thì mình thấy đã có 5 team giải được bài “findme”, nên mình đã nghĩ rằng câu này chắc chắn dễ, thế là mình lại dừng bài “crypt” lại để chuyển sang làm bài “findme”.

Sau đó mình đã dùng procmon để theo dõi thì thấy process “findme.exe” drop một file khác. Vì từ lúc đó cho tới lúc mình viết bài này đã khá lâu nên mình không thể nhớ để trình bày rõ ràng các bước giải, nhưng đại khái mình làm như sau:

  • Phân tích tĩnh file mới được drop thì thấy 1 vtable ở trong IDA.
  • Debug “findme.exe” và đặt breakpoint tại CreateProcessA (hay CreateProcessW gì đó mình không nhớ).
  • Mở một cửa sổ debugger mới, attach vào process mới được tạo, đặt breakpoint tại tất cả các hàm mình thấy trong vtable.

Và cuối cùng, sau khi nhập password vào “findme.exe”, thì một trong số các hàm ở vtable hit breakpoint. Hàm này nhận duy nhất một tham số là input ta nhập vào, tính toán một số phương trình, rồi return true hoặc false. Đến đây mình dùng z3 để giải và lấy flag.

Crypt

Câu tiếp theo: “crypt”: câu này thật sự khó chịu đối với mình. Vì câu này bỏ vào IDA, nó sẽ bị mất tên hàm tùm lum, mà mình thì quen bấm F5 rồi. Cho nên mình quyết định: tải ghidra về, nhìn tên hàm trong ghidra và rename trong IDA.

Câu này chỉ đơn giản là nhập input, sau đó input này sẽ được đem cộng với một hằng số khác, rồi so sánh với một hằng số nữa. Tuy nhiên trong cuộc thi, mình đã quá áp lực và mất khá nhiều thời gian vào câu này. Thậm chí não mình còn bị lag, không biết cộng số, và phải nhờ anh Ân cộng dùm :smile: (nhưng dù gì thì team mình vẫn first blood câu này).

Sau khi kiểm tra input, chương trình sẽ lấy số input để tạo ra key AES để mã hoá file. Đến đây mình chỉ đặt breakpoint tại hàm AES_init để lấy key, rồi giải mã file đề cho với key vừa lấy được —–> ra flag ^^!

Câu RE còn lại là về vm, mình đã không đủ thời gian để giải nốt.

Về các đồng đội của mình:

  • Anh Hy đã gánh team với việc giải 3 bài crypto, và cũng là người nhanh nhất giải đủ cả 3 bài.
  • Anh Lâm và anh Ân đã giải thành công bài web, và bài này cũng chính là bài quyết định giúp đội mình vươn lên trên đội thứ nhì là Efiens, một đội rất mạnh đến từ trường đại học Bách Khoa TPHCM.
  • Cuối cùng, team mình đã đứng nhất kỳ thi sơ khảo.

Bảng xếp hạng kì thi sơ khảo, đội mình hơn đội về nhì đúng một bài web

Me and the kpop fanboys

Kì thi chung khảo

Trước kì thi, bọn mình đã đọc writeup của kì thi chung khảo năm ngoái (network, attack and defense) và setup môi trường để làm theo. Tuy nhiên đến gần ngày thi thì ban tổ chức gửi email luật chơi cho các đội: KHÔNG giống năm ngoái, và thế là công sức bọn mình luyện tập đã bị đổ đi :disappointed:.

Diễn biến ngày thi:

7 giờ

Team mình đã có mặt khá sớm tại điểm thi để setup môi trường, máy áo, test mạng các thứ …

8 giờ

Lúc này, ban tổ chức đang phát biểu khai mạc kỳ thi, nhưng mình nhìn xung quanh thì đã thấy các đội bắt đầu tải đề về làm, nên mình cũng tải đề về làm luôn :v.. Mình có một thói quen là thường hay làm bài theo thứ tự, vì vậy, mình bắt đầu phân tích bài Pwn01 đầu tiên, để lại hai bài pwn là Pwn02Pwn03.

Khoảng 8 giờ 15

Trong lúc mình đang làm bài Pwn01 thì đồng đội mình bảo đã có đội ghi điểm. Đó chính là đội Efiens, đã attack thành công bài Pwn02. Lúc này mình khá hoảng, nhưng mình lại có suy nghĩ rằng, nếu có đội giải được bài trong thời gian như vậy, thì chắc chắn là bài này không khó. Vì vậy mình đã chuyển sang làm bài Pwn02.

Khoảng 8 giờ 25

Mình nhận ra ngay lỗi buffer overflow trong bài này, và đã thành công với việc vá lỗ hổng như sau: mình chỉ cho chương trình nhận vào 256 ký tự thay vì 288 ký tự ở hàm scanf. Sau khi vá, mình thử exploit lại và không được, lúc này mình nghĩ là đã tạm ổn và tiếp tục làm bài Pwn01, nhưng không ….

Khoảng 8 giờ 45

Team Efiens đã chiếm lại thành công bài Pwn02 mặc dù mình đã vá lỗi buffer overflow, chứng tỏ bài này có lỗ hổng khác.

Khoảng 9 giờ hơn

Anh Hy đã chiếm thành công bài Crypto01 từ đội khác, đồng thời vá luôn lỗ hổng. Với việc vá lỗ hổng này, anh Hy đã chiếm đóng vùng đất này một khoảng thời gian khá dài, mang về một số điểm không hề nhỏ cho đội.

Trong lúc team mình đang chiếm giữ bài Crypto01, anh Hy đã giải được hai bài Crypto Jeopardy, đem về hơn 1500 tiền cho cả đội.

Khoảng 10 giờ

Team Efiens là team đầu tiên tấn công thành công bài Pwn03 và đang dẫn đầu, lúc này mình khá áp lực vì mình là người chơi pwn duy nhất trong team.

Khoảng 10 giờ hơn

Mình thử chạy bài Pwn03, đó là một game bắn xe tăng, ai sống lâu nhất sẽ có flag. Tuy nhiên không hiểu sao có round mình thắng nhưng không lấy được flag. Ngoài ra còn có một thời gian mình không connect được tới server trong khi các team khác vẫn cứ ăn điểm bài này đều đều :cry:.

Khoảng 12 giờ

Team Efiens đã chiếm đóng thành công bài Crypto01, đồng thời vá lỗ hổng, khiến cho script của anh Hy trở nên không hoạt động được nữa, lúc này team mình khá hoảng loạn.

Còn mình, đến lúc này, mình phát hiện ra bài Pwn02 còn có 1 cách khác để giải, chính là đoán random với tỷ lệ ra flag là 10%. Vì vậy mình đã viết script để đoán liên tục cho tới khi ra flag thì dừng.

Khoảng 13 giờ 30

Đội Efiens đã chiếm giữ bài Crypto01 khá lâu, nên mình và các đồng đội đã bàn chiến thuật, và dùng tiền để đóng băng vùng đất Crypto01 lại. Điều này có hai tác dụng:

  • Một là giữ chân đội Efiens lại, lúc đó, đội Efiens là đội dẫn đầu bảng xếp hạng, đội mình đang đứng nhì.
  • Hai là giúp anh Hy có thêm thời gian để tìm lỗ hổng khác trong bài Crypto01.

Mình đã dùng đóng băng 3 lần liên tiếp để giữ chân Efiens.

14 giờ 15: một bước tiến lớn

Đây là lúc đóng băng hết hiệu lực, và, đúng lúc đó, anh Hy đã tìm ra cách chiếm lại vùng đất Crypto01.

Cùng lúc đó, anh Lâm và anh Ân đã RCE được bài web.

Còn script của mình thì vẫn chạy đều đều :smile:.

14 giờ 30

Dù đã RCE được bài web nhưng bọn mình vẫn không tìm được flag trong suốt 15 phút (vì bọn mình đã làm một số thứ nhảm shit, cố đặt reverse shell nhưng con server của ban tổ chức không ra internet được hay sao ấy) … Cuối cùng bọn mình đã tìm được flag nhờ dòng lệnh sau …

find / -name "*flag*"
  • … có lẽ team mình phải học lại linux cơ bản rồi …
  • Sau đó team mình vá bài web lại, và kiếm được khá nhiều điểm từ bài này …

15 giờ

Anh Hy lại tìm được một lỗ hổng khác trong bài Crypto01 mà không đội nào vá được. Lúc này đội mình vẫn đang tạm dẫn đầu, nên mình đã đề xuất ý tưởng sau: team mình sẽ không cố gắng vá cái gì nữa, mà chỉ ngồi chiếm đất qua lại với các đội khác thôi. Bởi vì bọn mình biết chắc rằng bọn mình có khả năng chiếm lại bất kỳ bài nào trong 3 bài sau: Pwn02, Web01, Crypto01, nên nếu bọn mình cứ giằng co qua lại với các đội khác, thì điểm của team mình và các đội khác sẽ tăng NHƯ NHAU, tức là team mình vẫn giữ được vị trí số 1.

16 giờ

Chiến thuật của mình đề xuất đã thành công:

Bảng xếp hạng kỳ thi chung khảo

Cuối cùng

Từ trái qua: anh Lâm, anh Ân, anh Hy và mình

Bọn mình đã có một kỳ CTF với nhau thật tuyệt vời, xin cảm ơn ban tổ chức đã tạo ra một sân chơi bổ ích cho các sinh viên !

Em cũng xin cảm ơn thầy Duy và khoa Công nghệ thông tin đã tạo điều kiện cho bọn em được tham dự kì thi SVATTT 2020.

Đồng thời tất cả các anh chị em ở Cyberjutsu đã giúp đỡ bọn em rất nhiều trong việc luyện tập các challenge, và còn cung cấp bàn phím cho em nữa :smile:.

~~ Trung ~~