Introduction to Image Steganography with Python: Embedding and Extracting Files

D2

Администратор
Регистрация
19 Фев 2025
Сообщения
4,380
Реакции
0
Steganography is the art of concealing information within another medium, such as images, to ensure covert communication. This Python script leverages the power of PIL (Python Imaging Library) to embed files into images and extract them seamlessly, offering a practical introduction for beginners. i hope you make good use of this script and change it to your liking and share it ))))


Abstract:

This article explores an advanced method for data hiding within images, where sensitive information can be covertly embedded in the least significant bits of images. The process of embedding and extracting data utilizes encryption techniques and MIME analysis. This approach not only aids in preserving user privacy but also serves as a powerful tool for invisible communications and transferring sensitive information away from prying eyes.

so let's go :

1. split_into_chunks(file_path, chunk_size)​

Let's start with the basics. This function is the key to breaking down a large file into bite-sized chunks. After all, if you want to hide something, you've got to cut it into smaller pieces, right?
Python: Скопировать в буфер обмена
Код:
def split_into_chunks(file_path, chunk_size):
    chunks = []
    with open(file_path, 'rb') as file:
        while True:
            chunk = file.read(chunk_size)
            if not chunk:
                break
            chunks.append(bytearray(chunk))
    return chunks

2. embed_chunks_into_image(chunks, image_path)​

