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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
RTSPServer-Code-Execution-Vulnerability — RTSPServer 코드 실행 취약점 CVE-2018-4013 | Kitploit
도구/GitHubGitHub/r3dxpl0it/rtspserver-code-execution-vulnerability
Vulnerability AnalysisExploitationWeb SecurityFuzzingLearning & EducationBinary Exploitation
GitHubr3dxpl0it/rtspserver-code-execution-vulnerability

RTSPServer-Code-Execution-Vulnerability

RTSPServer 코드 실행 취약점 CVE-2018-4013

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
저장소 보기
1537년 전아직 검토되지 않음

Live Networks LIVE555 스트리밍 미디어 RTSPServer lookForHeader 코드 실행 취약점

CVE-2018-4013

요약

LIVE555 RTSP 서버 라이브러리의 HTTP 패킷 구문 분석 기능에 악용 가능한 코드 실행 취약점이 존재합니다. 특수하게 조작된 패킷은 스택 기반 버퍼 오버플로를 유발하여 코드 실행으로 이어질 수 있습니다. 공격자는 패킷을 전송하여 이 취약점을 트리거할 수 있습니다.

세부 정보

LIVE555 미디어 라이브러리는 RTSP/RTCP/RTSP/SIP용의 가벼운 멀티미디어 스트리밍 라이브러리 모음으로, 서버와 클라이언트 모두를 위한 코드를 지원합니다. VLC 및 MPlayer와 같은 인기 있는 미디어 플레이어와 수많은 임베디드 장치(주로 카메라)에서 사용됩니다. 이 취약점은 이러한 미디어 플레이어와 상호 작용하는 서버 구성 요소에 있으며 미디어 플레이어에는 영향을 미치지 않습니다.

LIVE555가 표준 RTSP 서버에 제공하는 기능 중 하나는 RTSP를 HTTP 위에서 터널링하는 기능입니다. 이는 서버가 바인딩하는 별도의 포트(일반적으로 호스트 머신에서 사용 가능한 포트에 따라 TCP 80, 8000 또는 8080)에서 제공됩니다. 이 포트는 일반 RTSP를 지원할 수 있지만, 특정 경우 HTTP 클라이언트가 RTSP-over-HTTP 터널을 협상할 수 있습니다. 이 기능을 처리하는 코드는 다음과 같습니다:

