Steganografia i jej analiza w Pythonie

Zgłosił się do mnie klient z projektem, którego celem było dojście do tego, czy w danym obrazku nie znajdują się ukryte informacje zakodowane poprzez steganografię.

Steganografia Kodek Online

Poniżej prezentuję skrypt w Pythonie, który wyciąga piksele w trybach horyzontalnych (czyli piksel po pikselu na wysokość obrazka) i wertykalnych z grafiki:

  • najmniej znaczące bity w składowych R
  • najmniej znaczące bity w składowych G
  • najmniej znaczące bity w składowych B
  • najmniej znaczące bity w składowych ALPHA
  • kombinowane najmniej znaczące bity w RGB
  • kombinowane najmniej znaczące bity w BGR
  • kombinowane najmniej znaczące bity w RGBA
  • kombinowane najmniej znaczące bity w ABGR

Są to najczęściej stosowane metody używane przez narzędzia do steganografii do ukrywania rozbitych danych w najmniej znaczących bitach składowych kolorów RGB.

from PIL import Image
from bitarray import bitarray


def dump(filename, content):
    f = open(filename, 'wb')
    f.write(content)
    f.close()


def stego(filename, filename_prefix):
    im = Image.open(filename)
    pixels = im.load()

    width, height = im.size

    #
    # RED, GREEN, BLUE least significant bits
    #
    byte1, byte2, byte3, byte4, bits = 0, 0, 0, 0, 0
    out1, out2, out3, out4 = bytearray(), bytearray(), bytearray(), bytearray()
    bit1, bit2, bit3, bit4 = bitarray(), bitarray(), bitarray(), bitarray()
    all1, all2, all3, all4 = bitarray(), bitarray(), bitarray(), bitarray()

    rgb, rgba = bitarray(), bitarray()

    xx = width
    yy = height
    horizontal = True

    if filename_prefix == "vertical":
        xx = height
        yy = width
        horizontal = False

    for x in range(xx):
        for y in range(yy):

            if horizontal is True:
                pixel = pixels[x, y]
            else:
                pixel = pixels[y, x]

            # separate R G B
            bit1.append(pixel[0] & 1)
            bit2.append(pixel[1] & 1)
            bit3.append(pixel[2] & 1)
            bit4.append(pixel[3] & 1)

            # combined RGB
            all1.append(pixel[0] & 1)
            all2.append(pixel[1] & 1)
            all3.append(pixel[2] & 1)
            all4.append(pixel[3] & 1)

            # RGB
            rgb.append(pixel[0] & 1)
            rgb.append(pixel[1] & 1)
            rgb.append(pixel[2] & 1)

            # RGBA
            rgba.append(pixel[0] & 1)
            rgba.append(pixel[1] & 1)
            rgba.append(pixel[2] & 1)
            rgba.append(pixel[3] & 1)

            # compose 8 bits
            if bits < 8:
                byte1 = (byte1 << 1) | (pixel[0] & 1)
                byte2 = (byte2 << 1) | (pixel[1] & 1)
                byte3 = (byte3 << 1) | (pixel[2] & 1)
                byte4 = (byte4 << 1) | (pixel[3] & 1)
                bits = bits + 1
            else:
                bits = 0
                out1.append(byte1 & 0xFF)
                out2.append(byte2 & 0xFF)
                out3.append(byte3 & 0xFF)
                out4.append(byte4 & 0xFF)

    dump(filename_prefix + "_1_RED.bin", out1)
    dump(filename_prefix + "_1_GREEN.bin", out2)
    dump(filename_prefix + "_1_BLUE.bin", out3)
    dump(filename_prefix + "_1_ALPHA.bin", out4)

    dump(filename_prefix + "_2_RED_BITS.bin", bit1)
    dump(filename_prefix + "_2_GREEN_BITS.bin", bit2)
    dump(filename_prefix + "_2_BLUE_BITS.bin", bit3)
    dump(filename_prefix + "_2_ALPHA_BITS.bin", bit4)

    bit1.reverse()
    bit2.reverse()
    bit3.reverse()
    bit4.reverse()

    dump(filename_prefix + "_3_RED_REV_BITS.bin", bit1)
    dump(filename_prefix + "_3_GREEN_REV_BITS.bin", bit2)
    dump(filename_prefix + "_3_BLUE_REV_BITS.bin", bit3)
    dump(filename_prefix + "_3_ALPHA_REV_BITS.bin", bit4)

    dump(filename_prefix + "_4_RED_BITS_RGB.bin", all1)
    dump(filename_prefix + "_4_GREEN_BITS_RGB.bin", all2)
    dump(filename_prefix + "_4_BLUE_BITS_RGB.bin", all3)
    dump(filename_prefix + "_4_ALPHA_BITS_RGB.bin", all4)

    all1.reverse()
    all2.reverse()
    all3.reverse()
    all4.reverse()

    dump(filename_prefix + "_5_RED_BITS_BGR.bin", all1)
    dump(filename_prefix + "_5_GREEN_BITS_BGR.bin", all2)
    dump(filename_prefix + "_5_BLUE_BITS_BGR.bin", all3)
    dump(filename_prefix + "_5_ALPHA_BITS_BGR.bin", all4)

    dump(filename_prefix + "_6_RGB_ALL_BITS.bin", rgb)
    dump(filename_prefix + "_6_RGBA_ALL_BITS.bin", rgba)

    rgb.reverse()
    rgba.reverse()

    dump(filename_prefix + "_6_RGB_ALL_REV_BITS.bin", rgb)
    dump(filename_prefix + "_6_RGBA_ALL_REV_BITS.bin", rgba)