Now that we've sliced the data into smaller chunks, it's time to conceal them within an image. This means stuffing the data into the least significant bits of the image's pixels. Ever wondered how big the image needs to be to fit all that data?
Python: Скопировать в буфер обмена
Код:
def embed_chunks_into_image(chunks, image_path):
    try:
        img = Image.open(image_path)
        width, height = img.size
        total_pixels = width * height

        flat_chunks = [bit for chunk in chunks for byte in chunk for bit in format(byte, '08b')]

        if len(flat_chunks) > total_pixels * 3:
            print(f"The image isn't big enough to embed the file. Image size: {total_pixels} pixels, needed: {len(flat_chunks) // 3} pixels.")
            resize_confirmation = input("Do you want to resize the image to fit the data? (yes/no): ").strip().lower()
            if resize_confirmation == 'yes':
                required_size = ((len(flat_chunks) // 3) ** 0.5)
                new_size = (int(required_size) + 1, int(required_size) + 1)
                img = img.resize(new_size)
                width, height = img.size
                print(f"Image resized to: {new_size} to fit the data.")
            else:
                print("Embedding canceled.")
                return

        output_image_path = input("Enter the filename to save the embedded image (including extension): ").strip()

        index = 0
        for x in range(width):
            for y in range(height):
                if index < len(flat_chunks):
                    r, g, b = img.getpixel((x, y))
                    r = (r & ~1) | int(flat_chunks[index])
                    index += 1
                    if index < len(flat_chunks):
                        g = (g & ~1) | int(flat_chunks[index])
                        index += 1
                    if index < len(flat_chunks):
                        b = (b & ~1) | int(flat_chunks[index])
                        index += 1
                    img.putpixel((x, y), (r, g, b))

        img.save(output_image_path)
        print(f"File embedded into '{output_image_path}' successfully.")

    except Exception as e:
        print(f"Error occurred during embedding: {str(e)}")

3. extract_chunks_from_image(image_path, output_dir, chunk_size)​

Imagine you're hunting for something hidden in an image. This function's job is to uncover those hidden bits and reconstruct the original file. That means everything that's been hidden can be yours to retrieve.
Python: Скопировать в буфер обмена
Код:
def extract_chunks_from_image(image_path, output_dir, chunk_size):
    try:
        img = Image.open(image_path)
        width, height = img.size

        bits = []
        for x in range(width):
            for y in range(height):
                r, g, b = img.getpixel((x, y))
                bits.append(r & 1)
                bits.append(g & 1)
                bits.append(b & 1)

        bytes_array = bytearray()
        for i in range(0, len(bits), 8):
            byte = 0
            for bit in bits[i:i+8]:
                byte = (byte << 1) | bit
            bytes_array.append(byte)

        
        mime = magic.Magic(mime=True)
        mime_type = mime.from_buffer(bytes(bytes_array[:1024]))  # Check the first 1024 bytes

        
        mime_extensions = {
            'application/x-dosexec': '.exe',
            'image/jpeg': '.jpg',
            'image/png': '.png',
            'application/pdf': '.pdf',
            'text/plain': '.txt',
            'application/msword': '.doc',
            'application/vnd.ms-excel': '.xls',
            'application/vnd.openxmlformats-officedocument.wordprocessingml.document': '.docx',
            'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': '.xlsx',
            'application/zip': '.zip'
           
        }

        
        default_extension = '.bin'

        
        extension = mime_extensions.get(mime_type, default_extension)

        output_file_path = input("Enter the filename to save the extracted file (including extension): ").strip()
        output_file_path = os.path.join(output_dir, output_file_path)

        if not os.path.exists(output_dir):
            create_dir = input(f"The directory '{output_dir}' does not exist. Do you want to create it? (yes/no): ").strip().lower()
            if create_dir == 'yes':
                os.makedirs(output_dir)
            else:
                print("Extraction canceled.")
                return

        with open(output_file_path, 'wb') as file:
            file.write(bytes_array)

        print(f"File extracted successfully to '{output_file_path}'.")

    except Exception as e:
        print(f"Error occurred during extraction: {str(e)}")

4. auto_determine_chunk_size(file_path)​

If you're new to this game, you'll want to know how big to cut the chunks for processing. This function makes sure the file data is processed in the best way possible.
Python: Скопировать в буфер обмена
Код:
def auto_determine_chunk_size(file_path):
    file_size = os.path.getsize(file_path)
    chunk_size = min(file_size, 1024)
    return chunk_size

These functions together form a toolkit for manipulating and hiding data within images, all while maintaining a low profile. Perfect for those who want to keep things off the radar, don't you think? ;)
Stego(Xss).png


For Example


Now, I wrote another script here, with which we can extract the data in the image through this Python script (note: these are only for teaching beginners and novices)

extracting Hidden Data from Images Using Python A Beginner's Guide
Python: Скопировать в буфер обмена
Код:
from PIL import Image
import os
import magic
import random
import string
import zipfile

def extract_chunks_from_image(image_path, output_dir):
    try:
        img = Image.open(image_path)
        width, height = img.size

        bits = []
        for x in range(width):
            for y in range(height):
                r, g, b = img.getpixel((x, y))
                bits.append(r & 1)
                bits.append(g & 1)
                bits.append(b & 1)

        bytes_array = bytearray()
        for i in range(0, len(bits), 8):
            byte = 0
            for bit in bits[i:i+8]:
                byte = (byte << 1) | bit
            bytes_array.append(byte)

      
        mime = magic.Magic(mime=True)
        mime_type = mime.from_buffer(bytes(bytes_array[:1024]))  # Check the first 1024 bytes

      
        mime_extensions = {
            'application/x-dosexec': '.exe',
            'image/jpeg': '.jpg',
            'image/png': '.png',
            'application/pdf': '.pdf',
            'text/plain': '.txt',
            'application/zip': '.zip'
           
        }

       
        default_extension = '.bin'

       
        extension = mime_extensions.get(mime_type, default_extension)

        if extension == '.bin':
            print("No embedded data found in the image.")
            return

        output_file_path = os.path.join(output_dir, f"extracted_file{extension}")

        if not os.path.exists(output_dir):
            os.makedirs(output_dir)

        if extension == '.zip':
            # Extract ZIP file
            with open(output_file_path, 'wb') as file:
                file.write(bytes_array)
            print(f"ZIP file extracted successfully to '{output_file_path}'.")
        elif extension == '.txt':
           
            with open(output_file_path, 'wb') as file:
                file.write(bytes_array)
            print(f"TXT file extracted successfully to '{output_file_path}'.")
        else:
            # Extract other types (image, PDF, etc.)
            with open(output_file_path, 'wb') as file:
                file.write(bytes_array)
            print(f"File extracted successfully to '{output_file_path}'.")

    except Exception as e:
        print(f"Error occurred during extraction: {str(e)}")

def main():
    operation = input("Enter 'open' to open an image file and check for embedded data: ").strip()

    if operation == 'open':
        image_path = input("Enter the path to the image file you want to open: ").strip()

        extract_chunks_from_image(image_path, os.getcwd())

    else:
        print("Invalid operation. Please enter 'open'.")

if __name__ == "__main__":
    main()
1. Opening Image and Pixel Analysis:

  • Using Image.open(image_path), the function accesses and analyzes pixels of the specified image (image_path).
  • It iterates through each pixel (x and y coordinates), extracting the least significant bits (LSBs) from the RGB channels (r, g, b). These LSBs potentially contain hidden data embedded within the image.
2. Reconstructing Binary Data:

  • bits accumulates the LSBs extracted from the image pixels.
  • bytes_array compiles these LSBs into binary chunks, reconstructing them into bytes using bitwise operations (<< and |).
3. Determining File Extension:

  • Utilizes the magic library to determine the MIME type of the reconstructed data from the first 1024 bytes (mime.from_buffer()).
  • Maps MIME types (mime_extensions) to corresponding file extensions to identify the type of file embedded in the image.
  • Sets a default extension (.bin) for unrecognized MIME types.
4. Saving Extracted Data:

  • Constructs output_file_path to save the extracted file with the determined extension in the specified output_dir.
  • Creates the output directory (output_dir) if it doesn't exist using os.makedirs().
  • Depending on the identified extension:
    • Writes the bytes_array to a ZIP file if the extension is .zip.
    • Writes to a text file if the extension is .txt.
    • Directly saves for other recognized file types (e.g., image, PDF) by writing bytes_array to the file.
5. Error Handling:
  • Catches exceptions during the extraction process and prints an error message ("Error occurred during extraction: {error_message}").

Auhtor : blackhunt
Special for XSS.is

~Enjoy !
 
Сверху Снизу