root@kitploit:~
  // liveMedia/RTSPServer.cpp:607
  void RTSPServer::RTSPClientConnection::handleRequestBytes(int newBytesRead) {
  [...]
      // The request was not (valid) RTSP, but check for a special case: HTTP commands 
      // (for setting up RTSP-over-HTTP tunneling):
     char sessionCookie[RTSP_PARAM_STRING_MAX];  //[1]
     char acceptStr[RTSP_PARAM_STRING_MAX];          //[2]
            *fLastCRLF = '\0'; // temporarily, for parsing
            parseSucceeded = parseHTTPRequestString(cmdName, sizeof cmdName,
                        urlSuffix, sizeof urlPreSuffix,
                        sessionCookie, sizeof sessionCookie,
                        acceptStr, sizeof acceptStr);                        //[3]

위 [3]에서 볼 수 있듯이, “Accept” 및 “x-sessioncookie” HTTP 헤더가 RTSP-over-HTTP 터널 여부를 결정합니다. 따라서 입력 바이트에서 매개변수를 스택의 sessionCookie [1] 및 acceptStr [2] 버퍼(둘 다 크기 200)로 읽어들인 후 아래에서 추가로 구문 분석합니다.

코드 경로는 parseHTTPRequestString 함수로 이어집니다:

root@kitploit:~
  Boolean RTSPServer:: RTSPClientConnection::parseHTTPRequestString(char*     resultCmdName, unsigned resultCmdNameMaxSize,
  char* eurlSuffix, unsigned urlSuffixMaxSize,
  char* sessionCookie, unsigned sessionCookieMaxSize,
  char* acceptStr, unsigned acceptStrMaxSize) { 
  [...]
  lookForHeader("x-sessioncookie", &reqStr[i], reqStrSize-i, sessionCookie,   sessionCookieMaxSize);  // [1]
  lookForHeader("Accept", &reqStr[i], reqStrSize-i, acceptStr, acceptStrMaxSize); //[2]

실제로 주목해야 할 중요한 점은 상위 함수의 char 배열이 1 및 2에서 새 함수로 다시 직접 전달된다는 것입니다. 이는 lookForHeader 함수로 이어집니다:

root@kitploit:~
  static void lookForHeader(char const* headerName, char const* source, unsigned
                            sourceLen, char* resultStr, unsigned resultMaxSize) {
      resultStr[0] = '\0'; // by default, return an empty string
      unsigned headerNameLen = strlen(headerName);
      for (int i = 0; i < (int)(sourceLen-headerNameLen); ++i) {
          if (strncmp(&source[i], headerName, headerNameLen) == 0 && source[i+headerNameLen] == ':') { // [1]
          // We found the header. Skip over any whitespace, then copy the rest of the line to "resultStr":
          for (i += headerNameLen+1; i < (int)sourceLen && (source[i] == ' ' || source[i] == '\t'); ++i) {} 
          for (unsigned j = i; j < sourceLen; ++j) {          // [4]
              if (source[j] == '\r' || source[j] == '\n') { // [2]
              // We've found the end of the line. Copy it to the result (if it will fit):
              if (j-i+1 > resultMaxSize) break;
              char const* resultSource = &source[i];
              char const* resultSourceEnd = &source[j];
              while (resultSource < resultSourceEnd) *resultStr++ = *resultSource++; // [5]
              *resultStr = '\0';
              break; //[3]
              }
          }
          }
      }
  }

가장 바깥쪽 루프는 headerName을 찾을 때까지 입력 바이트를 반복합니다. 이 프로그램의 경우 [1]에서 strncmp로 “Accept:” 및 “x-sessioncookie:”를 계속 찾습니다. 주석에 언급된 대로 다른 루프가 발견된 공백을 건너뛴 다음 [2]에서 예상된 줄바꿈 문자 ‘\r\n’을 찾기 시작합니다. 그 후 프로그램은 복사 크기를 resultMaxSize로 올바르게 제한하며, 이 함수에 대한 두 호출 모두에서 resultMaxSize는 0xc8(200)로 올바르게 설정됩니다.

복사 후 [3]의 break가 실행되는데, 이는 실제로 [4]의 루프만 빠져나가며, 코드가 앞서 언급된 초기 strncmp 루프로 다시 점프하게 됩니다. 따라서 버퍼 내에 또 다른 “Accept:” 또는 “x-sessioncookie:” 문자열이 있으면 복사가 다시 수행되며, [5]의 실제 복사 방식을 살펴보면 초기 포인터(handleRequestBytes 함수의 스택 프레임에 있는 주소를 가리키는)가 계속 증가하고, 주어진 각 복사의 길이는 버퍼 크기로 제한되지만 계속 증가하는 대상 주소에 대해 수행될 수 있는 복사 횟수에는 제한이 없으므로 스택 기반 버퍼 오버플로가 쉽게 트리거될 수 있습니다.

root@kitploit:~
  Crash Output
  ==38574==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fffffffd878 at pc 0x555555aad1fb bp 0x7fffffffced0 sp 0x7fffffffcec8
  WRITE of size 1 at 0x7fffffffd878 thread T0 
  #0 0x555555aad1fa in lookForHeader /root/boop/work_work/triages/live555/live/liveMedia/RTSPServer.cpp:398
  #1 0x555555aad847 in RTSPServer::RTSPClientConnection::parseHTTPRequestString(char*, unsigned int, char*, unsigned int, char*, unsigned int, char*, unsigned int) /root/boop/work_work/triages/live555/live/liveMedia/RTSPServer.cpp:479
  #2 0x555555ab82ac in RTSPServer::RTSPClientConnection::handleRequestBytes(int) /root/boop/work_work/triages/live555/live/liveMedia/RTSPServer.cpp:828
  #3 0x555555aa9c17 in GenericMediaServer::ClientConnection::incomingRequestHandler() /root/boop/work_work/triages/live555/live/liveMedia/GenericMediaServer.cpp:246
  #4 0x555555e0063b in BasicTaskScheduler::SingleStep(unsigned int) /root/boop/work_work/triages/live555/live/BasicUsageEnvironment/BasicTaskScheduler.cpp:153
  #5 0x555555e12c75 in BasicTaskScheduler0::doEventLoop(char volatile*) /root/boop/work_work/triages/live555/live/BasicUsageEnvironment/BasicTaskScheduler0.cpp:80
  #6 0x555555a9452c in main /root/boop/work_work/triages/live555/live/mediaServer/live555MediaServer.cpp:89
  #7 0x7ffff550b2b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
  #8 0x555555a978e9 in _start (/root/boop/work_work/triages/live555/live555MediaServer+0x5438e9)

  Address 0x7fffffffd878 is located in stack of thread T0 at offset 2024 in frame
  #0 0x555555ab6b9f in RTSPServer::RTSPClientConnection::handleRequestBytes(int) /root/boop/work_work/triages/live555/live/liveMedia/RTSPServer.cpp:607

  This frame has 12 object(s):
  [32, 33) 'reuseConnection'
  [96, 97) 'deliverViaTCP'
  [160, 164) 'contentLength'
  [224, 232) 'proxyURLSuffix'
  [288, 488) 'cmdName'
  [544, 744) 'urlPreSuffix'
  [800, 1000) 'urlSuffix'
  [1056, 1256) 'cseq'
  [1312, 1512) 'sessionIdStr'
  [1568, 1768) 'sessionCookie'
  [1824, 2024) 'acceptStr' <== Memory access at offset 2024 overflows this variable
  [2080, 2480) 'urlTotalSuffix'
  HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
  (longjmp and C++ exceptions *are* supported)
  SUMMARY: AddressSanitizer: stack-buffer-overflow /root/boop/work_work/triages/live555/live/liveMedia/RTSPServer.cpp:398 in lookForHeader
  Shadow bytes around the buggy address:
  0x10007fff7ab0: f4 f4 f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00
  0x10007fff7ac0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f4
  0x10007fff7ad0: f4 f4 f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00
  0x10007fff7ae0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f4
  0x10007fff7af0: f4 f4 f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00
  =>0x10007fff7b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00[f4]
  0x10007fff7b10: f4 f4 f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00
  0x10007fff7b20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007fff7b30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007fff7b40: 00 00 00 00 00 00 00 00 f4 f4 f3 f3 f3 f3 00 00
  0x10007fff7b50: 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00

크레딧

Cisco Talos의 Lilith ¯_(ツ)_/¯가 발견했습니다.

도구 다운로드