Oyun Bitti: FlareOn 2015 CTF> Mücadelesi 5
Herkese selam! Geçenlerde bu yýlki FireEye FLARE On CTF'ye katýlarak uykusuz geceler geçirdim.
Ne yazýk ki boþ zaman eksikliði, uykusuzluk ve 0xc0ff33 eksikliði nedeniyle Challenge 9'u bombaladým.
Tüm þakalar bir yana, harika bir yolculuktu ve bir sürü yeni þey öðrendim.
Bunu bir araya getirdikleri için tüm FLARE ekibine çok teþekkürler!
Bu gönderi, Challenge 5'in bir yazýmýdýr. Bu zorluðu birkaç nedenden ötürü seçtim:
(1) çok karmaþýk deðil,
(2) kötü amaçlý yazýlým benzeri bir bileþeni var
(3) oldukça zevkliydi !
Tamam, kemerlerinizi baðlayýn ve baþlayalým!
Mmm Büyüleyici Gerçekten ..
Bu yüzden, meydan okumanýn nereye gittiðine dair bazý göstergeler veren aþaðýdaki postayý alýyoruz.

JavaScript gizlenmesinin söz konusu olacaðýný umuyordum ama durum böyle deðildi.
Ekli arþiv iki dosya içeriyordu: "challenge.pcap " ve "Sender(gönderen)"olarak adlandýrýlan bir 32bit PE.
challenge.pcap
Önce trafik yakalamasýna bir göz atalým ve ihtiyacýmýz olan her þeyi sökelim, böylece pcap'yi bir kenara koyabiliriz.
Daha yakýn bir inceleme, pcap'nin 12 HTTP POST isteði içerdiðini gösterir.

Hepsi ayný boyuta sahip ve oldukça küçük görünüyorlar, bu da cesaret verici. Aþaðýdaki resim, son post isteðini ve yanýtýný göstermektedir.

Her isteðin biçimi aynýdýr, ikili, "1"göndererek yanýt veren dinleyiciye 4 karakter gönderir.
Son isteði göstermemin nedeni, 4 karakterin iki eþit iþaret içerdiðini görebilmemizdir. Hemen, base64 çýðlýk atýyor.
Ek olarak, eþit iþaretler son istekte olduðundan, bu bize ikili verinin doðru sýrayla gönderildiðini gösteren oldukça iyi bir gösterge verir.
Ýletilen tüm karakterleri ayýklamak bize aþaðýdaki base64 dizesini verir.
Kod:
UDYs1D7bNmdE1o3g5ms1V6RrYCVvODJF1DpxKTxAJ9xuZW==
Tabii ki, bu gerçekten mantýklý bir þey için deþifre deðil, çok sýkýcý olurdu!

Neden bu kadar baþarýsýz oldun?
IDA'daki iþlenenlere hýzlý bir bakýþ, baþarýsýz koþullara iþaret eden bazý dizeleri gösterir.

Bu dizelere bakarak ve pcap'de gördüklerimizi kullanarak, ikili dosyanýn düzgün çalýþmasý için neye ihtiyacý olduðunu kolayca anlayabiliriz.
En azýndan bir anahtar gerektirir.txt var (muhtemelen içeriði bir arabelleðe okuyor) ve HTTP POST isteklerini almak için localhost üzerinde bir dinleyici.
Pcap'den, sunucunun aldýðý her þey için "1" döndürmesi gerektiðini biliyoruz.
Ayrýca garip dize "flarebearstare" (0x66 = f) dikkat edin, daha sonra buna geri döneceðiz.

