
RunPE 기술의 VBA 구현 또는 애플리케이션 허용 목록 우회 방법
RunPE 기법을 VBA로 간단하면서도 효과적으로 구현한 것입니다. 이 코드는 Word나 Excel의 메모리에서 실행 파일을 실행하는 데 사용할 수 있습니다. Microsoft Office 2010 이상의 32비트 및 64비트 버전과 호환됩니다.
자세한 내용은 여기에서 확인하세요: https://itm4n.github.io/vba-runpe-part1/ https://itm4n.github.io/vba-runpe-part2/

Exploit 프로시저에서 실행하려는 파일의 경로를 설정합니다.strSrcFile = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
/!\ 64비트 OS에서 32비트 버전의 Microsoft Office를 사용하는 경우, 32비트 바이너리를 지정해야 합니다.
strSrcFile = "C:\Windows\SysWOW64\cmd.exe"
strSrcFile = "C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe"
strArguments = "-exec Bypass"
이 값은 다음과 같은 명령줄을 구성하는 데 사용됩니다:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -exec Bypass
(선택 사항) 보기 > 직접 실행 창 (Ctrl+G)을 사용하여 실행 및 오류 로그를 확인합니다.
Exploit 매크로를 실행하세요!
pe2vba.py를 사용하여 PE 파일을 VBA로 변환합니다. 이렇게 하면 PE를 매크로에 직접 포함시킬 수 있습니다.user@host:~/Tools/VBA-RunPE$ ./pe2vba.py meterpreter.exe
[+] Created file 'meterpreter.exe.vba'.
RunPE.vba의 다음 코드를 이전 단계에서 생성된 .vba 파일의 내용으로 바꾸세요.' ================================================================================
' ~~~ EMBEDDED PE ~~~
' ================================================================================
' CODE GENRATED BY PE2VBA
' ===== BEGIN PE2VBA =====
Private Function PE() As String
Dim strPE As String
strPE = ""
PE = strPE
End Function
' ===== END PE2VBA =====
(선택 사항) 보기 > 직접 실행 창 (Ctrl+G)을 사용하여 실행 및 오류 로그를 확인합니다.
Exploit 매크로를 실행하세요!
/!\ 내장 PE를 사용하는 경우, PE() 메서드가 비어 있지 않은 문자열을 반환하므로 매크로가 자동으로 이 모드로 전환됩니다.
GetThreadContext()가 오류 코드 998과 함께 실패합니다.__64비트 버전의 Office__에서 이 매크로를 실행하면 이 오류가 발생할 수 있습니다. __해결 방법__으로, Word 개체 참조에서 실행하는 대신 코드를 __모듈__로 이동할 수 있습니다. @joeminicucci님께 팁 감사드립니다.
================================================================================
[*] Source file: 'C:\Windows\System32\cmd.exe'
[*] Checking source PE...
[*] Creating new process in suspended state...
[*] Retrieving the context of the main thread...
|__ GetThreadContext() failed (Err: 998)
이 해결 방법이 왜 작동하는지 현재로서는 알 수 없습니다. 하지만 조금 조사해 보았습니다. 이 오류는 64비트 버전에서 CONTEXT 구조체가 올바르게 정렬되지 않아 발생하는 것으로 보입니다. 구조체의 크기도 잘못되었습니다 ([VBA] LenB(CONTEXT) != [C++] sizeof(CONTEXT)). 32비트 버전에서는 정상입니다. GetThreadContext()가 제대로 반환되도록 하는 해결 방법은 있지만, 이후 실행 과정에서 다른 부분이 깨집니다.
수정 2019-12-15: 64비트 버전의 CONTEXT 구조체 정의가 실제로 올바르지 않았지만, 이를 수정해도 버그가 해결되지 않았습니다. 따라서 64비트 버전에 대한 해결 방법을 구현했습니다. GetThreadContext() 및 SetThreadContext() 함수의 CONTEXT 구조체 인수를 동일한 크기의 Byte 배열로 대체했습니다.
수정 2019-12-17: 마침내 문제를 찾았습니다. 처음 가정이 맞았습니다. CONTEXT 구조체는 메모리에서 16바이트 정렬되어야 합니다. C에서는 align(16)을 사용하여 제어할 수 있지만 VBA에서는 그렇게 할 수 없습니다. 따라서 GetThreadContext()와 SetThreadContext()는 "무작위로" 실패할 수 있습니다. 반면 Byte 배열은 항상 16바이트 정렬되어 있는 것 같아 이 해결 방법이 효과적이지만, VBA 인터프리터/컴파일러를 리버스 엔지니어링하여 확인하지 않는 한 보장할 수 없습니다.
LongPtr - 사용자 정의 형식이 정의되지 않았습니다이 오류가 발생하면 이전 버전의 Office(<=2007)에서 매크로를 실행하고 있음을 의미합니다. LongPtr 형식은 VBA7(Office 2010)에서 64비트 Windows API 지원과 함께 도입되었습니다. 아키텍처(32비트/64비트)를 신경 쓰지 않고 포인터를 처리하는 데 매우 유용합니다.
해결 방법으로, 모든 LongPtr을 Long(32비트) 또는 LongLong(64비트)으로 바꿀 수 있습니다. 즐겨 사용하는 텍스트 편집기에서 Ctrl+H를 사용하세요.
@hasherezade - 완전한 RunPE 구현 (https://github.com/hasherezade/)
@Zer0Mem0ry - C++로 작성된 32비트 RunPE (https://github.com/Zer0Mem0ry/RunPE)
@DidierStevens - VBA에 PE 포함
이 코드는 다음 플랫폼에서 테스트되었습니다:
다음은 일부 Win32 형식과 VBA 형식 간의 대응 관계 표입니다:
(*) LongPtr은 "동적" 형식으로, Office 32비트에서는 4바이트, Office 64비트에서는 8바이트입니다. https://msdn.microsoft.com/fr-fr/library/office/ee691831(v=office.14).aspx
| C++ | VBA | Arch |
|---|
| BYTE | Byte | 32 & 64 |
| WORD | Integer | 32 & 64 |
| DWORD, ULONG, LONG | Long | 32 & 64 |
| DWORD64 | LongLong | 64 |
| HANDLE | LongPtr(*) | 32 & 64 |
| LPSTR | String | 32 & 64 |
| LPBYTE | LongPtr(*) | 32 & 64 |