오늘은 펜테스터들이 가장 사랑하면서도, 관리자들에게는 가장 두려운 도구인 sqlmap에 대해 깊이 있게 알아보겠습니다.
sqlmap은 "자동화된 SQL 인젝션 공격 도구의 제왕"입니다.
단순히 취약점만 찾는 게 아니라, 데이터베이스(DB)를 통째로 털거나(Dump), 심지어 DB 서버의 셸(Shell)까지 획득하여 시스템을 장악할 수 있습니다.
이번 글에서는 기본 사용법부터, WAF(웹 방화벽) 우회 기법, 그리고 대망의 시스템 장악(--os-shell)까지 전문가 레벨의 기술을 다룹니다.
"SQL 인젝션이 있는 것 같은데, 수동으로 쿼리 짜기가 너무 힘들어요."
이런 고민을 단숨에 해결해 주는 도구가 바로 sqlmap입니다.
탐지(Detection)부터 익스플로잇(Exploitation)까지 명령어 한 줄이면 충분합니다.
◎ 기본 사용법: "데이터베이스 이름 알아내기"
- 가장 먼저 해야 할 일은 공격 대상이 어떤 DB를 쓰는지, DB 이름은 무엇인지 알아내는 것입니다.
① GET 방식 공격 (-u)
> URL 파라미터(id=1)에 취약점이 있는지 검사합니다.
| # sqlmap -u "http://target.com/view.php?id=1" --dbs |
- -u: 타겟 URL 지정
- --dbs: 접근 가능한 모든 데이터베이스 이름 목록을 가져옵니다 (Database Server).
② POST 방식 공격 (-r)
> 로그인 창이나 검색창 같은 POST 요청은 URL에 파라미터가 보이지 않습니다.
> 이럴 땐 Burp Suite로 요청을 파일로 저장해서 사용하면 편합니다.
- Burp Suite에서 로그인 요청을 잡습니다 (Intercept).
- 요청 내용을 복사해서 request.txt 파일로 저장합니다.
- 아래 명령어를 실행합니다.
| # sqlmap -r request.txt -p username --dbs |
- -r: 저장된 요청 파일을 읽어서 공격합니다.
- -p username: username 파라미터만 집중적으로 공격하라고 지정합니다.
◎ 데이터 탈취: "테이블과 컬럼 털기"
- DB 이름을 알아냈다면, 이제 그 안의 데이터를 가져올 차례입니다. 단계별로 파고들어 갑니다.
① 테이블(Table) 목록 보기 (-D, --tables)
> ServiceDB라는 데이터베이스를 찾았다고 가정해 봅시다.
| # sqlmap -u "http://target.com/view.php?id=1" -D ServiceDB --tables |
② 컬럼(Column) 목록 보기 (-T, --columns)
> Users라는 테이블이 나왔네요. 그 안에 어떤 컬럼이 있는지 봅니다.
| # sqlmap -u "http://target.com/view.php?id=1" -D ServiceDB -T Users --columns |
③ 데이터 덤프(Dump) (-C, --dump)
> id, pw, email 컬럼이 보입니다. 이제 내용을 다 긁어옵니다.
| # sqlmap -u "http://target.com/view.php?id=1" \ -D ServiceDB -T Users -C "id,pw,email" --dump |
- --dump: 데이터를 화면에 출력하고 파일(CSV 등)로 저장합니다.
- 만약 비밀번호가 해시(Hash)로 되어있다면, sqlmap이 "이거 해시인데 크랙(복호화) 시도해 볼까?"라고 친절하게 물어봅니다.
◎ WAF 우회 기술 (--tamper)
- 보안 장비(WAF)가 "SELECT"나 "UNION" 같은 단어를 막고 있다면? Tamper Script를 써서 공격 코드를 난독화해야 합니다.
| space2comment: 공백(Space)을 주석(/**/)으로 바꿔서 우회 # sqlmap -u "http://target.com/view.php?id=1" --tamper=space2comment.py |
> 자주 쓰는 스크립트
- space2comment.py: 공백 우회 (가장 흔함)
- between.py: >나 < 기호가 막혔을 때 BETWEEN으로 대체
- charencode.py: URL 인코딩으로 우회
◎ 시스템 셸 획득 (--os-shell)
- 단순히 데이터를 훔치는 것을 넘어, DB 서버의 운영체제(OS)를 장악하고 싶다면 이 옵션을 씁니다. (단, DB 관리자 권한이 필요합니다.)
| # sqlmap -u "http://target.com/view.php?id=1" --os-shell |
- 이 명령어가 성공하면, 터미널에 익숙한 셸 프롬프트가 뜹니다.
- 이제 ls, cat /etc/passwd 같은 리눅스 명령어를 마음대로 실행할 수 있습니다.
> 작동 원리
- sqlmap이 DB의 파일 쓰기 기능(INTO OUTFILE 등)을 이용해 웹 서버에 웹 셸(Web Shell) 파일(예: tmp.php)을 몰래 업로드하고, 그 파일을 통해 명령을 내립니다.
◎ 전문가의 꿀팁 (배치 모드 & 레벨업)
- 실무에서 sqlmap을 돌릴 때 계속 "Y/n" 질문이 나와서 귀찮으셨죠? 그리고 기본 스캔으로는 취약점이 잘 안 잡힐 때가 있습니다.
[추천 명령어 조합]
| # sqlmap -u "http://target.com/view.php?id=1" \ --batch --random-agent --level 3 --risk 2 --dbs |
- --batch: 모든 질문에 기본값(Default)으로 자동 대답합니다. (켜두고 딴짓 가능)
- --random-agent: User-Agent를 랜덤하게 바꿔서 차단을 피합니다.
- --level 3: 기본(1)보다 더 깊게 검사합니다. (헤더, 쿠키까지 검사)
- --risk 2: 조금 더 위험한(무거운) 쿼리도 날려봅니다. (기본 1)
◎ sqlmap의 --level (1~5)과 --risk (1~3) 옵션에 대한 정확한 의미와 차이점 정리
- 이 두 옵션은 "얼마나 꼼꼼하게(Level)" 그리고 "얼마나 위험하게(Risk)" 공격할지를 결정하는 가장 중요한 스위치입니다.
- 무작정 높인다고 좋은 게 아니며, 상황에 맞춰 조절하는 것이 핵심입니다.
① 검사 범위의 깊이: --level (1 ~ 5)
- --level은 "어디까지 찔러볼 것인가?"를 결정합니다.
- 레벨이 높아질수록 검사하는 위치(Injection Point)와 테스트하는 페이로드(Payload)의 양이 늘어납니다.
> Level 1 (기본값)
- GET 및 POST 파라미터만 검사합니다.
- 가장 빠르고 일반적인 검사입니다.
> Level 2
- HTTP Cookie 헤더 값을 검사 대상에 포함합니다.
- 사이트가 쿠키에 SQL 구문을 숨겨놓거나 검증할 때 유효합니다.
> Level 3 (실무 권장)
- HTTP User-Agent 및 Referer 헤더까지 검사합니다.
- 개발자가 로그를 남기기 위해 User-Agent를 DB에 저장하는 경우, 이곳이 취약점이 될 수 있습니다.
> Level 4
- 더 많은 종류의 변형된 페이로드(Payload)를 사용해 우회를 시도합니다.
> Level 5 (최고 레벨)
- HTTP Host 헤더를 포함하여 거의 모든 가능한 입력 지점을 검사합니다.
- 테스트할 페이로드 양이 기하급수적으로 늘어나 스캔 속도가 매우 느려집니다. (기본 대비 1,000개 이상의 요청 추가)
> 요약
- 보통 --level 3까지 설정하면 쿠키와 헤더를 포함한 대부분의 영역을 커버할 수 있어 실무에서 가장 많이 사용됩니다.
② 공격의 위험도: --risk (1 ~ 3)
- --risk는 "얼마나 위험한 쿼리를 날릴 것인가?"를 결정합니다.
- 여기서 '위험'이란 데이터베이스의 데이터가 훼손되거나 서비스가 느려질 가능성을 의미합니다.
> Risk 1 (기본값)
- 가장 안전한 쿼리만 사용합니다.
- 대부분의 SELECT 기반 공격만 수행하며, 데이터 변조 위험이 거의 없습니다.
> Risk 2
- Heavy Time-based SQL Injection 쿼리를 추가합니다.
- SLEEP(10) 같은 명령을 더 많이, 더 길게 보내보므로 서버 응답 속도가 느려지거나 일시적인 부하(DoS)가 걸릴 수 있습니다.
> Risk 3 (매우 위험)
- OR-based SQL Injection 쿼리를 추가합니다.
- 예: OR 1=1 같은 구문을 UPDATE나 DELETE 문에 주입할 경우, WHERE 절이 무력화되어 테이블의 모든 데이터가 수정되거나 삭제될 위험이 있습니다.
- (절대 주의): 운영 중인 서비스(Production)에서는 절대 Risk 3를 사용하면 안 됩니다. 오직 테스트 환경에서만 사용하세요.
> 요약
- 실무 진단 시에는 안전을 위해 Risk 1을 권장하며, 정말 취약점이 안 나올 때 제한적으로 Risk 2를 사용합니다.
- Risk 3는 데이터 파괴 가능성 때문에 금기시됩니다.
③ 실무 추천 조합
일반적인 정밀 진단 (가장 추천)
| --level 3 --risk 1 |
(쿠키/헤더까지 꼼꼼히 보되, 데이터는 안전하게 지킴)
취약점이 있을 것 같은데 안 나올 때
| --level 5 --risk 2 |
(모든 곳을 다 찌르고, 서버 부하를 감수하고라도 찾아내겠다)
이 내용을 참고하여 상황에 맞는 적절한 옵션을 선택하시기 바랍니다. 특히 Risk 3는 반드시 주의해주세요
◎ 파일로 요청 보내기: -r (Request File)
- 실무에서 가장 많이 쓰는 옵션 1위입니다.
- URL이 너무 길거나 복잡한 헤더, 쿠키가 섞여 있을 때 터미널에 다 치기 힘들죠?
> Burp Suite에서 요청 패킷 전체를 복사해서 req.txt 파일로 저장합니다.
> 아래 명령어를 날립니다.
| # sqlmap -r req.txt --dbs |
- sqlmap이 알아서 파일 내용을 분석해 GET, POST, Cookie 파라미터 중 어디가 취약한지 찾아냅니다.
◎ 응답 판별 기준 잡아주기: --string
- "참(True)"일 때와 "거짓(False)"일 때 페이지 내용이 미묘하게 다를 때 씁니다.
- sqlmap이 "이게 성공한 건지 실패한 건지" 헷갈려 할 때 딱 정해주는 옵션입니다.
> 상황: 로그인 성공 시 "Welcome"이 뜨고, 실패 시 안 뜬다면?
> 사용법:
| # sqlmap -u "http://target.com/login.php" --data="id=admin&pw=1234" --string="Welcome" |
- 이제 sqlmap은 응답 페이지에 "Welcome"이라는 글자가 있으면 "참(True)"이라고 확실하게 판단합니다.
◎ 속도 올리기: --threads
- 기본적으로 sqlmap은 한 번에 하나씩 요청을 보냅니다(싱글 스레드). 대량의 데이터를 덤프할 때 속 터지죠.
> 사용법
| # sqlmap -u "http://target.com/list.php?id=1" --dump --threads 10 |
- 최대 10까지 설정 가능합니다. 너무 높이면 서버가 요청을 차단할 수 있으니 5~10 정도가 적당합니다.
◎ POST 데이터 지정: --data
- -r 옵션을 쓰기 귀찮고, 간단한 POST 요청을 보내고 싶을 때 씁니다.
> 사용법
| # sqlmap -u "http://target.com/search" --data="query=apple&category=fruit" |
- 이러면 query와 category 파라미터를 대상으로 POST 인젝션을 시도합니다.
◎ DB 종류 찍어주기: --dbms
- sqlmap은 처음에 "이게 MySQL인가? Oracle인가?" 확인하는 과정을 거칩니다.
- 우리가 이미 타겟이 MySQL인 걸 알고 있다면, 이 과정을 생략하고 바로 공격할 수 있습니다. (속도 향상 + 오탐 방지)
> 사용법
| # sqlmap -u "http://target.com/view.php?id=1" --dbms="MySQL" |
- 지원 값: MySQL, Oracle, PostgreSQL, Microsoft SQL Server 등
◎ 영혼까지 털어가기: --dump-all
- 특정 테이블 하나가 아니라, 접근 가능한 모든 데이터베이스의 모든 테이블, 모든 데이터를 싹 다 가져옵니다.
> 사용법
| # sqlmap -u "http://target.com/view.php?id=1" --dump-all --exclude-sysdbs |
- 주의: 데이터 양에 따라 몇 시간~며칠이 걸릴 수 있습니다.
- 팁: --exclude-sysdbs를 같이 써주세요. 시스템 기본 DB(information_schema 등)까지 털면 시간이 너무 오래 걸리고 쓸모도 없습니다.
◎ 인증 정보 유지: --cookie
- 로그인이 필요한 페이지를 공격하려면 세션 ID(쿠키)를 같이 보내야 합니다.
> 사용법
| # sqlmap -u "http://target.com/mypage.php?id=1" --cookie="PHPSESSID=a1b2c3d4; security=low" |
- 만약 사이트가 로그인 여부를 쿠키로만 체크한다면 이 옵션 하나로 뚫립니다.
◎ 전문가의 One-Liner
- 이 모든 옵션을 조합하면 아래와 같은 강력한 명령어가 됩니다.
> 상황
- 로그인이 필요한(--cookie) 게시판 검색 기능(POST 방식)에서 취약점 발견.
- DB는 MySQL(--dbms)인 걸 알고 있음.
- 성공 시 화면에 "Result Found"(--string)가 뜸.
- 빠르게(--threads) 모든 데이터(--dump-all)를 가져오고 싶음.
> 명령어
| # sqlmap -u "http://target.com/search.php" \ --data="keyword=test&type=title" \ --cookie="JSESSIONID=xyz123" \ --dbms="MySQL" \ --string="Result Found" \ --dump-all --exclude-sysdbs \ --threads 10 --batch |
◎ [요약: 언제 쓸까?]
| 옵션 | 용도 |
| -r | Burp Suite 요청 패킷 파일 그대로 사용 (가장 추천) |
| --data | 간단한 POST 요청 보낼 때 |
| --string | 참/거짓 판단을 못해서 스캔이 헛돌 때 (오탐 방지) |
| --threads | 데이터 덤프 속도가 너무 느릴 때 |
| --dbms | DB 종류를 이미 알고 있을 때 (시간 절약) |
| --cookie | 로그인이 필요한 페이지일 때 |
| --dump-all | DB 전체를 백업하듯 다 가져오고 싶을 때 |
- sqlmap은 옵션을 얼마나 정교하게 주느냐에 따라 성공률이 천지차이입니다.
- "안 되네?" 하고 포기하기 전에 --string이나 --dbms 옵션을 꼭 시도해 보시기 바랍니다.
◎ 윤리적 해킹
- --os-shell이나 --dump는 실제 시스템에 파일(쓰레기 데이터)을 남기거나 민감 정보를 유출하는 행위입니다.
- 반드시 허가된 모의해킹 환경에서만 사용해야 하며, 테스트 후에는 --os-pwn 등으로 생성된 셸 파일을 삭제해 주는 것이 매너입니다.
- sqlmap은 강력한 만큼 책임도 큽니다. 안전하고 합법적인 연구 되시길 바랍니다.
'OFFENSIVE > Vulnerable Web Application' 카테고리의 다른 글
| [WAPT] 웹 애플리케이션 모의해킹 nf(NucleiFuzzer) 가이드 (0) | 2025.12.13 |
|---|---|
| [WAPT] 웹 애플리케이션 모의해킹 Nikto 가이드 (0) | 2025.12.13 |
| [WAPT] 웹 애플리케이션 모의해킹 Wfuzz 가이드 (0) | 2025.12.13 |
| [WAPT] 웹 애플리케이션 모의해킹 Curl 가이드 (0) | 2025.12.13 |
| [WAPT] 웹 애플리케이션 모의해킹 Spyhunt 가이드 (0) | 2025.12.13 |
