NahamCon 2022, Ostrich
-
Steganography
- diberikan 3 file
-
ostrich.jpg
result.apng
ostrich.py
ostrich.py
import imageio
from PIL import Image, GifImagePlugin
from Crypto.Util.number import long_to_bytes as l2b, bytes_to_long as b2l
import random
from apng import APNG
filenames = []
flag = "REDACTED"
orig_filename = "ostrich.jpg"
orig_image = Image.open(orig_filename)
pixels = orig_image.load()
width, height = orig_image.size
images = []
for i in range(len(flag)):
new_filename = f'./images/ostrich{i}.png'
new_image = Image.new(orig_image.mode, orig_image.size)
new_pixels = new_image.load()
for x in range(width):
for y in range(height):
new_pixels[x,y] = orig_image.getpixel((x, y))
x = random.randrange(0,width)
y = random.randrange(0,height)
pixel = list(orig_image.getpixel((x, y)))
while(pixel[2] == 0):
x = random.randrange(0,width)
y = random.randrange(0,height)
pixel = list(orig_image.getpixel((random.randrange(0,width), random.randrange(0,height))))
new_val = l2b(pixel[2]*ord(flag[i]))
pixel[0] = new_val[0]
if len(new_val) > 1:
pixel[1] = new_val[1]
pixel[2] = 0
new_pixels[x, y] = (pixel[0], pixel[1], pixel[2])
new_image.save(new_filename)
filenames.append(new_filename)
images.append(new_image)
APNG.from_files(filenames, delay=0).save("result.apng")
APNG / Animated-PNG, dalam konteks soal APNG merupakan gabungan dari beberapa gambar dengan beberapa nilai piksel yang berbeda sehingga membentuk gambar beranimasi
Note
gambar asli = ostrich.jpg
gambar baru / gambar gabung = ostrich.jpg dengan mengubah salah satu pixel
Ide Enkoding
aturan pengubahan nilai pixel
pixel_lama = rgb(a,b,c)
*memilih pixel yang nilai c != 0
new_val = l2b(c*flag[i])
x = new_val[0]
if len(new_val) > 1:
y = new_val[1]
else:
y = b
z = 0
pixel_baru = rgb(x,y,z)
maka perlu diekstrak terlebih dahulu file result.apng
from apng import APNG
im = APNG.open("result.apng")
for i, (png, control) in enumerate(im.frames):
png.save("hasil/ostrich{i}.png".format(i=i))
dengan membandingkan setiap hasil gambar ekstrak dengan gambar asli, dapat diperoleh titik pixel yang berbeda
get_flag.py
from apng import APNG
from PIL import Image
gambar_asli = Image.open('ostrich.jpg')
for k in range(38):
gambar0 = Image.open('hasil/ostrich'+str(k)+'.png')
data_asli = gambar_asli.load()
data_0 = gambar0.load()
width, height = gambar_asli.size
for i in range(width):
for j in range(height):
if data_0[i,j] != data_asli[i,j]:
if data_0[i,j][0] / data_asli[i,j][2] > 1:
fl = data_0[i,j][0] / data_asli[i,j][2]
else: # kebetulan semua nilai pixel gambar masuk ke else
p1 = hex(data_0[i,j][1])[2:]
if len(p1) == 1:
p1 = '0'+p1
fl = int(hex(data_0[i,j][0])+p1,16) / data_asli[i,j][2]
print(chr(int(fl)),end='')