if __name__ == '__main__':
    stego('IMG1.PNG', 'horizontal')
    stego('IMG1.PNG', 'vertical' )

Może komuś się kiedyś przyda.

Steganografia Ukrywanie Wiadomości w Obrazkach

Steganografia to sztuka i nauka ukrywania informacji poprzez osadzanie ukrytych informacji w innych, pozornie niewinnych plikach, np. w obrazkach.

Z poniższym kodekiem steganograficznym będziesz w stanie ukryć w obrazku dowolną wiadomość tekstową w bezpiecznych sposób oraz przesłać ją bez wzbudzania jakichkolwiek podejrzeń. Odczytanie wiadomości będzie możliwe jedynie po podaniu hasła deszyfrującego.

https://www.pelock.com/pl/produkty/steganografia-kodek-online

Jak to działa?

W tym przypadku poszczególne bity zaszyfrowanej wiadomości ukryte są jako najmniej znaczące bity w składowych kolorach RGB w pikselach wybranego obrazu. Naniesione zmiany nie są widoczne gołym okiem.

Steganografia sztuka ukrywania informacji w obrazkach

W jaki sposób ukrywane są dane w obrazku?

  1. Wiadomość tekstowa jest kompresowana algorytmem DEFLATE w celu zmniejszenia jej rozmiaru
  2. Generowany jest silny kryptograficzny klucz szyfrujący na podstawie podanego hasła, wykorzystując algorytm PBKDF2 z 20000 iteracjami
  3. Skompresowane dane są szyfrowane poprzednio wygenerowanym kluczem w trybie CBC używając 256 bitowego szyfrowania AES
  4. Zaszyfrowane bity danych są zapisywane na pozycjach najmniej znaczących bitów składowych kolorów RGB poszczególnych pikseli wybranego obrazu

Jakie są praktyczne zastosowania steganografii?

Kilka przykładów:

  • Możesz przechowywać ukryte i zaszyfrowane wiadomości i informacje w obrębie obrazów i przesyłać je do dowolnej osoby za pośrednictwem poczty elektronicznej bez wzbudzania żadnych podejrzeń
  • Whistleblowing i tajne dziennikarstwo
  • Wysyłanie tajnych wiadomości w wysoce monitorowanym lub wrogim środowisku (np. monitorowany przez państwo Internet, strefy działań militarnych)
  • Obrazy z ukrytymi wiadomościami można osadzać na stronach internetowych