Journey to Security/웹 보안

[SQLi] 취약한 실습용 웹 애플리케이션 만들기 (Claude AI 이용)

보눔비스타 2026. 5. 16. 10:51

SQL 인젝션 실습을 위해 Claude AI를 이용해서 다음과 같이 전체 실습 환경을 구성했다.

Windows 10/11 (호스트)
└── VMware Workstation
    └── Rocky Linux 9 (192.168.100.25)
        └── Docker Engine
            └── sqli_net (bridge network)
                ├── sqli_web (PHP 8.2 + Apache 2.4) :8080
                └── sqli_db  (MySQL 8.0)             :3306 내부전용

1. 하이퍼바이저 — VMware Workstation

보안 실습의 첫 번째 원칙은 격리다.

아무리 실습용이라도 취약한 코드를 실서버나 로컬 머신에 직접 올리는 것은 권장되지 않으므로 가상머신에서 실습을 진행한다.

 

먼저 프로젝트를 올릴 가상머신을 다음과 같이 구성한다.

 

🟢 VM 웹서버 네트워크 구성 정보 (예시)

VM Name : Rocky-sqli-lab

VMware Network : VMnet8

Host Name : www.example.com 

IP address : 192.168.100.25/24

Default gateway : 192.168.100.2

DNS Servers : 168.126.63.1, 168.126.63.2

📌 VMware에서 네트워크 설정하는 방법은 아래 포스팅에 자세히 정리되어 있다. 

https://nanujahope.tistory.com/318

 

2. 컨테이너 — Docker + Docker Compose

환경 재현성과 빠른 초기화의 장점 외에도 웹 서버(sqli_web)와 DB(sqli_db)가 별도 컨테이너로 분리되어 컨테이너 간 통신은 Docker 내부 DNS(db:3306)를 통해 이루어지고, MySQL 포트는 외부에 노출하지 않기 때문에 더 안전한 실습이 가능하다.

🔵 Docker 환경 구성

sqli-lab/
├── docker-compose.yml       # PHP + MySQL 컨테이너 정의
├── Dockerfile               # PHP 8.x + Apache 이미지
├── setup/
│   ├── db_init.sql          # DB 초기화 (자동 실행)
│   └── db_connect.php
├── vuln/
│   ├── login_vuln.php
│   ├── search_vuln.php
│   └── blind_vuln.php
├── patch/
│   ├── login_safe.php
│   └── search_safe.php
└── index.html

 

MySQL 컨테이너가 뜰 때 db_init.sql을 자동으로 실행하도록 구성하면 별도 초기화 명령어가 필요 없다.

 

 

MySQL 포트 3306은 외부에 노출되지 않는다.

docker-compose.yml에서 db 서비스에 ports 를 명시하지 않았기 때문에 sqli_net 내부에서만 접근 가능하고, web 컨테이너가 db:3306 으로만 통신한다.

 

3. 언어 — PHP 8.2

보안 실습에 PHP를 선택하는 이유는 단순히 옛날 언어라서 취약해서가 아니다.

취약점이 최소한의 코드로 표현된다.

SQL Injection 취약점을 만드는 데 PHP는 단 세 줄이면 충분하다.

php
$id = $_GET['id'];
$query = "SELECT * FROM users WHERE id = $id";
mysqli_query($conn, $query);

 

Java(Spring)나 Python(Django) 같은 프레임워크 기반 언어로 동일한 실습 환경을 구성하려면 레이어 구조와 설정 파일을 이해하는 데 먼저 시간을 써야 한다.

PHP는 요청 수신 → 쿼리 실행 → 응답 출력이 파일 하나에서 일어나기 때문에 취약점의 흐름을 한눈에 추적할 수 있다.

또한 보안 업계에서 널리 쓰이는 DVWA, Mutillidae, bWAPP이 모두 PHP로 만들어져 있고, 수많은 CTF 문제와 실전 머신도 PHP 환경 비중이 높다. PHP로 취약점 원리를 체득해두면 이 자료들을 활용할 때 언어 장벽이 없다.

PHP로 SQL Injection 원리를 이해하고 나면 Python, Node.js, Java 어디서든 같은 패턴을 즉시 알아볼 수 있다.

 
python
# Python에서도 구조는 동일
cursor.execute("SELECT * FROM users WHERE id=" + id)

# Node.js에서도 마찬가지
db.query("SELECT * FROM users WHERE id=" + req.query.id)

 

이후 Python(Flask), Node.js(Express) 환경으로 실습을 확장할 예정이고, PHP에서 쌓은 개념이 그대로 이어진다.

 

4. DBMS — MySQL 8.0

SQL Injection 실습에서 사용하는 UNION SELECT, SLEEP(), INFORMATION_SCHEMA 기반 공격 기법이 MySQL 환경에서 가장 잘 문서화되어 있고, sqlmap 같은 자동화 도구도 MySQL을 기준으로 기본 동작하기 때문에 MySQL을 사용하기로 한다.

 

5. 환경 세팅

클로드에게 요청하면 yml 파일과 Dockerfile을 포함한 프로젝트 소스 파일을 작성해서 zip 파일로 업로드를 해준다.

sqli-lab-docker.zip
├── docker-compose.yml   ← 컨테이너 구성 설정
├── Dockerfile           ← 이미지 빌드 명세서
├── setup/
├── vuln/
└── patch/

 

이 zip 파일을 받아서 VM 리눅스로 옮긴다.

PS C:\Users\windowuser\Desktop> scp sqli-lab-docker.zip ~linuxuser@192.168.100.25:

 

리눅스에서 빌드하면 도커 이미지가 만들어지고 컨테이너가 뜬다.

# 1. 압축 해제
unzip sqli-lab-docker.zip
cd sqli-lab-docker

# 2. 컨테이너 빌드 및 실행
docker compose up -d --build

# 3. 상태 확인 (두 컨테이너 모두 Up 이어야 함)
docker compose ps

 

외부(호스트 OS) 클라이언트에서 접속이 잘 되는지 확인한다.

http://192.168.100.25:8080/