Basit bir python dinleyicisini hýzlý bir þekilde bir araya getirebiliriz, bu da hata ayýklama sýrasýnda yararlý olacaktýr, çünkü baþarýsýz koþullarla uðraþmaya devam etmek istemiyoruz.
Kod:
#!/usr/bin/python
import SocketServer
class EchoRequestHandler(SocketServer.BaseRequestHandler ):
def handle(self):
while 1:
data = self.request.recv(1024)
print data + "\n"
self.request.send("1")
return
SocketServer.TCPServer.allow_reuse_address = 1
server = SocketServer.ThreadingTCPServer(("0.0.0.0", 80), EchoRequestHandler)
server.serve_forever()
Anahtar oluþturduktan sonra.txt bazý örnek metin "AAAABBBB" ile aþaðýdaki yanýtý alýyoruz.

Bingo, þimdi ikili tarafýndan iþlendiðinde giriþ arabelleðine ne olduðunu anlayýp anlayamayacaðýmýzý görelim.
Girdiyi Deðiþtirme
Ýkili, key.txt'deki metni okuduktan hemen sonra, aþaðýdaki montaj talimat bloklarýna ulaþýr.

Buradaki önemli parçalar, bir kesme noktasý belirlediðim iki iþlev çaðrýsýdýr (bilginize, bu iþlevleri yeniden adlandýrdým).
Bu iki iþlev, programa aktardýðýmýz girdiyi deðiþtirmekten sorumludur. Her ikisini de sýrayla inceleyeceðiz.
Shift_ASCII_Input
Bu özellik oldukça küçüktür, aþaðýda tamamen görebilirsiniz.

Yukarýdaki resimde, en alakalý kýsýmda yürütmeyi duraklattým.
EBX, test arabelleðimize ("AAAABBBB") iþaret ediyor ve 0x41 (A) arabelleðimizin ilk baytý 0x66 (f) ile artýrýlýyor gibi görünüyor.
Daha önce bulduðumuz garip iþleneni hatýrlýyor musun?
Bazý hýzlý araþtýrmalar aþaðýdakileri göstermektedir:
EBX: tamponumuzun baþlangýcýna iþaret ediyor. Biz de yýðýnda görebilirsiniz.
ESI: bir sayaç, döngü her çalýþtýðýnda artar ve giriþ arabelleðimiz için bir dizin olarak kullanýlýr.
EDI: tamponumuzun uzunluðunu içerir, döngüden ne zaman çýkýlacaðýný belirlemek için ESI ile karþýlaþtýrýlýr.
AL: "flarebearstare" dizesinden tek bir bayt içerir, döngünün her yinelemesi bu deðerdir
saða kaymýþ.
Esasen, olan þey, giriþ arabelleðimizin her karakterinin "flarebearstare"dizesinden bir karakter tarafýndan artýrýlmasýdýr.
Bu, ikili dosyaya verdiðimiz herhangi bir giriþi etkili bir þekilde karýþtýrýr.
Anahtarýn uzunluðunun 14 karakter olduðuna dikkat edin, eðer anahtardan daha uzun olan program giriþini saðlarsak, basit bir döngü yapar ve ilk karakterden tekrar baþlar.
Aþaðýdaki örnek, giriþ arabelleðimizi kullanarak gösterilecek, umarým bunu göstermelidir:
Kod:
Input : 0x41(A) 0x41(A) 0x41(A) 0x41(A) 0x42(B) 0x42(B) 0x42(B) 0x42(B) # Sample input "AAAABBBB"
Key : 0x66(f) 0x6c(l) 0x61(a) 0x72(r) 0x65(e) 0x62(b) 0x65(e) 0x61(a) + # Key "flarebea"
---------------------------------------------------------------
Scrambled: 0xA7(?) 0xAD(?) 0xA2(?) 0xB3(?) 0xA7(?) 0xA4(?) 0xA7(?) 0xA3(?) # Output
Döngüden geçerken EBX kaydýný takip ederek bunu kolayca doðrulayabiliriz.
Giriþ tamponumuz bundan deðiþir:

Bu:

