Invoke-Obfuscation v1.8

소개
Invoke-Obfuscation은 PowerShell v2.0+ 호환 PowerShell 명령
및 스크립트 난독화 도구입니다.
배경
2015년 가을, 저는 PowerShell 언어의 유연성을 연구하기 시작했고
공격자들이 정기적으로 사용하는 몇 가지 일반적인 기술을
수행하는 다양한 방법을 목록화하기 시작했습니다.
처음에는 인코딩된 명령과 원격 다운로드 크래들(cradle) 구문에 초점을 맞추면서,
명령 실행을 방해하지 않는 다양한 이스케이프 문자들이 실행 중인 프로세스와
Security EID 4688 및 Sysmon EID 1 이벤트 로그에 기록되는
명령줄 인수 모두에 남아 있음을 발견했습니다. 이로 인해 저는 모든 PowerShell
명령 또는 스크립트에서 발견되는 각 종류의 "토큰"을 난독화하는 방법을
체계적으로 탐색하게 되었습니다.
그런 다음 문자열 수준 난독화를 수행하는 더 난해한 방법, 다양한 인코딩/암호화 기술
(ASCII/hex/octal/binary 및 SecureString과 같은), 마지막으로 powershell.exe에서
명령줄 인수를 추상화하고 이를 부모 프로세스 및 심지어 조부모 프로세스로
다시 전달하는 PowerShell 실행 기술을 탐구했습니다.
목적
공격자와 상용 멀웨어는 극도로 기본적인 난독화 기술을 사용하여 powershell.exe의
명령줄 인수에서 명령의 대부분을 숨기기 시작했습니다. 저는 블루 팀이 PowerShell
2.0-5.0에서 구문적으로 가능하다고 현재 알려진 것에 기반한 난독화 명령을
시뮬레이션하여 이러한 기술에 대한 탐지 역량을 테스트할 수 있도록
이 도구를 개발했습니다.
이 도구의 유일한 목적은 방어자로서 우리가 PowerShell 명령이 명령줄에 어떻게
나타날 수 있는지에 대해 가질 수 있는 모든 가정을 깨는 것입니다. 제 바람은
이 도구가 블루 팀으로 하여금 PowerShell 로깅에 모듈, 스크립트블록 및
전사(Transcription) 로깅을 포함하도록 업데이트하는 것뿐만 아니라 명령줄에서
난독화 표시(Indicators of Obfuscation)를 찾도록 전환하도록 장려하는 것입니다.
이러한 소스는 이 도구가 생성하는 난독화 기술의 대부분 측면을 단순화하기 때문입니다.
사용법
모든 난독화 계층이 별도의 스크립트로 구축되어 있지만, 대부분의 사용자는
Invoke-Obfuscation 함수가 이 프레임워크가 현재 지원하는 난독화 기술을
탐색하고 시각화하는 가장 쉬운 방법임을 알게 될 것입니다.
설치
Invoke-Obfuscation의 소스 코드는 Github에 호스팅되어 있으며, 이 저장소
(https://github.com/danielbohannon/Invoke-Obfuscation)에서 다운로드, 포크 및
검토할 수 있습니다. 문제 또는 기능 요청은 이 프로젝트와 관련된 Github의
버그 추적기를 통해 보고해 주십시오.
설치 방법:
Import-Module ./Invoke-Obfuscation.psd1
Invoke-Obfuscation
라이선스
Invoke-Obfuscation은 Apache 2.0 라이선스로 배포됩니다.
릴리스 노트
v1.0 - 2016-09-25 DerbyCon 6.0 (루이빌, 켄터키주, 미국): Invoke-Obfuscation 공개 릴리스.
v1.1 - 2016-10-09 SANS DFIR 서밋 (프라하, 체코): 모든 해당 TOKEN 난독화 함수에
-f 형식 연산자 재정렬 기능을 추가했습니다. 또한 변수 값을 설정하는
추가 구문 옵션을 추가했습니다.
v1.2 - 2016-10-20 CODE BLUE (도쿄, 일본): Type TOKEN 난독화(유형 이름에 대한
문자열 난독화 옵션이 있는 직접 유형 캐스팅)를 추가했습니다.
v1.3 - 2016-10-22 Hacktivity (부다페스트, 헝가리): CLIP+ 및 CLIP++라는 두 가지
새로운 LAUNCHER를 추가했습니다. 또한 For-EachObject/%가 필요 없는 모든 ENCODING
함수에 대한 추가(및 더 간단한) 배열 문자 변환 구문을 추가했습니다.
v1.4 - 2016-10-28 BruCON (겐트, 벨기에): 새로운 BXOR ENCODING 함수를 추가했습니다.
또한 모든 ENCODING 함수의 모든 구성 요소와 모든 LAUNCHER의 PowerShell 실행
플래그에 대한 무작위 대소문자를 강화했습니다. 마지막으로, 모든 LAUNCHER에
-ExecutionPolicy에 대한 -EP 약칭 옵션과 -WindowStyle PowerShell 실행 플래그의
선택적 정수 표현(Normal (0), Hidden (1), Minimized (2), Maximized (3))을
추가했습니다.
v1.5 - 2016-11-04 Blue Hat (레드몬드, 워싱턴주, 미국): 일부 무작위화된
WMIC 명령줄 인수가 포함된 WMIC LAUNCHER를 추가했습니다.
v1.6 - 2017-01-24 Blue Hat IL (텔아비브, 이스라엘):
- CLI 기능 추가:
예: Invoke-Obfuscation -ScriptBlock {Write-Host 'CLI FTW!'} -Command 'Token\All\1,
Encoding\1,Launcher\Stdin++\234,Clip' -Quiet -NoExit
- 한 번에 하나의 난독화 계층을 제거하는 UNDO 기능 추가.
- 대규모 스크립트 난독화 속도를 높이기 위해 Token\All\1에서 공백(Whitespace) 난독화를 제거했습니다.
- 방어자를 돕기 위해 모든 런처에 프로세스 인자 트리(Process Argument Tree) 출력을 추가했습니다.
- BACK 또는 HOME을 사용할 필요가 없도록 기본 메뉴 자동 감지 기능 추가:
예: TOKEN을 실행한 다음 ALL, 1을 실행했다면, HOME이나 BACK을 입력하여 홈 메뉴로
돌아갈 필요 없이 LAUNCHER를 입력하기만 하면 LAUNCHER 메뉴에 도달합니다.
- CLI 및 대화형 모드에서 사용되는 다중 명령 구문 추가:
예: Token\All\1,String\3,Encoding\5,Launcher\Ps\234,Clip
- 모든 메뉴 및 난독화 명령에 정규식 기능 추가:
예: Token**,String[13],Encoding(1|6),Launcher.*[+]{2}\234,Clip
- OUT FILEPATH 단일 명령 기능 추가.
- SCRIPTBLOCK 값으로 powershell -enc 구문이 입력된 경우 디코딩 기능 추가.
- 모든 ENCODING 함수에서 ForEach-Object/% 무작위 구문 옵션에 별칭 ForEach를 추가했습니다.
- Out-SecureStringCommand.ps1에 -Key -Ke -K KEY 하위 문자열 구문 옵션을 추가했습니다.
- 모든 \Home\String 난독화 함수에 더 철저한 대소문자 무작위화를 추가했습니다.
- PowerShell 2.0에서 실행할 때 필요하므로 CLIP+ 및 CLIP++ 런처 함수에
-ST/-STA(단일 스레드 아파트) 플래그를 추가했습니다.
- 변수 값을 가져오기 위해 Get-ChildItem을 사용하는 모든 곳에
Get-Item/GI/Item 구문을 추가했습니다.
- TYPE 난독화 함수에 Set-Item 변수 초기화 구문을 추가했습니다.
- PowerShell 자동 변수와 환경 변수 값 연결을 사용하여
Out-ObfuscatedStringCommand.ps1의 Out-EncapsulatedInvokeExpression 함수에
추가 Invoke-Expression/IEX 구문을 추가하고 모든 런처, STRING 및 ENCODING
함수에 복사하여 IEX에 대한 다양한 명령줄 구문을 추가했습니다.
- String\Reverse 및 모든 ENCODING 난독화 옵션에 두 가지 새로운 JOIN 구문 추가:
- [String]::Join('',$string) JOIN 구문 추가
- OFS 변수 JOIN 구문 추가(Output Field Separator 자동 변수)
- Encoding\5에 SecureString 구문 두 개를 더 추가했습니다:
- PtrToStringAnsi / SecureStringToGlobalAllocAnsi
- PtrToStringBSTR / SecureStringToBSTR
- 여러 SecureString 멤버에 대한 GetMember 대체 구문 6개 추가:
- PtrToStringAuto, ([Runtime.InteropServices.Marshal].GetMembers()[3].Name).Invoke
- PtrToStringAuto, ([Runtime.InteropServices.Marshal].GetMembers()[5].Name).Invoke
- PtrToStringUni , ([Runtime.InteropServices.Marshal].GetMembers()[2].Name).Invoke
- PtrToStringUni , ([Runtime.InteropServices.Marshal].GetMembers()[4].Name).Invoke
- PtrToStringAnsi, ([Runtime.InteropServices.Marshal].GetMembers()[0].Name).Invoke
- PtrToStringAnsi, ([Runtime.InteropServices.Marshal].GetMembers()[1].Name).Invoke
- Out-ObfuscatedTokenCommand.ps1을 업데이트하여 VARIABLE 난독화가 이미
캡슐화된 변수를 ${}로 캡슐화하지 않도록 했습니다(따라서 ${${var}}는 오류를
유발하므로 발생하지 않음).
- Invoke-Obfuscation.psm1을 Invoke-Obfuscation.psd1로 대체했습니다(@Carlos_Perez
님 감사합니다).
- @cobbr_io 및 @IISResetMe 님이 보고한 여러 TOKEN 수준 난독화 버그를 수정했습니다.
v1.7 - 2017-03-03 nullcon (고아, 인도):
- RUNDLL, RUNDLL++ 및 MSHTA++의 3가지 새로운 LAUNCHER 추가
- 추가 ExecutionContext 와일드카드 변수 문자열 추가
v1.8 - 2017-07-27 Black Hat (라스베이거스, 네바다주, 미국):
- 특수 문자 및 공백의 2가지 새로운 ENCODING 옵션 추가
v1.8.1 - 2017-12-19:
- cmd.exe 명령줄 길이 제한을 위해 명령 길이를 대폭 줄이면서 여러 줄 스크립트를
한 줄 명령으로 더 쉽게 변환할 수 있는 COMPRESS 함수 추가.
v1.8.2 - 2018-01-04:
- 특수 문자를 많이 사용하지 않고 AbstractSyntaxTree의 구조를 조작하여 난독화하는
AST 난독화 함수 추가.