뭉크테크
Blind SQL Injection 모의해킹 본문
목차
- Blind SQL Injection 이론
- Blind SQL Injection 실습
- Blind SQL Injection 대응방안
Blind SQL Injection 이론
- 쿼리의 결과를 참 또는 거짓으로만 출력하는 페이지에서 사용할 수 있는 SQL Injection 공격 기법
- 출력 내용이 참 또는 거짓으로만 구성된 웹 페이지에서 참/거짓 정보를 이용해 데이터베이스의 내용을 추측하는 공격 방식
- Brute Force 공격과 비슷하게 상당히 많은 경우의 수를 대입해보며 공격을 수행해야 하기 때문에 일반적으로 자동화 도구를 이용하여 공격을 수행한다.
Blind SQL Injection 실습
![]() |
![]() |
- Blind SQL Injection 공격을 실습하기 위해 해당 탭으로 들어온 모습
- User ID 입력란에 번호를 입력하면 해당 번호에 사용자 계정의 유무를 판단해주는 기능이 있으며,
- 해당 번호에 사용자가 존재하는 경우, 좌측 사진과 같이 User ID exists in the database. 라는 문구를 출력해주는 것을 확인할 수 있고, 사용자 계정이 존재하지 않는 번호를 조회할 경우 우측 사진과 같이 User ID is MISSING from the database. 라는 문구를 출력하는 것을 확인할 수 있다.

- 이전과 같은 방식(Error based SQL Injection)을 시도하였지만, T/F 결과값만을 보여준다.
- 따라서 그에 맞는 시나리오를 다시 세운다.
- DB 명(스키마) 길이 확인
- DB 명(스키마) 문자열 확인
- Table 이름(스키마) 문자열 확인
- Table을 이용하여 특정 계정 id 및 password 값 확인
- 해당 값으로 계정 로그인 시도

- 비슷하게 1' and length(database()) = 질의문을 이용하여 DB의 이름 길이를 알아낼 수 있습니다. 위 사진에서 보듯이 1, 2, 3 값을 입력했을 때는 오류가 나타나지만 4 값을 입력했을 때는 참 값을 출력하는 것으로보아 DB의 이름의 길이는 4글자이다.
- 이제 데이터베이스의 이름 길이를 알아냈으니, 데이터베이스의 이름을 알아내기 위해 모든 알파벳을 대입해 보는 방식으로 데이터베이스의 이름을 알아낼 수 있다.
- 하지만 수작업으로 이 모든 과정을 처리한다면 막대한 시간이 소요되기 때문에, 이후 실습은 자동화 프로그램(SQLmap)을 사용하도록 한다.


- 먼저 버프스위트의 http history에 들어가서 지금 사용하던 웹 애플리케이션의 쿠키값을 추출한다.
- 그리고 터미널에서 쿠키값을 이용하여 SQLmap을 작동시킨다. 명령어는 다음과 같다.
- sqlmap -u "http://localhost/DVWA/vulnerabilities/sqli_blind/?id=1&Submit=Submit" --cookie="쿠키값" --current-db
- 최근한 사용한 db를 조회하도록 옵션값을 설정해주었다.
- dvwa라는 데이터베이스에 접근할 수 있다는 것을 확인하였다

- 알아낸 데이터베이스 이름을 기반으로 SQLMAP을 이용하여 데이터베이스에 있는 테이블들을 --tables 옵션을 사용하여 알아내는 공격을 수행한 결과이다.
- dvwa 라는 이름의 데이터베이스에는 guestbook 이라는 테이블과 users 라는 이름의 테이블이 존재하는 것을 확인할 수 있다.

- 이 중 users 라는 테이블에 모든 사용자의 계정 정보와 패스워드 정보가 있을 확률이 높을 것으로 예상되어 users 라는 테이블을 좀 더 상세하게 살펴보기로 하였다

- 알아낸 데이터베이스 이름과 테이블 정보를 기반으로 users 테이블의 모든 항목을 덤프한 결과이다.
- 우측 사진에 보이는 것과 같이 users 테이블에 있는 모든 정보들이 출력되는 모습을 확인할 수 있다.
- 이 중 password 라는 이름의 Columns 에 있는 정보들은 MD5 해시 값으로 저장되어 있는 것을 확인할 수 있는데 해당 정보는 복호화하여 우측에 표시 해주는 것도 확인할 수 있다.

- 이전 users 테이블에 있는 정보에서 pablo 라는 사용자 계정과 패스워드를 이용해 DVWA 웹 페이지에서 로그인한 결과 계정 탈취에 성공하여 로그인에 성공한 모습을 확인할 수 있었다
Blind SQL Injection 대응방안
Prepared statement 구문
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;
public class LoginExample {
public static void main(String[] args) {
// 데이터베이스 연결 정보
String url = "jdbc:mysql://localhost:3306/mydatabase";
String dbUsername = "root";
String dbPassword = "password";
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
Scanner scanner = new Scanner(System.in);
try {
// 사용자로부터 로그인 정보 입력받기
System.out.print("Enter username: ");
String username = scanner.nextLine();
System.out.print("Enter password: ");
String password = scanner.nextLine();
// Step 1: 데이터베이스 연결
connection = DriverManager.getConnection(url, dbUsername, dbPassword);
// Step 2: Prepared Statement로 SQL 쿼리 작성
String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
preparedStatement = connection.prepareStatement(sql);
// Step 3: 사용자가 입력한 값 바인딩
preparedStatement.setString(1, username); // 첫 번째 '?'에 username 바인딩
preparedStatement.setString(2, password); // 두 번째 '?'에 password 바인딩
// Step 4: 쿼리 실행 및 결과 처리
resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
System.out.println("Login successful! Welcome, " + username + "!");
} else {
System.out.println("Invalid username or password.");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// Step 5: 리소스 해제
try {
if (resultSet != null) resultSet.close();
if (preparedStatement != null) preparedStatement.close();
if (connection != null) connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
scanner.close();
}
}
}
- 자바 코드 기준으로 Prepared statement 구문을 사용하여 서버에서 반복적으로 사용되는 쿼리 템플릿은 미리 파싱 과정과 메모리 적재하는 과정을 거치고, 사용자에게 입력 받은 값은 Setstring 함수를 이용하여 문자열로 취급한 뒤, 방금 미리 저장된 쿼리 템플릿안에 따로 바인딩 처리를 해준다.
- 그러면, 문법 오류를 일으키고자 하는, 공격자의 악의적인 의도를 막을 수 있다.
블랙리스트 활용

- 하지만 여러 이유로 Prepared statement 구문을 사용하여 구현하지 못하는 상황 有
- 그럴 경우 입력된 값이 개발자가 의도한 값인지 검증할 수 있는 로직을 구현하여 불필요한 특수 문자 등은 입력되지 않도록 구현
- 위 예시는 특정 문자가 입력될 경우 자동으로 공백으로 치환하고자할 때 참고하는 필터링 대상 목록

- WAS 설정 파일(위 예시는 php 설정 파일)에서 에러메시지는 출력 되지 않도록 설정해야 한다.
- 웹 방화벽(WAF, Web Application Firewall)을 사용하여 부적절한 요청이 전송될 경우 차단한다.
'CERT' 카테고리의 다른 글
XSS 모의해킹 (0) | 2024.07.28 |
---|---|
Weak Session ids 모의해킹 (0) | 2024.07.28 |
Insecure Captcha 모의해킹 (0) | 2024.07.27 |
File Inclusion 모의해킹 (0) | 2024.07.27 |
BruteForce 모의해킹 (0) | 2024.07.27 |