- 통합 네트워크 보안 솔루션 - 방화벽, VPN, 웹 필터링, 바이러스 방지, 네트워크 모니터링 기능 제공
2. CVE-2024-52875 [2]
- KerioControl에서 발생하는 CRLF 인젝션 취약점
> HTTP 헤더와 응답 내용을 조작하여, 악성 자바스크립트가 서버 응답에 삽입
> 스크립트가 실행되면 인증된 관리자 사용자의 쿠키 또는 CSRF 토큰을 탈취하며, 토큰을 활용해 악성 .IMG 파일 업로 및 루트 권한의 쉘 스크립트 실행
영향받는 버전 : KerioControl 9.2.5 ~ 9.4.5
CRLF (Carriage Return Line Feed) Injection - CR (Carrige Return: \r, %0D) : 커서의 위치를 현재 줄의 맨 처음으로 보내는 기능 - LF (Line Feed: \n, %0A) : 커서를 다음 줄로 옮기는 기능 > CRLF는 줄 바꿈을 의미 - HTTP 요청과 응답은 Header와 Body로 구성되며, 이를 CRLF로 구분 - 요청 또는 응답에 CRLF를 추가해 Header와 Body를 분리하여 의도하지 않은 Header를 추가하거나 Body에 명령 추가가 가능한 취약점
- dest 파라미터에서 줄 바꿈 문자(Line Feed, LF)에 대한 불충분한 검증으로 인해 발생
> dest 파라미터를 통해 전달된 값은 Location 헤더로 설정되어 HTTP 응답
> Location 헤더는 HTTP 응답에서 클라이언트에게 리소스가 이동된 URL을 알려주는 데 사용되며, 주로 3xx 리다이렉션 응답에 사용
[요청] GET /nonauth/guestConfirm.cs?dest=aHR0cDovL2F0dGFja2VyLndlYnNpdGU= HTTP/1.1 Host: 192.168.123.64:4081 Connection: close
[응답] HTTP/1.1 302 Found Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Connection: Close Content-Type: text/html Date: Thu, 5 Dec 2024 11:03:38 GMT Expires: Wed, 4 Jun 1980 06:02:09 GMT Location: hxxp://attacker.website Pragma: no-cache Server: Kerio Control Embedded Web Server Strict-Transport-Security: max-age=63072000, includeSubDomains, preload X-UA-Compatible: IE=edge
If your browser does not redirect automatically, please click this link: <a href="hxxp://attacker.website">hxxp://attacker.website</a>
- dest 매개변수에 "\n"이 포함된 값을 전달하면 불충분한 검증으로 Header와 Body를 조작 및 분할할 수 있음
> 아래 응답 예시에서 Header는 HTTP/1.1 302 Found ~ Location: Test 이며 Body는 Test ~ Test</a>로 조작됨
[요청] GET /nonauth/guestConfirm.cs?dest=VGVzdAoKVGVzdA== HTTP/1.1 Host: 192.168.123.64:4081 Connection: close
* VGVzdAoKVGVzdA== : Test\n\nTest
[응답] HTTP/1.1 302 Found Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Connection: Close Content-Type: text/html Date: Thu, 5 Dec 2024 11:34:58 GMT Expires: Wed, 4 Jun 1980 06:02:09 GMT Location: Test
Test Pragma: no-cache Server: Kerio Control Embedded Web Server Strict-Transport-Security: max-age=63072000, includeSubDomains, preload X-UA-Compatible: IE=edge
If your browser does not redirect automatically, please click this link: <a href="Test
Test">Test
Test</a>
- 공격자는 dest 매개변수에 \n\n를 포함하는 악성 스크립트를 삽입해 악성 스크립트 실행 가능 [3]
스크립트 예시
<script>
target = "192.168.123.64"; // IP address / hostname of the Kerio Control instance
payload = (navigator.userAgent.includes("Firefox")) ? "resource://xss" : "";
payload += "\n\n<script>alert('XSS on ' + document.domain)<\/script>";
location.href = "https://" + target + ":4081/nonauth/guestConfirm.cs?dest=" + encodeURIComponent(btoa(payload));
</script>
3. 대응방안
- 벤더사 제공 업데이트 적용
제품명
영향받는 버전
해결 버전
KerioControl
9.2.5 ~ 9.4.5
9.4.5 패치 1
- 신뢰할 수 있는 IP만 웹 관리 인터페이스에 접근할 수 있도록 제한
- /admin 및 /noauth 페이지에 대한 공개 접근을 방화벽 규칙을 통해 비활성화
- dest 파라미터 대상 한 악성 활동 모니터링
- alert tcp any any -> any any (msg:"CVE-2024-52875"; content:"/nonauth/guestConfirm.cs?dest="; http_uri; nocase;) - alert tcp any any -> any any (msg:"CVE-2024-52875"; content:"/admin/guestConfirm.cs?dest="; http_uri; nocase;) - alert tcp any any -> any any (msg:"CVE-2024-52875"; content:"\n\n";)
- 온라인에서 의류, 머그컵, 휴대폰 케이스 등을 사용자 맞춤형으로 디자인할 수 있게 해주는 Worpress 플러그인 [2]
2. 취약점
2.1 CVE-2024-51818 [3]
- 취약점은 class-wc-dokan.php의 get_products_sql_attrs() 함수에 존재 > 해당 함수는 class-product.php의 get_products()에 의해 호출 > Line13 : $attrs를 매개변수로 fpd_get_products_sql_attrs() 호출
- get_products_sql_attrs() > Line23 : fpd_filter_users_select 값이 존재하고, -1이 아닌 경우 if문 실행 > Line24 : "user_id=" 문자열 뒤 strip_tags($_POST['fpd_filter_users_select'])를 추가한 결과를 $where 변수에 할당
- strip_tags()는 NULL bytes와 HTML 및 PHP 태그를 제거하는 함수로 SQL 공격을 방지하지 못함 [4] > Line29~31 : $where 값은 get_products()의 $wpdb->get_results로 쿼리에 실행
- 취약점이 벤더사에 전달 되었으나, 최근 버전(6.4.3)까지 패치가 이루어지지 않은 상태 > 권고사항 ⓐ임의 파일 업로드 방지 : 안전한 파일 확장자만 허용하는 허용 목록(allowlist) 설정 ⓑ SQL 인젝션 대응 : 데이터베이스 쿼리의 철저한 입력 값 검증 및 적절한 이스케이프 처리 ⓒ 정기적인 보안 점검 : 플러그인 업데이트 상태 주기적 확인 및 새로운 취약점 발생 여부 모니터링 ⓓ 대안 플러그인 고려 : 개발사가 문제를 해결하지 않는 상황에서 보안이 보장된 대안 플러그인을 사용 고려
- 도메인 컨트롤러를 대상으로 시스템 충돌과 재부팅을 유발할 수 있는 취약점 LDAPNightmare 발견 [1] - 서비스 거부 취약점 CVE-2024-49113과 정수 오버플로를 통한 원격 코드 실행 취약점 CVE-2024-49112 - Windows 서버를 대상으로 한 심각한 보안 위협이 되고 있어 가능한 한 빨리 '24.12 보안 업데이트 적용 필요
1.1 LDAP(Lightweight Directory Access Protocol)
- 네트워크 상에서 조직이나 개인정보 혹은 파일이나 디바이스 정보 등을 찾아보는 것을 가능하게 만든 소프트웨어 프로토콜로 389 포트 사용 [2][3]
> 디렉토리 서비스 표준인 X.500의 DAP(Directory Access Protocol)를 기반으로한 경량화(Lightweight)된 버전으로 서버-클라이언트 구조
※ 디렉토리 서비스란 이름을 기준으로 대상을 찾아 조회하거나 편집할 수 있는 서비스
2. 취약점
2.1 CVE-2024-49113
- Windows LDAP 프로토콜에서 발생하는 서비스 거부 취약점
> 공격자가 조작된 CLDAP 요청을 보내 LSASS 프로세스를 충돌시켜 서버 재부팅을 유발할 수 있음
CLDAP (Connection-less Lightweitght Directory Access Protocol) - LDAP의 한 종류로, UDP/389포트를 사용 (LDAP는 TCP 사용) - LDAP 대비 응답 시간이 빠르고 오버헤드가 낮으나, 데이터 손실이 발생 가능 ※ UDP의 특성상 송신 IP를 확인하지 않고, 응답 패킷이 요청 패킷보다 훨씬 커 DRDoS 공격에 사용됨 (평균 50~86배 정도 증폭)
LSASS (Local Security Authority Subsystem Service) - Windows 운영체제에서 시스템의 보안 정책을 강화를 위한 윈도우의 프로세스 > 윈도우 시스템에 로그인하려는 사용자의 유효성을 판단 > 사용자 비밀번호 저장 및 관리, 비밀번호 변경 요청 처리 > 인증된 사용자에게 시스템 자원에 접근할 수 있는 권한을 부여하는 액세스 토큰을 생성 > 시스템 보안 관련 이벤트를 기록하며, 시스템의 보안 정책을 적용 및 관리 ※ 시스템의 모든 사용자 자격 증명을 저장하고 관리하기 때문에 공격자의 주요 목표 중 하나이며, Mimikatz 등의 공격 도구 존재
- 공격과정
① 공격자는 피해자 DC에 DCE/RPC 요청을 전송
- 공격자가 제어하는 LDAP 서버를 쿼리하도록 조작된 DCE/RPC 요청을 전송
> RPC 메소드 중 DsrGetDcNameEx2 메소드는 도메인 컨트롤러의 LDAP 서버 정보를 반환하기 위해 설계된 RPC 호출임
- DsrGetDcNameEx2 메소드의 매개변수 중 DomainName을 공격자가 제어하는 DNS 서버로 조작하여 요청 전송
> DomainName이 특정 도메인 또는 사이트를 가리킬 때, 자동으로 해당 도메인에 대한 LDAP DNS SRV 쿼리를 생성
> DNS는 공격자가 제어하는 LDAP 서버의 호스트 네임과 LDAP 포트 정보 응답
- DC (Domain Controller) : 로그인, 이용권한 확인, 새로운 사용자 등록, 암호 변경 등을 처리하는 기능을 하는 서버 컴퓨터 - DCE/RPC (Distributed Computing Environment/Remote Procedure Calls) : 분산 컴퓨팅 환경(DCE)에서 원격 프로시저 호출(RPC)을 구현하기 위한 프로토콜 - DNS SRV (Service Resource Record) : 특정 서비스에 대해 도메인 이름을 기반으로 연결할 수 있는 호스트 및 포트 정보를 제공하는 DNS 레코드 유형
② NBNS 요청 및 응답
- LDAP 서버의 호스트네임과 포트 정보를 수신한 피해자는 LDAP 서버에 대한 NBNS 쿼리를 수행
> 호스트네임에 대응하는 LDAP 서버의 IP 주소(공격자가 제어하는 LDAP 서버 IP) 응답
- NetBIOS (Network Basic Input/Output System) : 윈도우 네트워크에 사용되는 컴퓨터 이름 [6] - NBNS (NetBIOS Name Service) : NetBIOS 네트워크 상에서 호스트 이름을 IP 주소로 해석하기 위해 사용되는 프로토콜 [7]
③ 조작된 CLDAP 응답으로 시스템 재부팅 유도
- 피해자 DC는 공격자의 LDAP 서버에 CLDAP 요청을 전송
> 공격자는 LDAP 참조(referral) 결과 코드와 함께 조작된 lm_referral 값을 포함한 조작된 CLDAP 응답 전송
> 조작된 lm_referral 값에 의해 범위를 벗어난 읽기와 LSASS를 충돌이 발생하고 시스템 재부팅을 유도할 수 있음
※ 관련 PoC [8]
lm_referral 값
- LDAP 클라이언트가 참조 테이블에서 메모리 접근을 수행할 때 사용 - 참조 테이블에 액세스하는지 여부를 결정하는 조건은lm_referral 값이 0이 아닌지 확인 - 0이 아닌 값은 참조 테이블의 오프셋으로 사용되어 메모리 접근이 시도 - 공격자는 해당 값을 조작해 클라이언트가 잘못된 메모리 위치를 참조하도록 유도
2.2 CVE-2024-49112
- Windows LDAP 프로토콜에서 발생하는원격 코드 실행 취약점 (CVSS: 9.8)
> CLDAP 패킷을 변조하여 LDAP 서비스에서 임의 코드를 실행할 수 있음
<<내용 추가 예정>>
3. 대응방안
- MS 12월 보안 위협에 따른 정기 보안 업데이트 적용 [10]
> 즉시 패치가 어려운 경우 권고 사항
① 악성 값이 설정된 CLDAP 참조 응답을 모니터링 ② 비정상적인 DsrGetDcNameEx2 호출을 탐지 ③ 도메인 컨트롤러를 대상으로 하는 의심스러운 DNS SRV 조회를 감지
- ProjectDiscovery에서 개발한 YAML 기반 템플릿을 사용하여 취약점을 스캔하는 go 언어 기반의 오픈소스 취약점 스캐너 > YAML 파일로 취약점 스캔 탬플릿을 정의하며, 해당 템플릿을 통해 취약점을 식별 > 템플릿은 직접 작성하거나 커뮤니티에서 제공하는 템플릿 활용 가능 - 웹 애플리케이션 취약점, 네트워크 서비스, API 스캔 등이 가능 - 멀티스레드 기반의 빠른 스캔, 유연성 및 확장성 등의 장점이 있음
2. CVE-2024-43405
- Nuclear의 템플릿 서명 검증 시스템에서 발생하는 서명 검증 우회 취약점
영향받는 버전 : Nuclei 3.0.0 ~ 3.3.2 이전 버전
- ProjectDiscovery는 무단 데이터 액세스와 시스템 손상을 방지 하기위해 서명 검증 메커니즘을 구현 (위변조 방지, 무결성 확인)
> 템플릿 파일 내용을 기준으로 SHA256을 계산해 "#digest:"로 삽입
서명 검증 과정
서명 추출
정규식을 사용하여 "#digest:" 줄 검색
서명 제거
템플릿 콘텐츠에서 서명 줄 제외
해시 계산
서명을 제외한 콘텐츠 해시 계산
서명 검증
계산된 해시를 추출된 서명과 비교하여 검증
- Nuclear 서명 검증 논리에서 서명 추출 및 제거는 정규표현식을 사용하며, 이후 구문 분석 및 실행에는 YAML 파서 사용
> Line1 ~ Line31 : 첫 번째 서명을 찾아 템플릿에서 서명을 제거 > Line33 ~ Line51 : 서명 검증 후 YAML로 구문 분석 및 실행
> 첫 번째 서명(#digest:)만 확인 : 악성코드가 포함된 두 번째 서명이 검증되지 않고 템플릿에 남아있을 수 있음 > 줄 바꿈 해석 불일치 : 정규 표현식을 사용한 서명 검증과 YAML 파서 간 줄 바꿈 해석 불일치로 추가 콘텐츠를 삽입할 수 있음
구분
설명
정규 표현식
‘\r’를 동일한 줄의 일부로 간주
YAML 파서
‘\r'를 줄 바꿈 문자로 해석
1 var (
2 ReDigest = regexp.MustCompile(`(?m)^#\sdigest:\s.+$`)
3 SignaturePattern = "# digest: "
4 )
5
6 func RemoveSignatureFromData(data []byte) []byte {
7 return bytes.Trim(ReDigest.ReplaceAll(data, []byte("")), "\n")
8 }
9
10 func (t *TemplateSigner) Verify(data []byte) (bool, error) {
11 digestData := ReDigest.Find(data)
12 if len(digestData) == 0 {
13 return false, errors.New("digest not found")
14 }
15
16 digestData = bytes.TrimSpace(bytes.TrimPrefix(digestData, []byte(SignaturePattern)))
17 digestString := strings.TrimSuffix(string(digestData), ":"+t.GetUserFragment())
18 digest, err := hex.DecodeString(digestString)
19 if err != nil {
20 return false, err
21 }
22
23 buff := bytes.NewBuffer(RemoveSignatureFromData(data))
24
25 // Verify using standard Go's ECDSA
26 if !t.verify(sha256.Sum256(buff.Bytes()), digest) {
27 return false, errors.New("signature verification failed")
28 }
29
30 return true, nil
31 }
32
33 // SecureExecute is a mock we at Wiz created that mimics Nuclei's logic to illustrate the vulnerability,
34 // verifying a template's signature, parsing it as YAML, and executing it.
35 func SecureExecute(rawTemplate []byte, verifier *TemplateSigner) (interface{}, error) {
36 // Verify the template signature
37 isVerified, err := verifier.Verify(rawTemplate)
38 if err != nil || !isVerified {
39 return nil, errors.New("template verification failed")
40 }
41
42 // Parse the template
43 template := &Template{}
44 err = yaml.Unmarshal(rawTemplate, template)
45 if err != nil {
46 return nil, errors.New("couldn't unmarshal template")
47 }
48
49 // Execute the template and return the result
50 return template.execute()
51 }
- 두 번째 서명에 '\r'를 포함한 악성코드를 삽입하여 악용 가능 > 두 번째 서명은 서명 검증 과정을 거치지 않고, YAML에서 구문 분석 후 실행됨
3. 대응방안
- Nuclei 3.3.2 이상으로 업그레이드 - 악성 템플릿의 실행을 방지하기 위해 샌드박스 또는 격리된 환경에서 Nuclei 실행
- 벤더사의 취약점 패치 발표 여부 확인 불가 > VulnCheck는 Suricata를 이용한 규칙 공유
alert http any any -> any any ( \ msg:"VULNCHECK Four-Faith CVE-2024-12856 Exploit Attempt"; \ flow:to_server; \ http.method; content:"POST"; \ http.uri; content:"/apply.cgi"; startswith; \ http.header_names; content:"Authorization"; \ http.request_body; content:"change_action="; \ content:"adjust_sys_time"; \ pcre:"/adj_time_[^=]+=[a-zA-Z0-9]*[^a-zA-Z0-9=]/"; \ classtype:web-application-attack; \ reference:cve,CVE-2024-12856; \ sid:12700438; rev:1;)
> Snort 탐지 규칙
alert tcp any any -> any any (msg:"CVE-2024-12856"; flow:to_server,established; content:"POST"; http_method; content:"/apply.cgi"; http_uri; content:"adj_time_year"; http_client_body; nocase;)
- 권고사항 > 기본 자격 증명 변경 > 불필요 서비스 및 포트 비활성화 > 정기적 펌웨어 업데이트 등
※ Learning Management System : 학습 관리 시스템, 온라인으로 학생들의 학습을 관리할 수 있게 해주는 소프트웨어
2. VibeBP (Vibe BuddyPress Plugin)
- WPLMS와 함께 사용되는 플러그인으로, 강력한 소셜 네트워킹 및 회원 관리 기능을 제공
3. 취약점
3.1 CVE-2024-56042 [2][3]
- WPLMS에서 발생하는 SQL Injection 취약점 (CVSS: 9.3)
영향받는 버전 : WPLMS < 1.9.9.5.3
- includes/vibe-course-module/includes/api/v3/class-api-commissions.php의 get_instructor_commissions_chart()에 취약점 존재 > json/wplms/v1/commissions/instructor/<ID>/chart의 REST 엔드포인트를 처리 > REST 엔드포인트 자체에서는 commissions_request_validate()를 통해 사용자 권한을 확인
> Line4 및 Line7 : 클라이언트 요청에서 course_id와 currency 파라미터를 추출 및 $course_id와 $currency에 할당 > Line16 ~ Line24 : $course_id와 $currency를 .=(문자열 연결 연산자) 연사자를 사용해 $and_where에 할당 > Line29 ~ Line40 : get_results()를 사용해 SQL 쿼리를 실행한 후 결과를 $results에 할당
- $course_id와 $currency에 대한 적절한 검증 없이 $and_where에 포함되어 SQL 쿼리에 사용되므로, 유효한 ID를 가진 공격자에 의해 SQL Injection 취약점이 발생
includes/vibe-course-module/includes/api/v3/class-api-commissions.php, function get_instructor_commissions_chart()
1 function get_instructor_commissions_chart($request){
2
3 $user_id = $request->get_param('id');
4 $course_id =$request->get_param('course_id');
5 $date_start = $request->get_param('date_start');
6 $date_end = $request->get_param('date_end');
7 $currency = $request->get_param('currency');
8 ------------ CUT HERE ------------
9
10 $and_where = '';
11 $start_date = '';
12 $end_date = '';
13 $group_by = ' GROUP BY select_parameter';
14 $select = 'MONTH(activity.date_recorded) as select_parameter';
15
16 if(!empty($course_id)){
17 $and_where .= " AND activity.item_id = $course_id ";
18 }else{
19
20 ------------ CUT HERE ------------
21 }
22 if(!empty($currency)) {
23 $and_where .= " AND meta2.meta_value = '".$currency."' ";
24 }
25
26 ------------ CUT HERE ------------
27 global $wpdb;
28 global $bp;
29 $results = $wpdb->get_results( "
30 SELECT ".$select.", sum(meta.meta_value) as commission
31 FROM {$bp->activity->table_name} AS activity
32 LEFT JOIN {$bp->activity->table_name_meta} as meta ON activity.id = meta.activity_id
33 LEFT JOIN {$bp->activity->table_name_meta} as meta2 ON activity.id = meta2.activity_id
34 WHERE activity.component = 'course'
35 AND activity.type = 'course_commission'
36 AND activity.user_id = {$user_id}
37 AND meta.meta_key LIKE '_commission%'
38 AND meta2.meta_key LIKE '_currency%'
39 .$and_where.
40 .$group_by,ARRAY_A);
41 ------------ CUT HERE ------------
42 }
3.2 CVE-2024-56047 [4][5]
- WPLMS에서 발생하는 SQL Injection 취약점
영향받는 버전 : WPLMS < 1.9.9.5.3
- include/vibe-course-module/includes/api/v3/class-api-user-controller.php의 search_users_in_chat()에 취약점 존재 > json/wplms/v2/user/alluser의 REST 엔드포인트를 처리하며, 인증된 모든 사용자가 액세스할 수 있음 > Line3 : 클라이언트로부터 전달받은 user_initials를 추출해 $user_initials에 할당 > Line4 : $user_initials를 포함해 SQL 쿼리 실행 및 결과를 $results에 할당
- user_initials에 대한 적절한 검증 없이 $user_initials에 할당되어 SQL 쿼리에 사용되므로, SQL Injection 취약점이 발생
includes/vibe-course-module/includes/api/v3/class-api-user-controller.php, function search_users_in_chat()
1 function search_users_in_chat($request){
2 global $wpdb;
3 $user_initials = $request->get_param('user_initials');
4 $results = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}users WHERE `user_nicename` LIKE '%{$user_initials}%'", ARRAY_A );
5
6 $return = array('status'=>1,'message'=>'','users'=>array());
7 if(!empty($results)){
8 foreach($results as $result){
9 $return['users'][]=apply_filters('wplms_api_search_users_in_chat',array(
10 'name'=> bp_core_get_user_displayname($result['ID']),
11 'id'=> intval($result['ID']),
12 'image'=> bp_core_fetch_avatar(array('item_id' => $result['ID'],'type'=>'thumb', 'html' => false)),
13 'type'=> (user_can(intval($result['ID']),'manage_options')?_x('Administrator','Chat search result user type','wplms'):(user_can($result['ID'],'edit_posts')?_x('Instructor','Chat search result user type','wplms'):_x('Student','Chat search result user type','wplms')))
14 ));
15 }
16 }else{
17 $return = array('status'=> 0,'message'=>_x('No user found !','Chat search result','wplms'),'users'=>array());
18 }
19
20 }
3.3 CVE-2024-56039 [6][7]
- VibeBP에서 발생하는 SQL Injection 취약점(CVSS: 9.3)
영향받는 버전 : VibeBP < 1.9.9.7.7
- include/buddypress/class-api-settings-controller.php의 get_avatar()에 취약점 존재 > json/vbp/v1/avatar의 REST 엔드포인트를 처리 > REST 엔드포인트 자체에서는 commissions_request_validate()를 통해 사용자 권한을 확인
> Line3 ~ Line4 : 클라이언트로부터 전달받은 요청의 Body를 JSON으로 디코딩 및 재귀적으로 필터링한 후 $body에 할당 > Line33 : $body['ids']['item_id']를 포함해 SQL 쿼리 실행 및 결과를 $name에 할당
- $body 값에 대한 적절한 검증 없이 get_var()에 포함되어 SQL 쿼리에 사용되므로, SQL Injection 취약점이 발생
- include/buddypress/class-api-messages-controller.php의 remove_message_label()에 취약점 존재 > json/vbp/v1/messages/label/remove의 REST 엔드포인트를 처리
> Line2 ~ Line3 : 클라이언트로부터 전달받은 요청의 Body를 JSON으로 디코딩 및 재귀적으로 필터링한 후 $body에 할당 > Line14 및 Line16 : $body['slug']를 $slug에 할당한 후 이를 포함해 SQL 쿼리 실행 및 결과를 $labels_count에 할당
- $slug 값에 대한 적절한 검증 없이 get_results()에 포함되어 SQL 쿼리에 사용되므로, SQL Injection 취약점이 발생
※ Learning Management System : 학습 관리 시스템, 온라인으로 학생들의 학습을 관리할 수 있게 해주는 소프트웨어
2. VibeBP (Vibe BuddyPress Plugin)
- WPLMS와 함께 사용되는 플러그인으로, 강력한 소셜 네트워킹 및 회원 관리 기능을 제공
3. 취약점
3.1 CVE-2024-56043 [2][3]
- WPLMS의 잘못된 권한 할당으로 인한 권한 상승 취약점 (CVSS: 9.8)
영향받는 버전 : WPLMS <= 1.9.9
- includes/vibe-shortcodes/ajaxcalls.php의 wplms_register_user()에 취약점 존재
> wp_ajax_nopriv_wplms_register_user()에 의해 호출되어, 사용자 등록(≒ 회원가입)을 처리하는 함수 > Line7 : 사용자 입력인 $_POST['settings'] 값을 JSON으로 디코딩하여 $settings에 할당 > Line59 ~ Line62 : $setting 객체의 id 값을 확인해 default_role인 경우 $setting 객체의 value 값을 $user_args['role']에 할당 > Line100 : wp_insert_user($user_args)를 사용해 새로운 사용자 생성
※ WordPress의 default_role은 6가지의 값을 가짐 : Super Admin, Administrator, Editor, Author, Contributor, Subscriber [4]
- 사용자 입력으로 전달된 default_role에 대한 검증 없이 user_args['role']에 할당되므로, 임의의 역할을 지정해 권한을 상승(Super Admin, Administrator)할 수 있음
- include/vibe-customtypes/includes/musettings.php의 update_license_key()에 취약점 존재 > Line2 ~ Line5 : 해당 요청이 WordPress 내에서 생성된 유효한 요청인지 확인 > Line6 ~ Line9 : $_POST['addon'] 및 $_POST['key'] 값이 비어있지 않은지 확인 > Line10 : $_POST['addon'] 및 $_POST['key'] 값을 사용해 옵션 값 업데이트
- 각 값에 대한 검증이 누락되어, 권한을 확대할 수 있음 > wp_verify_nonce()에 사용되는 nonce 값은 인증된 사용자의 경우 누구나 검증 우회 가능 > $_POST['addon'] 및 $_POST['key'] 값이 비어있는지만 검증 하므로 임의의 값을 전달할 수 있음 > $_POST['addon'] 및 $_POST['key'] 값을 사용해 원하는 만큼 검증 없이 옵션 값 업데이트 가능
- includes/class.ajax.php의 vibebp_register_user()에 취약점 존재 > wp_ajax_nopriv_wplms_register_user()에 의해 호출되어, 사용자 등록(≒ 회원가입)을 처리하는 함수 > Line7 : 사용자 입력인 $_POST['settings'] 값을 JSON으로 디코딩하여 $settings에 할당 > Line60 ~ Line63 : $setting 객체의 id 값을 확인해 default_role인 경우 $setting 객체의 value 값을 $user_args['role']에 할당 > Line138 : wp_insert_user($user_args)를 사용해 새로운 사용자 생성
- 사용자 입력으로 전달된 default_role에 대한 검증 없이 user_args['role']에 할당되므로, 임의의 역할을 지정해 권한을 상승(Super Admin, Administrator)할 수 있음
※ Learning Management System : 학습 관리 시스템, 온라인으로 학생들의 학습을 관리할 수 있게 해주는 소프트웨어
2. 취약점
2.1 CVE-2024-56046 [2][3]
- WPLMS에서 발생하는 파일 업로드 취약점 (CVSS: 10.0)
영향받는 버전 : WPLMS <= 1.9.9
- includes/vibe-shortcodes/shortcodes.php의 wplms_form_uploader_plupload()에 취약점 존재 > Line9 : $_REQUEST["name"] 값을 우선적으로 $fileName에 할당하며, 해당 값이 없을 경우 $_FILES["file"]["name"] 값을 사용 > Line17 : $fileName은 파일 저장 경로를 결정하는데 사용됨
- name 파라미터는 사용자 요청으로부터 추출 (Line9) > 해당 값에 대한 검증 없이 사용하여 악의적인 파일(Ex. "../../../attack.php")을 사용해 파일을 업로드할 수 있음
- $fileName을 기반으로 서버의 특정 경로에 저장 > 해당 값에 대한 검증이 없어 임의 디렉터리에 악의적인 파일을 업로드할 수 있음
- includes/vibe-shortcodes/upload_handler.php의 wp_ajax_zip_upload()에 취약점 존재 > Line4 ~ Line8 : 사용자 요청에서 값을 추출해 변수 할당 > Line18 ~ Line19 : Zip 파일 내 다른 파일이 있는 경우 extractZip()을 통해 파일 내 모든 내용을 추출 > 사용자 요청에서 추출한 값을 검증없이 사용하여 취약점 발생
- extractZip() > Line6 : extractTo()를 사용해 Zip 파일내 모든 파일을 $target 디렉터리에 추출 > 파일에 대한 검증없이 추출되어 취약점 발생 > attack.php 등의 악의적 파일을 포함한 Zip 파일을 업로드할 수 있는 문제 발생
- includes/assignments/assignments.php의 wplms_assignment_plupload()에 취약점 존재 > Line2 ~ Line4 : WordPress 내에서 생성된 요청인지와 로그인 유무를 검증 > Line18 : $user_id 및 $assignment_id를 기반으로 $folderPath 생성
- $assignment_id에 대한 유효성 검증이 없어 임의 디렉터리에 악의적인 파일을 업로드할 수 있음