2023. 11. 22. 23:21ㆍnormaltic 취업반 5기/내용 정리
SQL 인젝션 (Injection)
SQL 인젝션이란 웹 사이트의 보안 취약점을 이용하여 특정 SQL 쿼리문을 삽입하여 공격자에게 필요한 DB 정보를 추출하거나 인증 우회 등의 공격을 하는 해킹 기법이다. 주로 클라이언트의 입력 값에 대한 필터링 기능이 제대로 갖춰지지 않은 경우 발생한다. SQL 인젝션 공격은 쉬운 난이도에 비해 그 피해는 상당히 효과적인 공격이므로 주의해야 한다.
SQL 인젝션의 공격이 성공하려면 우선적으로 갖춰야 할 조건이 존재한다.
- 웹 애플리케이션이 DB와 연동되어있어야 한다.
- 사용자가 입력한 입력 값이 SQL 구문의 일부로 사용되어야 한다.
공격 이름부터가 DB 언어인 SQL이기 때문에 DB와의 연동이 되어있어야 공격을 진행할 수 있으며 또한 SQL 구문에 사용자가 입력한 입력 값이 사용되어야만 가능하다. 위 두 조건은 현재까지 대부분의 웹 애플리케이션에서 충족하고 있기 때문에 잠재적인 SQL 인젝션 공격 대상 후보가 될 수 있다.
SQL 인젝션 공격 범위는 다양하지만 크게 다음과 같다.
- Authentication Bypass (인증 우회)
- DB Access (데이터베이스 접근)
- Content Change (콘텐츠 변경)
이 중 SQL 인젝션을 이용한 인증 우회 공격에 대해 알아보자
1) 테스트용 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
<p>로그인</p>
<form method="POST" action="">
<p><input id="id" type="text" name="user_id" placeholder="ID" maxlength="20"></p>
<p><input id="pw" type="text" name="user_pass" placeholder="Password" maxlength="20"></p>
<button type = "submit">로그인</button>
</form>
<?php
require_once("db.php");
$user_id=$_POST['user_id'];
$user_pass=$_POST['user_pass'];
if( $user_id != '')
{
$conn = db_conn();
$sql = "select * from test where user_id = '$user_id' and user_pass= '$user_pass'";
$result = mysqli_query($conn, $sql);
mysqli_close($conn);
// DB 조회 시 사용된 SQL 쿼리문
echo "<br><strong>".$sql."</strong><br>";
// 조회 결과
while($row = mysqli_fetch_array($result))
{
// 조회된 계정 정보
echo "<br>".$row['user_id']."<br>";
// 조회된 계정이 존재하는 경우 로그인
if($login_id == '')
{
$login_id=$row['user_id'];
echo "USER : ".$login_id."<br>";
}
}
}
?>
|
cs |
공격 방법을 테스트하기 위한 로그인 페이지다. 로그인하기 위해 아이디와 비밀번호를 입력 후 DB에서 조회하여 일치하는 데이터가 있는지 확인한다. 일치여부에 상관없이 DB 조회 시 사용된 SQL문이 출력되며 일치하는 계정 정보가 존재하면 조회 결과로 반환된 모든 계정 정보를 출력하며 로그인된 계정 정보도 ‘USER : 계정’라는 문자열과 함께 출력된다. 그러나 일치하는 데이터가 존재하지 않으면 반환되는 조회 결과가 없어 아무것도 출력되지 않는다.
2) 공격 방법
SQL인젝션 공격은 크게 3가지로 나뉜다.
- Error Based SQL Injection
- Blind SQL Injection
- Union SQL Injection
인증 우회 공격에 가장 많이 쓰이는 종류는 Error Based SQL Injection (에러 기반 SQL 인젝션)이다. 이 공격은 SQL 쿼리문의 논리적인 오류를 발생시켜 원하는 결과를 얻을 수 있는 방법이다. 그렇다면 어떤 구문이 삽입돼야 오류가 발생하는지 알아보자.
[1] [아이디]' OR '1' = '1
인증 우회에 가장 많이 쓰이는 구문 중 하나이다. 아이디는 알지만 비밀번호는 모르는 경우 사용된다.
1
2
3
4
5
6
7
8
9
10
11
|
<?php
SELECT * FROM TEST WHERE ID = '아이디' AND PASS = '비밀번호'
// 아이디 입력창에 [ 아이디' OR '1' = '1 ] 입력
SELECT * FROM TEST WHERE ID = '아이디' OR '1' = '1' AND PASS = '비밀번호'
?>
|
cs |
- 아이디 입력창에 [ 아이디' OR '1' = '1 ]을 입력한다.
- 논리연산자 우선순위에 의해 OR 연산자보다 AND 연산자가 우선적으로 연산된다.
- '1' = '1'의 결과는 참이지만 비밀번호는 모르기에 PASS='비밀번호'는 거짓이 된다. 따라서 AND 연산 결과는 거짓이 된다.
- 아이디는 DB에 저장되어 있는 정보와 일치하므로 ID = '아이디'의 결과는 참이므로 OR 연산 결과는 참이 된다.
- 따라서 ID = '아이디'인 계정으로 로그인된다.
해당 구문은 논리연산자 AND와 OR의 우선순위를 이용하여 비밀번호에 대한 일치는 필요 없이 아이디만 알아도 로그인이 가능하도록 만들어준다. 이러한 유형은 OR 뒤에 나오는 구문의 결과가 TRUE이기만 하면 되기 때문에 꼭 '1' = '1일 필요는 없다.
[테스트 코드를 이용한 실습]
[2] [아이디]' #
이번 구문도 마찬가지로 아이디는 알고 있지만 비밀번호를 모르는 경우 사용된다.
1
2
3
4
5
6
7
8
9
10
11
|
<?php
SELECT * FROM TEST WHERE ID = '아이디' AND PASS = '비밀번호'
// 아이디 입력창에 [ 아이디' #] 입력
SELECT * FROM TEST WHERE ID = '아이디' # AND PASS = '비밀번호'
?>
|
cs |
- 아이디 입력창에 [ 아이디' #]을 입력한다.
- #기호로 인해 #기호 뒤의 구문은 모두 주석처리되어 비밀번호 일치 코드는 무시된다.
- 아이디는 DB에 저장되어 있는 정보와 일치하므로 ID = '아이디'의 결과는 참이 된다.
- 따라서 ID = '아이디'인 계정으로 로그인된다.
해당 구문은 주석으로 비밀번호 일치 코드를 무시하게 만들어 아이디만 일치하면 로그인이 가능하게 만드는 구문이다. 주석 기호는 MySQL은 '#', Oracle은 '--'으로 DB마다 다르기 때문에 공격 대상의 DB의 종류가 무엇인지 파악한다거나 DB종류마다 다른 주석 기호를 모두 사용하여 공격을 시도해 볼 수 있다.
[테스트 코드를 이용한 실습]
[3] 1' OR '1' = '1' #
이번 구문은 아이디도 비밀번호도 모르는 경우 사용된다.
1
2
3
4
5
6
7
8
9
10
11
|
<?php
SELECT * FROM TEST WHERE ID = '아이디' AND PASS = '비밀번호'
// 아이디 입력창에 [ 1' OR '1' = '1' #] 입력
SELECT * FROM TEST WHERE ID = '1' OR '1' = '1' # AND PASS = '비밀번호'
?>
|
cs |
- 아이디 입력창에 [ ' OR '1' = '1' # ]을 입력한다.
- #기호로 인해 #기호 뒤는 주석 처리되어 비밀번호 일치 코드는 무시된다.
- ID = '1' OR '1' = '1' 구문은 항상 참이기 때문에 DB에 저장되어 있는 모든 계정 정보를 조회한다.
- 모든 계정 정보를 조회하기 때문에 DB에 저장돼있는 순서대로 조회가 된다.
- 이때 가장 위에 있는 계정으로 로그인된다.
해당 구문은 아이디도 비밀번호도 모를 때 공격 대상의 웹 애플리케이션의 인증 우회가 필요한 경우 사용된다. 주석으로 비밀번호 일치 코드를 무시하게 만들고 아이디에 해당하는 논리 연산 결과를 항상 참으로 만들어 DB에 저장되어 있는 모든 계정 정보를 조회하게 만든다. 이때 DB에 가장 먼저 저장된 계정으로 로그인이 된다. 일반적으로 DB에 가장 먼저 저장되어있는 계정은 'admin'이라는 관리자 계정일 확률이 높으므로 주의해야 한다.
[테스트 코드를 이용한 실습]
'normaltic 취업반 5기 > 내용 정리' 카테고리의 다른 글
[normaltic 취업반 5기] 2023-12-06 7주차 내용 정리 (0) | 2023.12.07 |
---|---|
[normaltic 취업반 5기] 2023-11-29 6주차 내용 정리 (0) | 2023.11.29 |
[normaltic 취업반 5기] 2023-11-15 4주차 내용 정리 (0) | 2023.11.15 |
[normaltic 취업반 5기] 2023-11-08 3주차 내용 정리 (0) | 2023.11.08 |
[normaltic 취업반 5기] 2023-11-01 2주차 내용 정리 (0) | 2023.11.02 |