sqlmap

RYEONGO KIM·2026년 2월 23일

kali linux

목록 보기
4/6

sqlmap이란 무엇인가요?

sqlmap은 웹 애플리케이션의 데이터베이스 취약점을 찾아내고, 이를 이용해 데이터를 탈취하거나 서버를 제어할 수 있게 도와주는 오픈 소스 모의 해킹 도구입니다.

주요 특징
자동화: 사람이 일일이 쿼리를 입력할 필요 없이, 도구가 알아서 취약한 파라미터를 찾고 데이터를 뽑아냅니다.

다양한 DB 지원: MySQL, Oracle, PostgreSQL, Microsoft SQL Server 등 거의 모든 데이터베이스를 지원합니다.

강력한 기능: 단순히 데이터를 보는 것을 넘어, DB 사용자의 비밀번호를 해시로 추출하거나 특정 상황에서는 서버의 쉘(Shell)까지 획득할 수 있습니다.

SQL 인젝션(SQL Injection)의 원리

sqlmap을 잘 쓰려면 공격 원리를 먼저 이해해야 합니다.

취약점 발생: 웹사이트가 사용자의 입력값(예: 아이디, 검색어)을 검증하지 않고 그대로 DB 쿼리에 포함시킬 때 발생합니다.

악성 코드 삽입: 공격자가 입력창에 ' OR '1'='1 같은 특수 쿼리를 넣습니다.

데이터 탈취: 서버는 이 입력을 명령어로 착각하여, 원래는 보여주면 안 될 회원 정보나 관리자 계정 등을 화면에 띄워버립니다.

sqlmap 사용법 (Kali Linux)

공격

kali 터미널에서 아래와 같은 단계로 실습을 진행합니다.

취약한 PHP 파일 (view.php)
Red Hat 서버의 /usr/share/nginx/html/view.php

<?php
// 1. MySQL 서버(22번) 연결 설정
$servername = "192.168.200.22";
$username = "root";       // 데이터베이스 접속 아이디
$password = "1234";       // 데이터베이스 접속 비밀번호
$dbname = "test_db";      // 접속할 데이터베이스 이름

$conn = new mysqli($servername, $username, $password, $dbname);

// 연결 확인
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

// 2. 외부로부터 id 파라미터 수신
$id = $_GET['id'];

// 3. SQL Injection에 취약한 쿼리문 (입력값 검증 없음)
$sql = "SELECT username, email FROM users WHERE id = $id";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
    while($row = $result->fetch_assoc()) {
        echo "<h1>User Info</h1>";
        echo "Name: " . $row["username"]. "<br>";
        echo "Email: " . $row["email"]. "<br>";
    }
} else {
    echo "0 results";
}
$conn->close();
?>

실습하기위해서 데이터베이스를 하나 만든다.

보안이 강화되어서 비번이 4자리로 안만들어져서 만들게 했다.

사용자생성과 권한부여를 한다

에러 메시지인 Permission denied는 PHP가 데이터베이스에 접속하려고 할 때, 리눅스의 강력한 보안 시스템인 SELinux가 막고 있기 때문에 발생하는 현상입니다.

Permission denied가 뜨는 이유
SELinux의 철벽 방어: Red Hat 계열 리눅스는 보안을 위해 웹 서버(Nginx)가 외부 네트워크(MySQL 포트 등)로 나가는 것을 기본적으로 차단합니다.

결과: PHP 코드는 완벽해도 시스템이 통로를 막고 있으니 500 Internal Server Error가 발생하고, sqlmap도 데이터를 가져오지 못하는 것입니다.

sudo setsebool -P httpd_can_network_connect_db 1
이 코드를 통해 웹 서비스가 데이터베이스에 연결할 수 있도록 허용

데이터 출력 확인 : curl http://192.168.200.23/view.php?id=1

sqlmap 실행 : sqlmap -u "http://192.168.200.23/view.php?id=1" --dbs --batch

  1. 취약점 탐지 결과 (Injection Points)
    가장 중요한 부분은 sqlmap이 찾아낸 "어떤 방식으로 공격이 가능한가"에 대한 요약입니다.
    의미: id라는 파라미터가 3가지 방식(참/거짓 판단, 시간 지연, 쿼리 합치기)으로 모두 공격 가능하다는 뜻입니다. 특히 UNION query가 가능하다는 것은 데이터를 아주 빠르고 정확하게 추출할 수 있다는 신호입니다.

  2. 공격 페이로드 (Payload)
    sqlmap이 실제로 서버에 날린 '공격용 명령어'입니다. 해커가 수동으로 공격할 때 사용하는 코드이기도 합니다.의미: 기존 쿼리에 내가 원하는 쿼리(SELECT)를 합쳐서(UNION) 서버가 원하지 않는 데이터를 강제로 출력하게 만드는 코드입니다. 뒤에 붙은 NULL-- -는 쿼리의 형식을 맞추고 뒷부분을 주석 처리하여 에러를 방지하는 중요한 트릭입니다.

  3. 최종 탈취 데이터 (Available Databases)
    이번 공격의 최종 목적인 데이터베이스 목록입니다.의미: 서버에 3개의 데이터베이스가 있고, 그중 우리가 목표로 삼은 test_db가 성공적으로 노출되었습니다. 이제 이 이름을 이용해 다음 단계인 '테이블 털기'로 넘어갈 수 있습니다.

test_db 안의 테이블 털기
이제 데이터베이스 이름을 알았으니, 그 안에 어떤 표(Table)들이 있는지 확인해야 합니다.
sqlmap -u "http://192.168.200.23/view.php?id=1" -D test_db --tables --batch

users 테이블의 데이터 훔쳐오기 (Dump)
테이블 이름까지 알아냈으니, 이제 그 안에 실제로 어떤 값들이 들어있는지 전부 뽑아올 차례입니다. 이번에는 --dump 옵션을 사용하여 테이블의 모든 내용을 화면에 출력한다.
sqlmap -u "http://192.168.200.23/view.php?id=1" -D test_db -T users --dump --batch

방어

view.php의 코드 변경 전
view.php의 코드 변경 후
방어 결과

보안 패치 성공의 증거 (분석)
이미지에서 가장 중요한 부분은 바로 이 빨간색 [CRITICAL] 메시지입니다.

GET parameter 'id' does not seem to be injectable: id 파라미터가 더 이상 공격에 반응하지 않는다는 뜻입니다.

all tested parameters do not appear to be injectable: sqlmap이 가진 모든 공격 기술을 다 동원해봤지만, 틈을 찾지 못하고 결국 포기했다는 의미입니다.

Prepared Statement 코드가 다음과 같이 공격을 막아냈기 때문입니다

공격 코드 무력화: 이전에는 1 UNION SELECT... 같은 글자가 SQL 명령어로 실행되었지만, 이제는 DB가 이를 단순한 '글자 뭉치'나 '잘못된 숫자'로만 인식합니다.

데이터 타입 강제: bind_param("i", $id) 코드가 오직 숫자(Integer)만 허용하도록 문을 좁혔기 때문에, sqlmap이 던지는 복잡한 공격 구문들이 입구에서 컷(Cut)당한 것입니다.

결론

공격: 취약점을 이용해 데이터베이스 목록과 사용자 정보를 탈취해봄.

방어: Prepared Statement를 적용해 sqlmap 같은 전문 도구도 뚫지 못하게 구멍을 메움.

profile
배우는 중 입니다.

0개의 댓글