Ýlk bölüm için bu kadar, base64'e geçelim.
Base64_Encode
Giriþimizi "muhtemelen" deðiþtiren ikinci iþlev, baytlarý doðrudan base64'e dönüþtürür.
Genel olarak, her üç baytýn (her türlü bayt) 4 ASCII yazdýrýlabilir bayta dönüþtürülmesidir.
Giriþ baytlarý üçe bölünemez olduðunda, dolgu uygulanýr.
Dönüþtürme iþlemi, her üç baytý ikili olarak çevirerek, elde edilen bitleri 6 bitlik gruplara gruplayarak ve daha sonra bu baytlarýn ondalýk gösterimini kullanarak base64 tablosunda karþýlýk gelen karakteri arayarak gerçekleþir.
Standart base64 arama tablosu aþaðýda görülebilir.

Biliyorum biliyorum, sadece bunu uydurmuþ gibi geliyor ama base64 gerçekten böyle çalýþýyor.
Deðiþtirilmiþ giriþ arabelleðimizin ilk üç baytý için bunu deneyelim:
Kod:
Input : A7 AD A2
8-bit binary : 10100111 10101101 10100010
6-bit split : 101001 111010 110110 100010
Decimal : 41 58 54 34
base64 Lookup: p 6 2 i ----> p62i
Base64 iþlevi, iþleri basitleþtirmek için biraz uzundur, aþaðýdaki resim dönüþtürme iþleminin son adýmýnda kesme noktalarýný gösterir (ondalýk - > base64 arama tablosu).
Doðal olarak, 4 kesme noktasý vardýr; her arama için bir tane.

Ne olmasý gerektiðini zaten biliyoruz, ancak ikili dosyanýn ne yaptýðýný görelim.
Ýlk karakter:

Ýkinci karakter:

Üçüncü karakter:

Dördüncü karakter:

Açýkçasý burada uðursuz bir þey oluyor, base64 iyi görünüyor ama ... durum ters çevrilmiþtir ("p62i "vs"P62Ý").
Base64 arama tablosunu hatýrlayýn, ikili de bir tane vardýr, sadece büyük ve küçük harf karakterlerinin sýrasý ters çevrilir.
Base64 iþlevinin yürütülmesi sýrasýnda arama tablosu yýðýnda görülebilir.

Gizem çözüldü, bu sorunu çözmek için ihtiyacýmýz olan tüm bilgilere sahibiz.
Ýkili dosyanýn geri kalaný, base64'ü parçalara ayýrýr ve dinleyiciye gönderir.
Çözüm
Açýkçasý, bu zorluðu biraz ayrýntýlý olarak açýkladým, ama gerçek þu ki, ilk çözdüðümde her þey biraz daha kaotik oldu.
Böyle... Base64'ü orijinal girdiye dönüþtüren güzel bir python betiði yazabilirim, ancak bitiþ çizgisine acele etmeye çalýþýrken tembel bir kiþinin (yani: ben) ne yapabileceðini göstereceðim.
Ýlk olarak, deðiþtirilmiþ arama tablosunu göz önünde bulundurarak base64'ü doðru baytlara geri dönüþtürelim:

Ýkili, çok fazla çaba harcamadan bizim için zor iþin geri kalanýný yapmasýna izin verebiliriz.
Unutmayýn, ilk ASCII baytlarý aþaðýdaki komut add [ESI+EBX], al kullanýlarak kodlanýr.
Eðer ikili kodu çözdüðümüz baytlarla tedarik edersek ve bu talimatý sub [ESI+EBX] ' e eklersek, o zaman sadece çözümü tükürmelidir(göstermelidir)!
Önce ikili dosyayý yeniden baþlatýyoruz ve yukarýda belirtilen talimata ulaþana kadar yürütmeye devam ediyoruz:

Sonra bellekte base64 gelen çözdük byte ile byte yerine talimat tamir edersek.

Geriye kalan tek þey döngüyü çalýþtýrmak ve çözümün bellekte çözülmesini izlemek!

