SQL Injection
SQL Injection은 In-band SQL Injection, Blind SQL Injection, Union-based SQL Injection, Stored SQL Injection 등등.. 많다.(왜 세상엔 천재들이 많아서 이런 공격기법들을 만들어 내는 거지..? 밉다 세상아)
SQL Injection이 뭔지부터 알아보자.
| ※ SQL인젝션: 사용자의 입력 값으로 웹 사이트 SQL 쿼리가 완성되는 약점을 이용하며, 입력 값을 변조하여 비정상적인 SQL 쿼리를 조합하거나 실행하는 공격. 개발자가 생각지 못한 SQL문을 실행되게 함으로써 데이터베이스를 비정상적으로 조작 가능함 |
주통기 취약점 가이드에 있는 정의이다.
쉽게 생각하면 로그인 폼에는 ID와 Password를 받는 박스가 있는데, 여기에 ' or 1=1 --# 같은 값을 넣어서 로그인 인증 우회가 가능하다.
이해가 안 될 수 있다. 이를 알려면 SQL 쿼리문부터 알아야 한다.
https://365kim.tistory.com/102
SQL 기초 & 자주쓰는 쿼리문 정리
SQL을 배워야하는 이유 데이터베이스와 SQL 우리는 일상 속에서 'DB' 또는 '데이터베이스'라는 단어를 어렵지 않게 접한다. 보통 '관리 목적으로 데이터를 모아놓은 것'을 의미할 때 사용한다. 이 '
365kim.tistory.com
이런 사이트에서 SQL 이란 무엇인지부터 알아보자.
사실 SQL Injection은 하루 이틀로는 제대로 알기 힘들다. 웹에서 가장 많이 발생하는 공격 중 하나이며, OWASP Top 10에도 포함되어 있다.
이에 대한 가장 큰 목적은 데이터를 탈취하는 것이다. 물론 이것만 있는게 아니라, DBMS에서 OS 명령을 실행할 수도 있는데, 이를 사용해 원격 코드 실행(RCE, Remote Code Execution)도 가능하다.
나도 burp suite academy 에서 제공하는 SQL Injection에 대한 자세한 내용을 차후 배울 생각이다. 그렇다 하더라도 우리는 수동적 공격이 아닌, SQLmap을 이용한 자동화된 점검을 할 수 있으니 그것부터 하도록 하자.
In-band SQL Injection
이에 대한 정의는 악의적인 쿼리문을 입력해 같은 채널에서 운영자가 의도치 않은 결과값을 얻는 것을 말한다. 말로만 해선 어렵다.
같은 채널이란 같은 경로을 말한다. SQL 쿼리를 날리는 폼이 있다고 가정하고 그 쿼리 값을 같은 사이트에 반환한다고 하면 이를 같은 채널 생각할 수 있다.
In-band SQL Injection에는 Error-based SQL Injection과 Union-Based SQL Injection이 들어간다.
Union-based SQL Injection
union은 다른 쿼리를 합쳐서 결과를 낼 때 사용한다. 이는 한 쿼리 안에 또 다른 쿼리를 넣는다고 생각하면 되며, 대충 이런 느낌이다. (First_Query(Second_Query))
여기서 컬럼 수도 맞아야 되고하는 조건들이 있지만 그런 개념들은 나중에 따로 알아보길 권한다.
Blind SQL Injection
제목으로부터 유추해보자. 숨겨진 SQL 인젝션? 라는 뜻으로 해석할 수 있는데, 이는 DB 내용을 볼 수는 없어도 True 인지 False 인지로만 판단해서 DB 내용을 맞춰가는 공격이다.
예시로 보는게 제일 편하니 bWAPP로 테스트 해보자(해당 테스트는 SQL Injection get/search easy 난이도이다.)
In-band SQL Injection

아무 값이나 입력하면 위와 같이 영화를 찾지 못했다고 나온다.

또한 이는 사용자 입력값을 Get Parameter로 보내고 있으며, action=search 인 것으로 봐서 action 값에 따른 조건분기문이 있는 것으로 추정된다.

' 이라는 값을 주니 위와 같은 에러 메시지가 나온다. 에러메시지에 따르면 해당 DBMS는 MySQL 이다. MySQL은 -- 과 # 으로 주석처리를 하고 있으며, 이를 이용해서 여러 값을 가져올 수 있다.

1' or 1=1 -- 또는 1' or 1=1 # 이라고 입력하면 모든 값들이 리턴된다. 입력값과 쿼리문을 합친 것을 예상해보자.
select * from movie where title = '1' or 1=1 -- #
대충 이런 식으로 예상할 수 있다.
or 앞에 1이 False 도 뒤에 1=1 이 True 이기에 where은 없는 것이나 마찬가지가 되어서 movie table에 있는 모든 값을 가져오는 것이다(여기서 주의해야 하는 점은 mysql에서 -- 로 주석 처리를 할 때는 -- 다음에 스페이스 하나를 추가해야 한다)
Error based SQL Injection

위 사진에는 에러가 나온다. 따라서 해당 쿼리 안에 다른 쿼리를 넣어도 아무런 값이 안나오는 것이 아닌, 다른 쿼리를 대신해서 실행할 수 있다.

예를 들어보자.
데이터 탈취를 위해서 우리가 알아야 하는 내용들은 Database 이름, Table 이름, Column 이름 정도가 있다. 이 중에 Database 이름이 Management 라고 가정을 하겠다.
SQL Query는 아래와 같다고 가정하고
SELECT * FROM users WHERE id = 'user input()'
아래와 같은 값을 user input 으로 주겠다.
1'AND (substring((select database()),1,1)='a') --#
그러면 이는 아래와 같은 SQL Query 문이 만들어진다.
SELECT * FROM users WHERE id = '1'AND (substring((select database()),1,1)='a') --# '
where 문을 해석해보면 id 가 1이고(이는 True라고 가정) 그 뒤에 나오는 것이 True면 이는 True가 된다. 조금 어려울 수 있는데, 이렇게 보면 된다.
True and True = True
and 좌우에 있는 것이 True 일 시 결과도 True가 된다. 그러나 둘 중 하나가 다르면 이는 False를 반환한다.
다시 SQL Query로 돌아가보면 and 다음에 substing이 나온다. 이는 문자열 추출 함수로 아래와 같은 형식을 지닌다.
substring(문자열, 시작위치, 길이)
예시로
substring(test, 1, 1) 일 시 반환 값은 t 이다.
그래서 select database() 로 현재 DB 이름을 가져오고, 여기 첫번째 문자가 a 라면 True를 반환하고 아니라면 False를 반환한다.
---------------------------------------------------------------
작성 중
'주요통신기반시설 취약점 가이드 > 주통기 웹' 카테고리의 다른 글
| 경로 추적(Path Traversal) (0) | 2025.03.18 |
|---|---|
| 관리자 페이지 노출 (0) | 2025.02.20 |
| LDAP Injection (0) | 2025.02.19 |
| Buffer Overflow (0) | 2025.02.19 |
| Command Injection (0) | 2025.02.19 |