# **Write Up KCSC Recruitment 2024 (Forensics)**
## 1. Observation - Super weak c2 communication

Bài cho mình 1 file Challenge.pcapng, mở nó ra, follow TCP stream, mình phát hiện flag bị đảo ngược ở tcp.stream eq 2:

Reverse và ta có được flag:

> KCSC{s1mplY_Str1ng_R3v3rseD}
---
## 2. Observation - Credentials

Ở bài này author yêu cầu vẫn sử dụng file của bài trước, mình tiếp tục kiểm tra các TCP stream nhưng không thu lại được gì cho chall này, chuyển qua export HTTP, mình thấy có 2 file:

Tải 2 file đó về thì file key.txt chứa dãy mã hóa có vẻ không liên quan đến thử thách này, để đó và tập trung vào file lsass.DMP:
> Đây là file dump của quá trình Local Security Authority Subsystem Service (LSASS) trên Windows. Nó chứa thông tin về quá trình đăng nhập, bao gồm cả hash mật khẩu, ta có thể sử dụng Mimikatz (Windows)/Pypykatz (Linux).
Mình dùng Pypykatz trên Kali có được:

Vì flag yêu cầu là mật khẩu, mình thử decrypt NT hash và may là nó ra:
> NT hash (hay còn gọi là NTLM hash) là một dạng băm của mật khẩu trong hệ điều hành Windows. Khi một người dùng đặt mật khẩu trên hệ thống Windows, mật khẩu đó được mã hóa và lưu trữ dưới dạng NT hash.

> KCSC{FrostBite}
---
## 3. Observation - No more weakness

Có lẽ file key.txt từ thử thách trước sẽ được áp dụng vào bài này, khi đọc qua TCP stream của file ta thấy được có các đoạn mã hóa như sau:


Lúc đầu nhìn qua thì mình đoán đây sẽ là 1 loại mã hóa có key để giải (aes,...) nhưng sau khi tìm hiểu trên GG thì mình đã tìm ra được loại mã hóa ở [đây](https://stackoverflow.com/questions/28775567/why-does-a-fernet-encryption-token-always-start-with-the-same-sequence-python). Có vẻ dữ liệu file key và nội dung các đoạn mã hóa trên là kiểu mã hóa fernet, sử dụng [tool](https://asecuritysite.com/encryption/ferdecode) và test các mã trên, mình đã ra flag:

> KCSC{Y0u_Kn0w_F__E__R__N__E__T!!}
---
## 4. Showdown

Bài stego này cho mình 1 ảnh, theo thói quen mình bỏ vào trang [này](https://www.georgeom.net/StegOnline/upload), thay đổi các giá trị bit planes, có được:


Viết script combine 2 ảnh lại:
```
from PIL import Image
image1_path = "Out_of_eyes_sight (1).png"
image2_path = "Out_of_eyes_sight (2).png"
image1 = Image.open(image1_path)
image2 = Image.open(image2_path)
image1 = image1.convert("RGBA")
image2 = image2.convert("RGBA")
blended_image = Image.blend(image1, image2, alpha=0.5)
blended_image.save("combined_image.png")
blended_image.show()
```
Kết quả:

> Hoặc mọi người có thể dùng [tool](https://www.aperisolve.com/) này là ra luôn nhé!!!
> KCSC{Th3_uNse3n_bL@de_1s_the_D34dL1357}
---
## 5. Ping Flood

Bài cho file traffic.pcapng, mở file lên mình thấy loạt các gói tin ICMP, kiểm tra sơ bộ thì có vẻ như không có thông tin gì liên quan đến flag, nhưng khi đọc lại đề, author nhắc đến "DDoS", mình nghĩ có thể có thông tin ẩn trong số lượng lớn các gói tin đó:
> ICMP (Internet Control Message Protocol) là một giao thức thuộc tầng mạng (Network Layer) trong mô hình OSI, chủ yếu được sử dụng để chẩn đoán và kiểm tra các kết nối mạng. Nó không truyền tải dữ liệu ứng dụng mà chủ yếu truyền các thông điệp về lỗi và trạng thái mạng.
Sau kiểm tra thì mình phát hiện ra điểm quan trọng, đó là ở mỗi gói ICMP đều chứa một số trong phần "code", có thể là đại diện cho một ký tự mã hóa:

Hướng đi đã rõ, bây giờ chỉ việc trích xuất các ký tự đó ra và đem decode ascii, mình dùng GPT để viết script (xin lỗi các anh vì quá lạm dụng GPT ạ).
```
from scapy.all import rdpcap, ICMP, IP
packets = rdpcap('traffic.pcapng')
icmp_codes = []
for packet in packets:
if IP in packet and ICMP in packet:
if packet[IP].src == '10.0.0.6':
icmp_codes.append(packet[ICMP].code)
def decode_ascii(codes):
return ''.join(chr(code) for code in codes if 0 <= code <= 127)
decoded_string = decode_ascii(icmp_codes)
print(decoded_string)
```
Thế nhưng khi ra hết chuỗi ký tự, đem đi decode base64 thì nó vẫn lỗi, mình có mở ticket thì các anh bảo kiểm tra lại, và mình đã phát hiện ra ký tự mình cần lấy nó chỉ ở gói ICMP Echo Request:

Sửa lại 1 chút:
```
from scapy.all import rdpcap, ICMP, IP
packets = rdpcap('traffic.pcapng')
icmp_codes = []
for packet in packets:
if IP in packet and ICMP in packet:
icmp_layer = packet[ICMP]
if icmp_layer.type == 8: # ICMP Echo Request
icmp_codes.append(icmp_layer.code)
def codes_to_ascii(codes):
return ''.join(chr(code) for code in codes if 0 <= code <= 127)
ascii_string = codes_to_ascii(icmp_codes)
print("Decoded ASCII String from ICMP Echo Requests:")
print(ascii_string)
```
Chạy chương trình và dùng [CyberChef](https://gchq.github.io/CyberChef/) decode, ta tìm được flag:


---
## 6. Ѕuѕpiciouѕ

Bài cho file Ѕuѕpiciouѕ.ad1, mình dùng FTK Imager mở file, nhìn qua thì có 2 thư mục chính là User và Windows/System32, vì đề yêu cầu xem có malware không nên mình ưu tiên kiểm tra thư mục System32 trước:

Kiên nhẫn xem qua một loạt các folders trong System32 và các tệp log sự kiện để kiểm tra dấu vết của malware, mình phát hiện được điều đặc biệt ở **windows/system32/winevt/logs/Windows PowerShell.evtx**:

Có 1 đoạn base 64 khả nghi ở đây, decode và mình ra phần đầu của flag:

Tiếp tục tìm xem con malware nó đang ở đâu thôi! Sau 1 hồi loay hoay nhưng không tìm ra, author đã cung cấp hint: "**Have u ever heard of malware persistence?**" Hỏi thử GPT mình có được:

Mình được dẫn đến file NTUSER.DAT:
> File NTUSER.DAT thường chứa thông tin về cấu hình và các key registry của người dùng, bao gồm các key liên quan đến persistence
Trích xuất file đó ra, mở bằng Registry Explorer, cho phép mình duyệt qua các key registry và xem các cấu hình của người dùng:

Trong Registry Explorer, mình sẽ kiểm tra các value trong key **HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run** để xem các ứng dụng nào sẽ được khởi động cùng với hệ thống.
> Thông thường khi cài malware trên máy nạn nhân, hacker sẽ cố gắng cho malware khởi động cùng với máy để quá trình hack được diễn ra 1 cách tự động.
Phát hiện rằng "spoolsv.exe" được thiết lập để tự động khởi động khi máy tính khởi động. Điều này rất đáng ngờ vì "spoolsv.exe" là một file hệ thống thường được sử dụng cho các mục đích khác, và việc nó tự động khởi động có thể là dấu hiệu của một hoạt động đáng ngờ.
Export và tải lên VirusTotal, ta có:


Kết hợp 2 phần và ta có Flag hoàn chỉnh:
> KCSC{n0w_y0u_s33_th3_unidentified_m3_6f56399aec2db382190593623d200fe24069ef629a07990897e6945e3c758cca}
---
## 7. Aidoru

Thử thách cuối cùng mà mình có thể làm được trong thời gian thi, dù nó đc tag warmup, nhưng mất khá nhiều thời gian. Bài cho folder Users chứa các folder khác, đọc mô tả, mình dùng FTK để tìm tất cả các file đã bị xóa nhưng kết quả là không thể tìm thấy gì cả.
Mình có nghĩ tới hướng tìm những file có ngày chỉnh sửa gần nhất (vì nghĩ author mới ra đề vài ngày thôi), và đúng là như thế, nhiều quá tìm không ra nổi nên mình bỏ qua hướng này.
Vì đa phần chỉ có thể tải file từ trình duyệt, mình chuyển hướng sang tìm lịch sử các browser trong folder để xem các đường dẫn mà author đã truy cập, khá là may vì dường như author chỉ truy cập mỗi edge:

Kiểm tra sâu hơn, mình phát hiện ra:

Link drive đó không thể không đáng ngờ hơn được, mình nghĩ là truy cập link đó là bước cuối cùng để có flag rồi, nhưng có vẻ như trang đích đã bị xóa.
Vì gần hết giờ, để đẩy nhanh tiến độ, mình hỏi GPT lần nữa:

Nó vẫn nằm trong folder Default đó, nhưng có thể nằm trong cache (mình chưa nghĩ đến) nên đã tiếp tục tìm đến cache của edge với hi vọng tìm được data của các file đã tải về.
> Cache (bộ nhớ đệm) là một cơ chế lưu trữ tạm thời các dữ liệu thường xuyên được truy cập để cải thiện hiệu suất và giảm thời gian tải. Trong ngữ cảnh trình duyệt web, cache giúp lưu trữ các phần của trang web, như HTML, CSS, JavaScript, và hình ảnh, để khi người dùng truy cập lại trang web đó, các phần tử này có thể được tải nhanh hơn từ bộ nhớ đệm thay vì phải tải lại từ máy chủ.

Tập trung vào cache của edge, mình đã thấy được trong folder Cache_Data chứa nhiều file hình ảnh:

Tiếp tục kiểm tra, khá nhanh mình tìm ra được file f_000069 đã xuất hiện vài thứ có vẻ khả nghi:


Kiểm tra qua mình thấy đây là 1 file zip có chứa 1 bức ảnh tên confidential.png (bảo mật.png - nghi vấn là flag), không chậm trễ mình export file ra ngay, extract để xem có đúng không:

Author tăng thêm độ khó bằng cách đặt pass cho file này, dùng [john](https://www.kali.org/tools/john/) để crack pass:

Giải nén với pass đã tìm được, ta có flag:

> KCSC{n0w_y0u_f0und_my_s3np41_:3}
---
## 8. BabyStego

Bài cho 1 file babystego, khi kiểm tra file xác định là data.

Kiểm tra bằng HxD, mình phát hiện có vẻ nó là 1 file png nhưng bị author sửa lại phần header bytes.

Có thể thấy được file đã bị mất phần hex signature và các phần sau bị hoa thường lẫn lộn:

Mình lấy 1 ảnh png mẫu và fix 1 số byte cho đúng định dạng:




Chú ý một chút thì phần IDAT file bị author sửa hết chữ A hoa thành a thường nên mình cần fix lại hết, lúc thi mình không tập trung nhiều vào bài này do lúc đó sửa mỗi IDAT đầu xong nó hiện mỗi cái trần nhà, nên bỏ qua luôn (sorry StegoKing ạ), giờ mới xem lại thì bài này không khó lắm.
Sau khi đổi hết ta có ảnh chứa flag:


---
# Các challs mảng khác mình làm thêm được
## now you see me (WEB)

Truy cập vào trang đề cho, mình thấy đây là bài liên quan đến SSTI cơ bản:
> SSTI (Server-Side Template Injection) là một lỗ hổng bảo mật xảy ra khi một ứng dụng web sử dụng template engine để hiển thị nội dung động và không kiểm tra đầu vào của người dùng một cách an toàn. Template engine là một công cụ giúp tách biệt phần logic xử lý và phần hiển thị giao diện trong các ứng dụng web.
Đầu tiên mình thử payload {{ 1+1 }}:

Kết quả trả về là 2:

Tiếp tục sử dụng payload để thực thi lệnh đọc file flag.txt:

Kết quả:

> KCSC{flagrandomngaunhienlagicungdu0c}
---
## Base64 (CRYPTO)

Bài cho file python mã hóa FLAG bằng phương pháp mã hóa Base64 tùy chỉnh. Ta cần giải mã chuỗi mã hóa và tìm lại FLAG:
```
b64 = {
"000000": "/",
"000001": "+",
"000010": "0",
"000011": "1",
"000100": "2",
"000101": "3",
"000110": "4",
"000111": "5",
"001000": "6",
"001001": "7",
"001010": "8",
"001011": "9",
"001100": "a",
"001101": "b",
"001110": "c",
"001111": "d",
"010000": "e",
"010001": "f",
"010010": "g",
"010011": "h",
"010100": "i",
"010101": "j",
"010110": "k",
"010111": "l",
"011000": "m",
"011001": "n",
"011010": "o",
"011011": "p",
"011100": "q",
"011101": "r",
"011110": "s",
"011111": "t",
"100000": "u",
"100001": "v",
"100010": "w",
"100011": "x",
"100100": "y",
"100101": "z",
"100110": "A",
"100111": "B",
"101000": "C",
"101001": "D",
"101010": "E",
"101011": "F",
"101100": "G",
"101101": "H",
"101110": "I",
"101111": "J",
"110000": "K",
"110001": "L",
"110010": "M",
"110011": "N",
"110100": "O",
"110101": "P",
"110110": "Q",
"110111": "R",
"111000": "S",
"111001": "T",
"111010": "U",
"111011": "V",
"111100": "W",
"111101": "X",
"111110": "Y",
"111111": "Z",
}
def encode(string):
s = ""
for i in string:
s += bin(ord(i))[2:].zfill(8)
pad = ""
if len(s) % 6 == 4:
pad = "="
s += "11"
elif len(s) % 6 == 2:
pad = "=="
s += "1111"
ret = ""
for i in range(0,len(s),6):
ret += b64[s[i:i+6]]
return ret+pad
from secret import FLAG
print(encode(FLAG))
# gObheRHIpN+wlQ7vqQiQb3XzpAbJn4iv6lR=
```
Đoạn script sử dụng một từ điển b64 để ánh xạ các chuỗi nhị phân 6-bit thành ký tự.
Mã hóa mỗi ký tự của chuỗi đầu vào thành chuỗi nhị phân 8-bit, sau đó nhóm lại thành các chuỗi 6-bit và ánh xạ thành ký tự theo từ điển b64.
Nếu chuỗi nhị phân không chia hết cho 6, script thêm các bit đệm và ký tự "=".
Các bước giải mã:
Loại bỏ padding (=).
Chuyển ký tự mã hóa về nhị phân bằng cách sử dụng từ điển đảo b64_reverse.
Loại bỏ các bit đệm thừa dựa vào cách padding ban đầu.
Chuyển nhị phân thành chuỗi ký tự gốc.
```
b64 = {
"000000": "/",
"000001": "+",
"000010": "0",
"000011": "1",
"000100": "2",
"000101": "3",
"000110": "4",
"000111": "5",
"001000": "6",
"001001": "7",
"001010": "8",
"001011": "9",
"001100": "a",
"001101": "b",
"001110": "c",
"001111": "d",
"010000": "e",
"010001": "f",
"010010": "g",
"010011": "h",
"010100": "i",
"010101": "j",
"010110": "k",
"010111": "l",
"011000": "m",
"011001": "n",
"011010": "o",
"011011": "p",
"011100": "q",
"011101": "r",
"011110": "s",
"011111": "t",
"100000": "u",
"100001": "v",
"100010": "w",
"100011": "x",
"100100": "y",
"100101": "z",
"100110": "A",
"100111": "B",
"101000": "C",
"101001": "D",
"101010": "E",
"101011": "F",
"101100": "G",
"101101": "H",
"101110": "I",
"101111": "J",
"110000": "K",
"110001": "L",
"110010": "M",
"110011": "N",
"110100": "O",
"110101": "P",
"110110": "Q",
"110111": "R",
"111000": "S",
"111001": "T",
"111010": "U",
"111011": "V",
"111100": "W",
"111101": "X",
"111110": "Y",
"111111": "Z",
}
b64_reverse = {v: k for k, v in b64.items()}
def decode(encoded):
# Remove padding
encoded = encoded.rstrip('=')
# Convert encoded characters back to binary
binary_string = ""
for char in encoded:
binary_string += b64_reverse[char]
# If padding was applied during encoding, remove extra bits
if len(binary_string) % 8 == 2:
binary_string = binary_string[:-4]
elif len(binary_string) % 8 == 4:
binary_string = binary_string[:-2]
# Convert binary back to original string
decoded_string = ""
for i in range(0, len(binary_string), 8):
decoded_string += chr(int(binary_string[i:i+8], 2))
return decoded_string
# Flag được mã hóa
encoded_flag = "gObheRHIpN+wlQ7vqQiQb3XzpAbJn4iv6lR="
decoded_flag = decode(encoded_flag)
print(decoded_flag)
```
Chạy mã và ta có flag:
> KCSC{no0b_base64_encode!!}
---
Cám ơn vì đã đọc đến tận đây !!!