OYUN BÝTTÝ!
Translator: @Qgenays
Source: https://www.fuzzysecurity.com/tutorials/23.html
Herkese selam! Geçenlerde bu yýlki FireEye FLARE On CTF'ye katýlarak uykusuz geceler geçirdim.
Ne yazýk ki boþ zaman eksikliði, uykusuzluk ve 0xc0ff33 eksikliði nedeniyle Challenge 9'u bombaladým.
Tüm þakalar bir yana, harika bir yolculuktu ve bir sürü yeni þey öðrendim.
Bunu bir araya getirdikleri için tüm FLARE ekibine çok teþekkürler!
Bu gönderi, Challenge 5'in bir yazýmýdýr. Bu zorluðu birkaç nedenden ötürü seçtim:
(1) çok karmaþýk deðil,
(2) kötü amaçlý yazýlým benzeri bir bileþeni var
(3) oldukça zevkliydi !
Tamam, kemerlerinizi baðlayýn ve baþlayalým!
Mmm Büyüleyici Gerçekten ..
Bu yüzden, meydan okumanýn nereye gittiðine dair bazý göstergeler veren aþaðýdaki postayý alýyoruz.

JavaScript gizlenmesinin söz konusu olacaðýný umuyordum ama durum böyle deðildi.
Ekli arþiv iki dosya içeriyordu: "challenge.pcap " ve "Sender(gönderen)"olarak adlandýrýlan bir 32bit PE.
challenge.pcap
Önce trafik yakalamasýna bir göz atalým ve ihtiyacýmýz olan her þeyi sökelim, böylece pcap'yi bir kenara koyabiliriz.
Daha yakýn bir inceleme, pcap'nin 12 HTTP POST isteði içerdiðini gösterir.

Hepsi ayný boyuta sahip ve oldukça küçük görünüyorlar, bu da cesaret verici. Aþaðýdaki resim, son post isteðini ve yanýtýný göstermektedir.

Her isteðin biçimi aynýdýr, ikili, "1"göndererek yanýt veren dinleyiciye 4 karakter gönderir.
Son isteði göstermemin nedeni, 4 karakterin iki eþit iþaret içerdiðini görebilmemizdir. Hemen, base64 çýðlýk atýyor.
Ek olarak, eþit iþaretler son istekte olduðundan, bu bize ikili verinin doðru sýrayla gönderildiðini gösteren oldukça iyi bir gösterge verir.
Ýletilen tüm karakterleri ayýklamak bize aþaðýdaki base64 dizesini verir.
Kod:
UDYs1D7bNmdE1o3g5ms1V6RrYCVvODJF1DpxKTxAJ9xuZW==
Tabii ki, bu gerçekten mantýklý bir þey için deþifre deðil, çok sýkýcý olurdu!

Neden bu kadar baþarýsýz oldun?
IDA'daki iþlenenlere hýzlý bir bakýþ, baþarýsýz koþullara iþaret eden bazý dizeleri gösterir.

Bu dizelere bakarak ve pcap'de gördüklerimizi kullanarak, ikili dosyanýn düzgün çalýþmasý için neye ihtiyacý olduðunu kolayca anlayabiliriz.
En azýndan bir anahtar gerektirir.txt var (muhtemelen içeriði bir arabelleðe okuyor) ve HTTP POST isteklerini almak için localhost üzerinde bir dinleyici.
Pcap'den, sunucunun aldýðý her þey için "1" döndürmesi gerektiðini biliyoruz.
Ayrýca garip dize "flarebearstare" (0x66 = f) dikkat edin, daha sonra buna geri döneceðiz.

