
.NET DLR 무기화를 위한 연구 노트 및 PoC 코드가 포함된 툴박스
.NET DLR을 무기화하기 위한 연구 노트 및 PoC 코드가 포함된 툴박스
| 스크립트 | 설명 |
|---|---|
Kukulkan | SILENTTRINITY의 축소 버전. IPY 엔진을 내장하는 C# DLL 및 EXE. 통신은 암호화되며 CobaltStrike와 함께 사용할 수 있음 |
Invoke-JumpScare.ps1 | 내장된 Boolang 컴파일러를 사용해 셸코드를 실행합니다. 디스크에 아무것도 닿지 않으며(적어도 제가 본 바로는) csc.exe 호출도 이루어지지 않습니다 :) |
Invoke-IronPython.ps1 | 내장된 IPY 엔진을 사용해 IronPython 코드를 실행합니다. Invoke-JumpScare와 동일한 개념이지만 IronPython을 사용합니다. |
Invoke-ClearScript.ps1 | 내장된 ClearScript 엔진을 사용해 JScript(또는 VBScript)를 실행합니다 |
SharpSnek.cs | IronPython 엔진을 내장하고 포함된 IPY 코드를 실행하는 C# 코드. 런타임에 필요한 어셈블리를 resolve하기 위해 AppDomain.CurrentDomain.AssemblyResolve를 후킹합니다. |
runBoo.cs | Invoke-JumpScare의 C# 버전. 내장된 Boolang 컴파일러를 사용해 셸코드를 실행합니다. |
runBooAssemblyResolve.cs | Boolang 컴파일러를 내장하고 포함된 Boolang 코드를 실행하는 C# 코드. 런타임에 필요한 어셈블리를 resolve하기 위해 AppDomain.CurrentDomain.AssemblyResolve를 후킹합니다. |
minidump.boo | MiniDumpWriteDump를 사용해 메모리를 덤프하는 네이티브 Boolang 스크립트 |
shellcode.boo | 셸코드를 실행하는 네이티브 Boolang 스크립트. 현재 3가지 다른 기술을 포함함 (QueueUserAPC, CreateThread/WaitForSingleObject, WriteProcessMemory/CreateRemoteThread) |
Invoke-SSharp.ps1 | PowerShell 내의 임베디드 컴파일러에서 SSharp을 실행합니다. 컴파일은 csc.exe를 호출하지 않습니다 |
Invoke-Boolang.ps1 | 임베디드 컴파일러에서 Boo 코드를 실행합니다. 또한 Boolang 컴파일러가 PowerShell 내에 임베드될 때 발견한 몇 가지 버그에 대한 해결 방법을 제공합니다. |
Invoke-NeoLua.ps1 | PowerShell 내의 임베디드 컴파일러에서 Lua 코드를 실행합니다. |
.NET DLR은 정말 말도 안 되게 강력합니다. OPSEC 안전을 유지하면서 메모리에 머무른 채 다른 .NET 언어(예: PowerShell 및 C#) 안에 컴파일러/엔진을 임베드하는 것과 같은 미친 짓을 할 수 있게 해줍니다. IronPython의 경우에는 제가 '엔진 인셉션'이라고 부르는 것도 가능합니다. IPY 엔진 안에 IPY 엔진을, 그리고 그 안에 또 다른 IPY 엔진을 임베드하고 싶지 않으세요? (yo dawg, I heard you liked IPY engines...).
공격 관점에서 이는 어마어마한 유연성과 여러 장점을 제공합니다. 몇 가지만 나열하면:
별도의 설정 없이 .NET API에 접근할 수 있으며, 어떤 식으로든 PowerShell을 거치지 않습니다. 본질적으로 DLR을 사용하면 PowerShell의 모든 힘을 PowerShell 없이, 그리고 (보통) 스크립팅하기 더 쉬운 언어(예: Python)로 사용할 수 있습니다.
끊임없이 엄청난 양의 리플렉션/임베딩이 발생하므로 더 많은 회피가 가능합니다.
DLR을 사용하면 항상 AMSI를 우회합니다(페이로드를 제대로 인스트루먼트했다면). 난독화나 패치 등을 할 필요가 없습니다.
'악성' 코드 전부를 임베드된 엔진/컴파일러의 언어로 작성할 수 있습니다. PowerShell로 이 작업을 수행하면 모든 마법이 DLR 안에서 일어나므로 ScriptBlock Logging은 아무것도 보지 못합니다.
일반적으로 모든 DLR 언어는 언어 자체를 통하거나 C#을 동적으로 컴파일하는 방식(예: PowerShell의 Add-Type)으로 네이티브 메서드를 호출할 수 있습니다.
전자의 방법을 사용하면 csc.exe 호출이 발생하지 않으며, 언어들이 IL 코드를 통해 필요한 모든 것을 메모리에서 생성하므로 디스크에 떨어지는 것이 없습니다.
우리는 "...우리가 원하는 만큼 낮게도 높게도.." 갈 수 있으며 (@Op_nomad), 이를 통해 우리 모두가 사랑하는 좋은 작업들(셸코드 주입, 비관리 DLL, PE 로드 등)을 할 수 있습니다.
페이로드를 신속하게 재도구화하고 무기화할 수 있습니다. 수동 컴파일이 필요 없습니다.
이 주제에 관심이 있다면, DLR을 무기화하려는 다른 도구들도 있습니다:
미리 경고합니다. 이 자료들을 읽기 시작하면 지옥 같은 토끼굴로 빠져들게 될 것입니다(실제 악마 토끼들과 함께).