#!/usr/bin/env python3 """ Правильный флаг спрятан в младшем бите (LSB) альфа-канала пикселей, где (R*G*B) % 7 == 3. Ложный флаг находится в LSB красного канала. Шаги: 1. Открыть изображение в режиме RGBA 2. Обойти пиксели в растровом порядке (слева направо, сверху вниз) 3. Для каждого пикселя проверить условие (R*G*B) % 7 == 3 4. Если условие выполнено — извлечь младший бит альфа-канала 5. Декодировать каждые 8 бит в один ASCII-символ """ import sys, os from PIL import Image def solve(filepath: str) -> str: # Открываем изображение и принудительно переводим в режим RGBA # (чтобы гарантированно получить альфа-канал) img = Image.open(filepath).convert('RGBA') pixels = img.load() # Извлекаем младшие биты альфа-канала из подходящих пикселей bits = [] for y in range(img.height): for x in range(img.width): r, g, b, a = pixels[x, y] # Условие фильтрации: произведение RGB по модулю 7 равно 3 # Это нестандартный критерий, чтобы скрыть данные от обычных стего-сканеров if (r * g * b) % 7 == 3: # Берём только последний (младший) бит альфа-канала bits.append(a & 1) print(f"[*] Найдено {len(bits)} подходящих пикселей (бит)") # Декодируем последовательность бит в строку флага flag = '' for i in range(0, len(bits) - 7, 8): # Собираем байт из 8 последовательных бит (старший бит — первый) byte_val = 0 for j in range(8): byte_val = (byte_val << 1) | bits[i + j] # Нулевой байт означает конец данных (аналог нуль-терминатора в C) if byte_val == 0: break # Принимаем только печатаемые ASCII-символы (коды 32–126) # Всё остальное — признак конца флага или мусорных данных if 32 <= byte_val <= 126: flag += chr(byte_val) else: break return flag if __name__ == '__main__': img_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'public', 'vacation.png') if len(sys.argv) > 1: img_path = sys.argv[1] flag = solve(img_path) print(f"[+] Флаг: {flag}")