Basit bir python dinleyicisini hýzlý bir þekilde bir araya getirebiliriz, bu da hata ayýklama sýrasýnda yararlý olacaktýr, çünkü baþarýsýz koþullarla uðraþmaya devam etmek istemiyoruz.
Kod:
#!/usr/bin/python
import SocketServer
class EchoRequestHandler(SocketServer.BaseRequestHandler ):
def handle(self):
while 1:
data = self.request.recv(1024)
print data + "\n"
self.request.send("1")
return
SocketServer.TCPServer.allow_reuse_address = 1
server = SocketServer.ThreadingTCPServer(("0.0.0.0", 80), EchoRequestHandler)
server.serve_forever()
Anahtar oluþturduktan sonra.txt bazý örnek metin "AAAABBBB" ile aþaðýdaki yanýtý alýyoruz.

Bingo, þimdi ikili tarafýndan iþlendiðinde giriþ arabelleðine ne olduðunu anlayýp anlayamayacaðýmýzý görelim.
Girdiyi Deðiþtirme
Ýkili, key.txt'deki metni okuduktan hemen sonra, aþaðýdaki montaj talimat bloklarýna ulaþýr.

Buradaki önemli parçalar, bir kesme noktasý belirlediðim iki iþlev çaðrýsýdýr (bilginize, bu iþlevleri yeniden adlandýrdým).
Bu iki iþlev, programa aktardýðýmýz girdiyi deðiþtirmekten sorumludur. Her ikisini de sýrayla inceleyeceðiz.
Shift_ASCII_Input
Bu özellik oldukça küçüktür, aþaðýda tamamen görebilirsiniz.

Yukarýdaki resimde, en alakalý kýsýmda yürütmeyi duraklattým.
EBX, test arabelleðimize ("AAAABBBB") iþaret ediyor ve 0x41 (A) arabelleðimizin ilk baytý 0x66 (f) ile artýrýlýyor gibi görünüyor.
Daha önce bulduðumuz garip iþleneni hatýrlýyor musun?
Bazý hýzlý araþtýrmalar aþaðýdakileri göstermektedir:
EBX: tamponumuzun baþlangýcýna iþaret ediyor. Biz de yýðýnda görebilirsiniz.
ESI: bir sayaç, döngü her çalýþtýðýnda artar ve giriþ arabelleðimiz için bir dizin olarak kullanýlýr.
EDI: tamponumuzun uzunluðunu içerir, döngüden ne zaman çýkýlacaðýný belirlemek için ESI ile karþýlaþtýrýlýr.
AL: "flarebearstare" dizesinden tek bir bayt içerir, döngünün her yinelemesi bu deðerdir
saða kaymýþ.
Esasen, olan þey, giriþ arabelleðimizin her karakterinin "flarebearstare"dizesinden bir karakter tarafýndan artýrýlmasýdýr.
Bu, ikili dosyaya verdiðimiz herhangi bir giriþi etkili bir þekilde karýþtýrýr.
Anahtarýn uzunluðunun 14 karakter olduðuna dikkat edin, eðer anahtardan daha uzun olan program giriþini saðlarsak, basit bir döngü yapar ve ilk karakterden tekrar baþlar.
Aþaðýdaki örnek, giriþ arabelleðimizi kullanarak gösterilecek, umarým bunu göstermelidir:
Kod:
Input : 0x41(A) 0x41(A) 0x41(A) 0x41(A) 0x42(B) 0x42(B) 0x42(B) 0x42(B) # Sample input "AAAABBBB"
Key : 0x66(f) 0x6c(l) 0x61(a) 0x72(r) 0x65(e) 0x62(b) 0x65(e) 0x61(a) + # Key "flarebea"
---------------------------------------------------------------
Scrambled: 0xA7(?) 0xAD(?) 0xA2(?) 0xB3(?) 0xA7(?) 0xA4(?) 0xA7(?) 0xA3(?) # Output
Döngüden geçerken EBX kaydýný takip ederek bunu kolayca doðrulayabiliriz.
Giriþ tamponumuz bundan deðiþir:

Bu:

