---
# System prepended metadata

title: 24520873 - Hà Thụy Ngọc Khuê

---

# Free Flag on Network 
Export Objects -> HTTP -> Save all (save vào 1 folder)
Mở 1 file thì ta thấy có dạng 
![image](https://hackmd.io/_uploads/rJ6f72J6ll.png)
Quăng lên Chat thì ta thấy nó gợi ý là tách 
```
import os
import base64
import re

def extract_and_decode_files():
    flags = []
    
    for i in range(100):
        filename = f"flag{i}.txt"
        if not os.path.exists(filename):
            print(f"File {filename} không tồn tại")
            continue
            
        with open(filename, 'r', encoding='utf-8', errors='ignore') as f:
            content = f.read()
            
        # Tìm tất cả các đoạn base64 trong file
        base64_pattern = r'([A-Za-z0-9+/]{20,}={0,2})'
        base64_matches = re.findall(base64_pattern, content)
        
        for b64_data in base64_matches:
            try:
                # Thử decode base64
                decoded = base64.b64decode(b64_data)
                
                # Thử decode thành string UTF-8
                try:
                    text = decoded.decode('utf-8')
                    if any(keyword in text.lower() for keyword in ['flag', 'ctf', 'wannafreshman', 'freeflag']):
                        flags.append(f"flag{i}: {text}")
                        print(f"Found in flag{i}: {text}")
                except:
                    pass
                    
                # Kiểm tra xem có phải là text có thể đọc được không
                try:
                    text = decoded.decode('latin-1')
                    if re.search(r'flag\{[^}]+\}', text) or any(keyword in text.lower() for keyword in ['flag', 'ctf']):
                        flags.append(f"flag{i}: {text}")
                        print(f"Found in flag{i}: {text}")
                except:
                    pass
                    
            except Exception as e:
                continue
                
        # Nếu không tìm thấy gì trong base64, thử tìm trực tiếp trong file
        if re.search(r'flag\{[^}]+\}', content, re.IGNORECASE):
            match = re.search(r'flag\{[^}]+\}', content, re.IGNORECASE)
            flags.append(f"flag{i}: {match.group()}")
            print(f"Found directly in flag{i}: {match.group()}")
    
    return flags

def extract_specific_base64():
    """Trích xuất và decode đoạn base64 dài nhất từ mỗi file"""
    flags = []
    
    for i in range(100):
        filename = f"flag{i}.txt"
        if not os.path.exists(filename):
            continue
            
        with open(filename, 'r', encoding='utf-8', errors='ignore') as f:
            content = f.read()
        
        # Tìm đoạn base64 dài nhất (có thể là nội dung file)
        base64_pattern = r'([A-Za-z0-9+/]{50,}={0,2})'
        base64_matches = re.findall(base64_pattern, content)
        
        if base64_matches:
            longest_b64 = max(base64_matches, key=len)
            
            try:
                decoded = base64.b64decode(longest_b64)
                
                # Thử nhiều encoding khác nhau
                for encoding in ['utf-8', 'latin-1', 'ascii']:
                    try:
                        text = decoded.decode(encoding)
                        if any(keyword in text.lower() for keyword in ['flag', 'ctf']):
                            flags.append(f"flag{i}: {text}")
                            print(f"Found in flag{i} with {encoding}: {text[:100]}...")
                            break
                    except:
                        continue
                        
                # Nếu không decode được thành text, có thể là binary data
                # Lưu ra file để phân tích
                with open(f"decoded_{i}.bin", 'wb') as f:
                    f.write(decoded)
                    
            except Exception as e:
                print(f"Error decoding flag{i}: {e}")
    
    return flags

if __name__ == "__main__":
    print("Đang tìm flag trong các file...")
    
    # Phương pháp 1: Tìm kiếm tổng quát
    flags1 = extract_and_decode_files()
    
    # Phương pháp 2: Trích xuất base64 cụ thể
    flags2 = extract_specific_base64()
    
    # Kết hợp kết quả
    all_flags = list(set(flags1 + flags2))
    
    print("\n" + "="*50)
    print("KẾT QUẢ TÌM ĐƯỢC:")
    print("="*50)
    
    for flag in all_flags:
        print(flag)
    
    if not all_flags:
        print("Không tìm thấy flag nào. Kiểm tra các file decoded_*.bin để phân tích thêm.")
```
Mở thử 1 file decoded_0.bin bằng HxD thì thấy file bị đảo -> file gốc là PNG vì ở cuối ta thấy GNP, cũng như các chunk của PNG như pHYs, gAMA,... Thêm hint là reverse + có nhiều file nhỏ lẻ nên em nghĩ là sẽ ghép lại các file -> decode ra file png.  
![image](https://hackmd.io/_uploads/Sk69M2kpel.png)
Code đảo ngược mỗi file thành decoded_*_reversed.bin 
```
import os

def batch_reverse_files(start_index=1, end_index=99):
    """
    Tìm và đảo ngược thứ tự các byte của các file theo mẫu 'decoded_N.bin'.
    Tạo ra file mới với tên 'decoded_N_reversed.bin'.
    """
    
    # Lấy thư mục hiện tại nơi script đang chạy
    current_dir = os.getcwd()
    print(f"Bắt đầu đảo ngược file trong thư mục: {current_dir}\n")
    
    files_processed = 0
    
    # Lặp qua các chỉ số từ start_index đến end_index
    for i in range(start_index, end_index + 1):
        input_filename = f'decoded_{i}.bin'
        output_filename = f'decoded_{i}_reversed.bin'
        
        input_path = os.path.join(current_dir, input_filename)
        output_path = os.path.join(current_dir, output_filename)
        
        # Kiểm tra xem file có tồn tại không
        if not os.path.exists(input_path):
            # print(f"Bỏ qua: Không tìm thấy file '{input_filename}'")
            continue
            
        print(f"Xử lý file {i}/{end_index}: '{input_filename}' -> '{output_filename}'")
        
        try:
            # 1. Đọc toàn bộ nội dung file
            with open(input_path, 'rb') as f:
                file_data = f.read()
                
            if not file_data:
                print(f"  [CẢNH BÁO] File '{input_filename}' trống, bỏ qua.")
                continue
                
            # 2. Đảo ngược thứ tự các byte
            reversed_data = file_data[::-1]
            
            # 3. Ghi dữ liệu đã đảo ngược ra file mới
            with open(output_path, 'wb') as f_out:
                f_out.write(reversed_data)
            
            files_processed += 1
            
        except Exception as e:
            print(f"  [LỖI] Xảy ra lỗi với file '{input_filename}': {e}")
            
    # --- Tổng kết ---
    print("\n" + "="*50)
    print(f"QUÁ TRÌNH HOÀN TẤT: Đã đảo ngược {files_processed} file.")
    print(f"Các file mới nằm trong thư mục '{current_dir}'.")
    print("="*50)

# --- Chạy hàm ---
# Lưu ý: Đảm bảo các file 'decoded_N.bin' nằm cùng thư mục với script này
batch_reverse_files(start_index=1, end_index=99)
```
Sau khi đảo lại thì ta kết hợp các file và đổi tên thành .png: 
```
import os

def concatenate_reversed_files(start_index=0, end_index=99, extension='bin'):
    """
    Nối tất cả các file đã đảo ngược theo thứ tự số (từ 0 đến 99) 
    thành một file duy nhất.
    """
    
    # Tên file kết quả
    output_filename = f'combined_final_image.png' # Đặt tên .png ngay để dễ kiểm tra
    
    current_dir = os.getcwd()
    
    print(f"Bắt đầu nối các file {start_index} đến {end_index}...")
    
    total_bytes = 0
    files_found = 0
    
    try:
        # Mở file đầu ra ở chế độ ghi nhị phân (wb)
        with open(os.path.join(current_dir, output_filename), 'wb') as outfile:
            
            # Lặp qua các chỉ số từ start_index (0) đến end_index (99)
            for i in range(start_index, end_index + 1):
                # Tên file cần tìm
                # Sử dụng cả hai khả năng: .bin hoặc .png (nếu bạn đã đổi tên)
                input_filename_bin = f'decoded_{i}_reversed.bin'
                input_filename_png = f'decoded_{i}_reversed.png'
                
                # Ưu tiên tìm file .bin trước, nếu không có thì tìm .png
                if os.path.exists(os.path.join(current_dir, input_filename_bin)):
                    input_path = os.path.join(current_dir, input_filename_bin)
                    name_to_print = input_filename_bin
                elif os.path.exists(os.path.join(current_dir, input_filename_png)):
                    input_path = os.path.join(current_dir, input_filename_png)
                    name_to_print = input_filename_png
                else:
                    # Bỏ qua nếu không tìm thấy file
                    continue
                    
                # 1. Đọc nội dung file
                with open(input_path, 'rb') as infile:
                    file_data = infile.read()
                
                # 2. Ghi nội dung vào file kết quả
                outfile.write(file_data)
                
                files_found += 1
                total_bytes += len(file_data)
                
                print(f"-> Đã nối file {i}: {name_to_print} ({len(file_data)} bytes)")
                
    except Exception as e:
        print(f"\n[LỖI] Xảy ra lỗi trong quá trình nối file: {e}")
        return

    # --- Tổng kết ---
    print("\n" + "="*50)
    print(f"QUÁ TRÌNH HOÀN TẤT: Đã nối {files_found} file.")
    print(f"Tổng kích thước: {total_bytes / 1024:.2f} KB")
    print(f"File kết quả: {output_filename}")
    print("="*50)

# --- Chạy hàm ---
# Chạy script để nối các file đã đảo ngược từ 0 đến 99
concatenate_reversed_files()
```
Flag: 
![image](https://hackmd.io/_uploads/S1xgN3y6gl.png)

# What is it?
Mở file .wav nghe lên tiếng beep nên em đoán là mã morse, search tool  [Morse Decoder](https://morsecode.world/international/decoder/audio-decoder-adaptive.html)
![image](https://hackmd.io/_uploads/HyAOE3yael.png)
Tới khúc này lúc đó em tưởng pw là GOODLUCK nhưng thử miết không ra :v hóa ra là `passwordisgoodluck`
File .wav, có password nên em liên tưởng tới `steghide extract -sf chall.wav`
![image](https://hackmd.io/_uploads/Sy6fH3yaex.png)
` unzip hidden.zip` 
![image](https://hackmd.io/_uploads/BJH4rnypgg.png)
Em gửi lên chatgpt nhờ ẻm sửa hộ header và EOCD 
```
dd if=next2.zip of=swapped.zip conv=swab
```
Unzip file swapped.zip và mở file lên đọc, ta có phần còn lại của flag
![image](https://hackmd.io/_uploads/Bk5pw2k6xg.png)
