BOF - Stack Based
Buffer Overflow
Stack Based Buffet Overflow
FuzzingUygulamada bulunan girdi noktalarına fuzzing uygulanır. Bu işlem için aşağıdaki python kodu ile bir soket başlatılıp TCP üzerinden data gönderilebilir.
Fuzzing işlemi sırasında program crashlenir ise "access violation" hatası alınırsa büyük ihtimal ile bof zafiyeti vardır. Immunity Debugger'dan EIP, EAX
gibi registerların değerine bakılabilir.
Crash kaç byte gönderildikten sonra alınmış ise o boyutta pattern oluşturulup gönderilir. Bunu yapmaktaki amaç kaç byte'dan sonra EIP ve ESP
registerlarına yazıyor bilgisine ulaşmak.
Offset Bulma
Bu işlem için pattern üretilmelidir. Bunu birçok farklı şekilde yapmak mümkündür. Immunity Debugger'da kullanılan mona
veya kalide bulunan pattern_create veya pattern_offset
gibi araçlar kullanılabilir.
Mona modülünü kullanırken logların kaydedileceği dizini ayarlamak için aşağıda yer alan komut kullanılabilir.
mona ile;
!mona pc <pattern_size>
msf'de bulunan ruby aracı ile;
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l <pattern_size>
/bin/msf-* araçları ile;
msf-pattern_create -l <pattern_size>
Benzer amaçla yazılmış bir çok tool bulmak mümkündür. (Kali de /bin/msf-* araçları da ayrıca vardır.)
EIP registarına yazılan değerin offset değerini bulmak için; 1. mona ile;
!mona po <pattern_value>
msf'de bulunan ruby aracı ile;
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l <pattern_size> -q <pattern_value>
/bin/msf-* araçları ile;
msf-patter_offset -q <pattern_value>
Badchar bulma;
EIP registerına ait offset değeri bulunduktan sonra badcharların bulunması gerekli. Badcharlar registerlarda bulunan veriler işlenirken özel olarak yorumlanan karakterlerdir. Bu durum bizim kullanacağımız zararlı shellcode'u etkileyeceği için bu tür karakterleri içermeyecek şekilde shellkodumuzu üretmeliyiz.
Bu aşamada gönderilecek verimiz
"A" * <offset_value> + "B" * 4 + badchars
şeklinde olacaktır. badchar değişkeninin tuple olması önemlidir!
Stack alanını doldurduğumuzda yani EAX, EBX, EIP
registarlarına yazdıktan sonra badcharların yazılacağı register ESP
registerı olacaktır.
Not ; ESP Shellkodumuzu bu registara yazacağız. O yüzden bu registara yazılacak shellcodun içinde badchar olması durumunda shellcodumuz çalışmayacaktır. Bu sebepten badchar tespiti önemlidir.
Uygun modulün bulunması
Shellcodumuz stack de bulunan ESP
belirtiği alana yazılır. Bu sebeple bizim bu registara atlayan (JMP) komutun bellek adresine ihtiyacımız olacak. Yukarıda belirtildiği üzere EIP
registerına yazabilmekteyiz. Biz de EIP
registarına, ESP
registarına zıplayan kodun bellek adresini yazacağız. Böylece kod ÈIP
registarına geldiğinde burda ESP
giden bellek adresini görecektir. ESP
ye shellcodumuzu yazarak programın akışını değiştirip istediğimiz kodu çalıştırmış olacağız. Bu sebeple ESP
registarına giden bir komutun bellek adresine ihtiyaç duymaktayız. Bunu bulmanın birçok farklı yolları vardır.
Öncellikler !mona modules
diyerek uygulamamızın kullandığı modüllere bakacağız. Bu modüllerde herhangi bir memory proctection var mı? varsa hangileri gibi bilgiler bizim için önemli. Çıkan menüde memory protection olmayan modüller birincil odak noktamız olmalı.
Daha memory procteion olmayan modüllerin herhangi birinde JMP ESP
kodunu arayacağız. Bunu yapmaktaki amacımız; bu komutun olduğu bellek adresini bulup EIP
registerına yazmak. EIP
bu bellek adresindeki komutu gösterdiğinde burdaki komut ile ESP
sıçrayacaktır ve ordan da shellcodumuz çalışmış olacak.
JMP ESP
komutunun opcoduFFE4
dür.
mona ile;
!mona find -s “\xff\xe4” -m <module_name>
ımmunity debugger ile;
View > Executables modules > "module_name" X2 click > CTRL + F > search "JMP ESP" > note memmory adres!
Bulunan değer EIP
registarına yazılacak şekilde koda eklenmelidir. Kodun bu aşamadki hali;
"A" * <byte_size> + "<adress of JMP ESP>" + "\x90" * 8
olmalıdır.
Not : JMP ESP
nin bellek adresi yazılırken little endian olduğu için tersten yazılmalıdır. Yani "A5F256CC" adresi "CC56F2A5" şeklinde yazılmalıdır.
Shellcode üretme
Bu aşamada shellcodu üretip göndereceğimiz payloada ekleyeceğiz. Bunun için msfvenom
aracını kullanacağız.
bu komutun sonucunda çıkan çıktıyı kodumuza aşağıdaki şekilde ekleyeceğiz.
buffer = "A" * <byte_size> + "<address of JMP ESP>" + "\x90" * 8 + shellcode
Payloadın nihai şekli yukarıdaki şekildedir.
Get Reverse Shell
Artık tüm işlemler tamam olduğuna göre nc
ile ilgili portu dinlemeye alıp exploit kodumuzu çalıştırmamız gerekecek.
nc -vlp <port_number>
Dipnotlar;
badchars değişkeni tuple olmalıdır!
"\x90" no operation komutudur. Kullanacağımız payloadın patlamaması için kesinlikle eklenmesi tavsiye edilir.
shellcode üretilirken özellikle windows tarafından engellenmeyecek portlar kullanılması tavsiye edilir. 53, 80, 443 gibi sık kullanılan portlar kullanılmalıdır.
Bonus - Sample;
Last updated