Ýlk bölüm için bu kadar, base64'e geçelim.
Base64_Encode
Giriþimizi "muhtemelen" deðiþtiren ikinci iþlev, baytlarý doðrudan base64'e dönüþtürür.
Genel olarak, her üç baytýn (her türlü bayt) 4 ASCII yazdýrýlabilir bayta dönüþtürülmesidir.
Giriþ baytlarý üçe bölünemez olduðunda, dolgu uygulanýr.
Dönüþtürme iþlemi, her üç baytý ikili olarak çevirerek, elde edilen bitleri 6 bitlik gruplara gruplayarak ve daha sonra bu baytlarýn ondalýk gösterimini kullanarak base64 tablosunda karþýlýk gelen karakteri arayarak gerçekleþir.
Standart base64 arama tablosu aþaðýda görülebilir.

Biliyorum biliyorum, sadece bunu uydurmuþ gibi geliyor ama base64 gerçekten böyle çalýþýyor.
Deðiþtirilmiþ giriþ arabelleðimizin ilk üç baytý için bunu deneyelim:
Kod:
Input : A7 AD A2
8-bit binary : 10100111 10101101 10100010
6-bit split : 101001 111010 110110 100010
Decimal : 41 58 54 34
base64 Lookup: p 6 2 i ----> p62i
Base64 iþlevi, iþleri basitleþtirmek için biraz uzundur, aþaðýdaki resim dönüþtürme iþleminin son adýmýnda kesme noktalarýný gösterir (ondalýk - > base64 arama tablosu).
Doðal olarak, 4 kesme noktasý vardýr; her arama için bir tane.

Ne olmasý gerektiðini zaten biliyoruz, ancak ikili dosyanýn ne yaptýðýný görelim.
Ýlk karakter:

Ýkinci karakter:

Üçüncü karakter:

Dördüncü karakter:

Açýkçasý burada uðursuz bir þey oluyor, base64 iyi görünüyor ama ... durum ters çevrilmiþtir ("p62i "vs"P62Ý").
Base64 arama tablosunu hatýrlayýn, ikili de bir tane vardýr, sadece büyük ve küçük harf karakterlerinin sýrasý ters çevrilir.
Base64 iþlevinin yürütülmesi sýrasýnda arama tablosu yýðýnda görülebilir.

Gizem çözüldü, bu sorunu çözmek için ihtiyacýmýz olan tüm bilgilere sahibiz.
Ýkili dosyanýn geri kalaný, base64'ü parçalara ayýrýr ve dinleyiciye gönderir.
Çözüm
Açýkçasý, bu zorluðu biraz ayrýntýlý olarak açýkladým, ama gerçek þu ki, ilk çözdüðümde her þey biraz daha kaotik oldu.
Böyle... Base64'ü orijinal girdiye dönüþtüren güzel bir python betiði yazabilirim, ancak bitiþ çizgisine acele etmeye çalýþýrken tembel bir kiþinin (yani: ben) ne yapabileceðini göstereceðim.
Ýlk olarak, deðiþtirilmiþ arama tablosunu göz önünde bulundurarak base64'ü doðru baytlara geri dönüþtürelim:

Ýkili, çok fazla çaba harcamadan bizim için zor iþin geri kalanýný yapmasýna izin verebiliriz.
Unutmayýn, ilk ASCII baytlarý aþaðýdaki komut add [ESI+EBX], al kullanýlarak kodlanýr.
Eðer ikili kodu çözdüðümüz baytlarla tedarik edersek ve bu talimatý sub [ESI+EBX] ' e eklersek, o zaman sadece çözümü tükürmelidir(göstermelidir)!
Önce ikili dosyayý yeniden baþlatýyoruz ve yukarýda belirtilen talimata ulaþana kadar yürütmeye devam ediyoruz:

Sonra bellekte base64 gelen çözdük byte ile byte yerine talimat tamir edersek.

Geriye kalan tek þey döngüyü çalýþtýrmak ve çözümün bellekte çözülmesini izlemek!

OYUN BÝTTÝ!
Translator: @Qgenays
Source: https://www.fuzzysecurity.com/tutorials/23.html