- Katılım
- 12 Nis 2024
- Mesajlar
- 7
- Tepkime puanı
- 16
- Puanları
- 3
benNeymisimBe
Aşama 1: Dosya İmzası
Bize verilen png dosyasını açıyoruz. Ardından dosyanın bozuk olduğunu ve resmi görüntüleyemediğimizi fark ediyoruz.
Pngcheck aracıyla veya PNG File Chunk Inspector sitesinden dosyanın neden bozuk olduğunu tespit edebiliriz.
Burada dosyanın ilk 4 baytının değiştirildiğini ve 42 değeri verildiğini görüyoruz. Peki bu ne anlama geliyor ve neden resmi görüntüleyemedik?
Dosya imzası, bir dosyanın türünü tanımlamak için kullanılır. Bu imzalara sihirli baytlar veya sihirli sayılar da denilebilir. Dosya imzası bozuk olduğunda bu dosya doğrulanamaz ve okunamaz hale gelir. Bu sihirli sayılar her dosya türü için özeldir.
PNG dosya imzasını araştırdığımızda(Kaynak: File Signatures) ilk 8 baytın dosya imzası olduğunu görüyoruz. Bunun ilk 4 değeriyle oynanmış. Dosyayı herhangi bir hex editörde(Örnek: hexedit) açtığımız zaman ilk 4 baytın 89 50 4e 47 yerine 42 42 42 42 olarak değiştirildiğini görüyoruz. Düzeltme işlemini yaptığımızda resmi görüntüleyebiliyoruz.
Aşama 2: Dosya içeriği
Her dosya esasında baytlardan(8 bitlerden) oluşmakta. Bu baytların da ondalık tabanda belli bir sayıya karşılık geldiğini, ASCII tablosunda da bu sayıların belli karakterlere karşılık gelebildiğini biliyoruz(Örneğin: 97=a). Bir dosyanın stringlerini(dizelerini) incelediğimizde, aslında her baytın karşılık geldiği karakterler bütününe bakıyoruz. Öncelikle dosyanın metadatasına ve stringlerine göz atalım.
Dosyanın metadatasını(üst verisini) incelediğimizde yazar olarak: binsek_mi_otobuse_yoksa
Stringlerini incelediğimizde veya metadatasında yorum olarak: yurusek_mi_sabaha_kadar
Metinlerini buluyoruz. Bu metinler bize bir aracı hatırlatıyor(umarım). İki metnin de ilk kelimelerine bakıyoruz(yok artık) vee... Binwalk kullanıyoruz!
Binwalk, bir dosya içinde farklı bir dosya gizlenmişse veya farklı dosya türü tespit etmişse bunları çıkartmamıza olanak tanıyor. Yani zip arşivini çıkartıyormuşuz gibi düşünebiliriz. Ayrıca dosyanın metadatasını incelerken bir uyarı da dikkatimizi çekiyor. Exiftool, trailer datadan sonra ekstra bir şeylerin olduğunu bize belirtiyor. Yine stringleri incelediğimzde aslında görselin içinde bir zip dosyası olduğunu fark ediyoruz. Ardından Binwalk veya bir arşiv uygulamasıyla(7-zip, WinRAR) görselin içindeki dosyayı çıkartıyoruz.
Aşama 3: En Önemsiz Bitin Önemi
Bu dosya bir metin belgesi ve ismi de bironemiyokyokyokyokyok. İçinde ikili yani a, b şeklinde verilmiş belirli sayılar var. Peki bu sayıların ne önemi var ya da bir önemi var mı?
Steganografide En Önemsiz Bit(Least Significant Bit / LSB) metodu önemli bir yere sahiptir. Çünkü bu metot, dosyanın içeriğiyle ilgili minimum değişikliği yaparak mesaj gizlememize olanak tanır.
Günümüzdeki görsellerin büyük çoğunluğu RGB renk modeliyle renklendirilir. Bu modelde üç farklı kanal vardır. R(Kırmızı), G(Yeşil) ve B(Mavi). Her bir piksel için bu kanallar 0'dan 255'e kadar değer alır ve bu değerlerin birleşimiyle pikselin rengi oluşmuş olur. Bu değer aralıkları geniş olduğundan küçük bir oynama söz konusu olduğunda, örneğin R değeri 255 yerine 254 olduğunda, gözümüz bu renk değişimini ayırt edemeyecektir.
En Önemsiz Bit metodu da bu şekilde mesajı şifreler. Aşama 2'yi hatırlayacak olursak, mesajdaki her bir karakter aslında bir sayıyı, dolayısıyla bir baytı yani 8 biti temsil ediyor.
Şekilde verilen işlem verilen her bir piksel için uygulanmış olmalı. Yapmamız gereken bu piksellerin en önemsiz bitini okumak. Dikkat edersiniz ki her bir karakter 8 bitten oluşuyor ve her piksel için R, G ve B değerleri olmak üzere 3 bit değiştiriliyor. Soruda bize verilen 64 piksel için 192 bit değiştirilmiş olmalı, dolayısıyla da her biri 8 bit olduğuna göre... 192/8... Evet, bize verilen mesaj 24 karakter uzunluğunda olmalı.
Bu hesapları bir kenara bırakırsak, bu piksellerin her biri için en önemsiz biti okuyacağımız ve karakterlere dönüştüreceğimiz örnek kod aşağıdaki gibidir.
Bu da soruyu özetleyen ve tüm aşamaları içeren örnek kod.
flag:
Umarım faydalı olmuştur. Yazarken keyif aldığım ve aynı zamanda öğrendiğim bir soru oldu. Okuduğunuz için teşekkürler ve mutlu seneler!
- Uğurcan Bayraktar aka breakpoint
Aşama 1: Dosya İmzası
Bize verilen png dosyasını açıyoruz. Ardından dosyanın bozuk olduğunu ve resmi görüntüleyemediğimizi fark ediyoruz.
Pngcheck aracıyla veya PNG File Chunk Inspector sitesinden dosyanın neden bozuk olduğunu tespit edebiliriz.
Burada dosyanın ilk 4 baytının değiştirildiğini ve 42 değeri verildiğini görüyoruz. Peki bu ne anlama geliyor ve neden resmi görüntüleyemedik?
Dosya imzası, bir dosyanın türünü tanımlamak için kullanılır. Bu imzalara sihirli baytlar veya sihirli sayılar da denilebilir. Dosya imzası bozuk olduğunda bu dosya doğrulanamaz ve okunamaz hale gelir. Bu sihirli sayılar her dosya türü için özeldir.
PNG dosya imzasını araştırdığımızda(Kaynak: File Signatures) ilk 8 baytın dosya imzası olduğunu görüyoruz. Bunun ilk 4 değeriyle oynanmış. Dosyayı herhangi bir hex editörde(Örnek: hexedit) açtığımız zaman ilk 4 baytın 89 50 4e 47 yerine 42 42 42 42 olarak değiştirildiğini görüyoruz. Düzeltme işlemini yaptığımızda resmi görüntüleyebiliyoruz.
Aşama 2: Dosya içeriği
Her dosya esasında baytlardan(8 bitlerden) oluşmakta. Bu baytların da ondalık tabanda belli bir sayıya karşılık geldiğini, ASCII tablosunda da bu sayıların belli karakterlere karşılık gelebildiğini biliyoruz(Örneğin: 97=a). Bir dosyanın stringlerini(dizelerini) incelediğimizde, aslında her baytın karşılık geldiği karakterler bütününe bakıyoruz. Öncelikle dosyanın metadatasına ve stringlerine göz atalım.
Dosyanın metadatasını(üst verisini) incelediğimizde yazar olarak: binsek_mi_otobuse_yoksa
Stringlerini incelediğimizde veya metadatasında yorum olarak: yurusek_mi_sabaha_kadar
Metinlerini buluyoruz. Bu metinler bize bir aracı hatırlatıyor(umarım). İki metnin de ilk kelimelerine bakıyoruz(yok artık) vee... Binwalk kullanıyoruz!
Binwalk, bir dosya içinde farklı bir dosya gizlenmişse veya farklı dosya türü tespit etmişse bunları çıkartmamıza olanak tanıyor. Yani zip arşivini çıkartıyormuşuz gibi düşünebiliriz. Ayrıca dosyanın metadatasını incelerken bir uyarı da dikkatimizi çekiyor. Exiftool, trailer datadan sonra ekstra bir şeylerin olduğunu bize belirtiyor. Yine stringleri incelediğimzde aslında görselin içinde bir zip dosyası olduğunu fark ediyoruz. Ardından Binwalk veya bir arşiv uygulamasıyla(7-zip, WinRAR) görselin içindeki dosyayı çıkartıyoruz.
Aşama 3: En Önemsiz Bitin Önemi
Bu dosya bir metin belgesi ve ismi de bironemiyokyokyokyokyok. İçinde ikili yani a, b şeklinde verilmiş belirli sayılar var. Peki bu sayıların ne önemi var ya da bir önemi var mı?
Steganografide En Önemsiz Bit(Least Significant Bit / LSB) metodu önemli bir yere sahiptir. Çünkü bu metot, dosyanın içeriğiyle ilgili minimum değişikliği yaparak mesaj gizlememize olanak tanır.
Günümüzdeki görsellerin büyük çoğunluğu RGB renk modeliyle renklendirilir. Bu modelde üç farklı kanal vardır. R(Kırmızı), G(Yeşil) ve B(Mavi). Her bir piksel için bu kanallar 0'dan 255'e kadar değer alır ve bu değerlerin birleşimiyle pikselin rengi oluşmuş olur. Bu değer aralıkları geniş olduğundan küçük bir oynama söz konusu olduğunda, örneğin R değeri 255 yerine 254 olduğunda, gözümüz bu renk değişimini ayırt edemeyecektir.
En Önemsiz Bit metodu da bu şekilde mesajı şifreler. Aşama 2'yi hatırlayacak olursak, mesajdaki her bir karakter aslında bir sayıyı, dolayısıyla bir baytı yani 8 biti temsil ediyor.
Şekilde verilen işlem verilen her bir piksel için uygulanmış olmalı. Yapmamız gereken bu piksellerin en önemsiz bitini okumak. Dikkat edersiniz ki her bir karakter 8 bitten oluşuyor ve her piksel için R, G ve B değerleri olmak üzere 3 bit değiştiriliyor. Soruda bize verilen 64 piksel için 192 bit değiştirilmiş olmalı, dolayısıyla da her biri 8 bit olduğuna göre... 192/8... Evet, bize verilen mesaj 24 karakter uzunluğunda olmalı.
Bu hesapları bir kenara bırakırsak, bu piksellerin her biri için en önemsiz biti okuyacağımız ve karakterlere dönüştüreceğimiz örnek kod aşağıdaki gibidir.
Python:
# RGB kanallarinda islem yapabilmemizi saglayan kutuphane.
from PIL import Image
# bironemiyokyokyokyokyok.txt dosyasina ulasilir.
# dosya iceriginde pikseller verilmistir.
# Sifreli mesaj Least Significant Bit(LSB) metoduyla gizlenmistir. Dosya adi bir ipucudur.
# Gorseli acalim
gorsel = Image.open("temiz.png")
# RGB renk moduna donusturelim.
gorsel = gorsel.convert("RGB")
# pikselleri yukleyelim
tum_pikseller = gorsel.load()
# bironemiyokyokyokyokyok.txt dosyasindaki pikselleri liste halinde import edelim.
ilginc_pikseller = []
with open("bironemiyokyokyokyokyok.txt", 'r') as file:
for line in file:
# Her satir icin sayilari ayirip tuple seklinde yukluyoruz(Pikseller tuple formatinda yazilir.)
x, y = map(int, line.strip().split(','))
ilginc_pikseller.append((x, y))
# Sonrasinda bu pikseller uzerinde LSB metoduyla desifre islemi uygulayalim.
# Elimizdeki her piksel icin RGB degerlerindeki en onemsiz bitleri okuyalim.
mesaj_binary = ""
for (x, y) in ilginc_pikseller:
# Elimizdeki piksellerin RGB degerlerine ulasiyoruz.
r, g, b = tum_pikseller[x, y]
# Her degerin son bitini okuyoruz.
mesaj_binary += mesaj_binary.join(format(r, '08b')[-1:])
mesaj_binary += mesaj_binary.join(format(g, '08b')[-1:])
mesaj_binary += mesaj_binary.join(format(b, '08b')[-1:])
# Olusan dizeyi 8 bit = bayt'lara ayiriyoruz. (1 bayt = 1 harf)
mesaj = ""
# Ondaliga cevirip ASCII tablosunda karsilik gelen karaktere ceviriyoruz.
for i in range(0, len(mesaj_binary), 8):
bayt = mesaj_binary[i:i+8]
harf = chr(int(bayt, 2))
mesaj += harf
flag = "PwnLabMeCTF{" + mesaj + "}"
print(flag)
Bu da soruyu özetleyen ve tüm aşamaları içeren örnek kod.
Python:
# Zip kutuphanesi.
# RGB kanallarinda islem yapabilmemizi saglayan kutuphane.
# pip install pillow
import zipfile
from PIL import Image
# Dosyanin acilamadigi fark edilir. File signature'i bozuk dosyada duzeltme islemi yapilir.
# Bakiniz: (https://en.wikipedia.org/wiki/List_of_file_signatures)
# Ilk 4 Bayt'in bozuk oldugunu fark ettikten sonra asagidaki gibi duzeltebiliriz.
with open("benNeymisimBe.png", "rb") as f:
bozuk_png = f.read()
temiz_png = b"\x89\x50\x4e\x47" + bozuk_png[4:]
with open("temiz.png", "wb") as f:
f.write(temiz_png)
# Ardindan metadata ve stringler incelenir.
# binsek_mi_otobuse_yoksa(bin)
# yurusek_mi_sabaha_kadar(walk)
# Burada gizlenmis zip dosyasi ya 7-zip, winrar gibi uygulamalarla ya da
# binwalk araciyla cikarilir. ("binwalk --extract temiz.png")
with zipfile.ZipFile("temiz.png", 'r') as zip_ref:
zip_ref.extractall("buneyahu/")
# bironemiyokyokyokyokyok.txt dosyasina ulasilir.
# dosya iceriginde pikseller verilmistir.
# Sifreli mesaj Least Significant Bit(LSB) metoduyla gizlenmistir. Dosya adi bir ipucudur.
# Gorseli acalim
gorsel = Image.open("temiz.png")
# RGB renk moduna donusturelim.
gorsel = gorsel.convert("RGB")
# pikselleri yukleyelim
tum_pikseller = gorsel.load()
# bironemiyokyokyokyokyok.txt dosyasindaki pikselleri liste halinde import edelim.
ilginc_pikseller = []
with open("bironemiyokyokyokyokyok.txt", 'r') as file:
for line in file:
# Her satir icin sayilari ayirip tuple seklinde yukluyoruz(Pikseller tuple formatinda yazilir.)
x, y = map(int, line.strip().split(','))
ilginc_pikseller.append((x, y))
# Sonrasinda bu pikseller uzerinde LSB metoduyla desifre islemi uygulayalim.
# Elimizdeki her piksel icin RGB degerlerindeki en onemsiz bitleri okuyalim.
mesaj_binary = ""
for (x, y) in ilginc_pikseller:
# Elimizdeki piksellerin RGB degerlerine ulasiyoruz.
r, g, b = tum_pikseller[x, y]
# Her degerin son bitini okuyoruz.
mesaj_binary += mesaj_binary.join(format(r, '08b')[-1:])
mesaj_binary += mesaj_binary.join(format(g, '08b')[-1:])
mesaj_binary += mesaj_binary.join(format(b, '08b')[-1:])
# Olusan dizeyi 8 bit = bayt'lara ayiriyoruz. (1 bayt = 1 harf)
mesaj = ""
# Ondaliga cevirip ASCII tablosunda karsilik gelen karaktere ceviriyoruz.
for i in range(0, len(mesaj_binary), 8):
bayt = mesaj_binary[i:i+8]
harf = chr(int(bayt, 2))
mesaj += harf
flag = "PwnLabMeCTF{" + mesaj + "}"
print(flag)
flag:
PwnLabMeCTF{b3n1m_1c1n_0n3ml1_0b3d4a}
Umarım faydalı olmuştur. Yazarken keyif aldığım ve aynı zamanda öğrendiğim bir soru oldu. Okuduğunuz için teşekkürler ve mutlu seneler!
- Uğurcan Bayraktar aka breakpoint