Blind based SQL Injection의 간단한 기본개념
- 기본원리는 참과 거짓의 개념이다
- 예전에 어디 가서 놀이를 할 때 스무고개라는 게임을 다 아는지 모르겠는데 그 게임과 메커니즘이 동일하다.
- 질문자는 질문을 할수있는 횟수를 정해놓고 질문을 한다.
- 그럼 대답자는 오로지 예 아니요라고만 대답할 수 있는데 그 대답을 유추해서 질문자는 정답을 맞히는 게임이다.
- 여기서 Blind based SQL Injection는 스무고개랑 동일한 게임이다
- 다만 질문 횟수는 무제한일 뿐… 예 아니오로 대답이 돌아오는 것은 마찬가지이다.
- 예를 들어 ID 가 normaltic라고 할 때 첫 글자가 a 맞나요? → 아니요 , 이런 메커니즘이다.
Blind based SQL Injection Process
1. SQLI 포인트 찾기
- 먼저 참과 거짓 구문이 적용되는지부터 살펴본다
- 예를 들어
- normaltic' and '1'='1 → 존재하는 아이디
- normaltic' and '1'='2 → 존재하지 않는 아이디
- 이렇게 적용이 가능하다면 SQLI 취약점이 있는 것이다.
2. select 문구가 사용가능한지 체크
- 참 거짓 구분 구문에서 and를 하나 더 넣어준다.
- 하나 더 넣는 이유는 나중에 자동화할 때 헷갈리지 않게 하기 위함이다.
- normaltic' and ( 여기에 조건을 넣는다 ) and '1'='1
- 예를 들어 (select 'test')='test’를 넣어서 select가 사용가능한지 체크한다
- normaltic' and ( (select 'test')='test’ ) and '1'='1 → 에러가 나지 않는다면 사용가능하다.
3. 공격 format 만들기
- 여기 부분이 아주 중요하고 헷갈리기 쉽기 때문에 잘 따라와야 한다.
- 아까 만든 구문을 그대로 가져와준다
- normaltic' and ( 여기에 조건을 넣는다 ) and '1'='1
- 여기서 select는 가능하므로 이제 우리가 원하는 질의를 넣으면 된다.
- 이때 중요한 것이 Blind SQLI로 알 수 있는 건 참 거짓 밖에 알 수 없다. 그래서 유추를 해야 하는데 그때 필요한 함수가 바로 substr 함수이다.
- substr 함수
- 기본적인 함수의 형태는 다음과 같다
- substr('test' , 1 , 1)
- 첫 번째 인자값 = 물어보고 싶은 것
- 두 번째 인자값 = ~ 번째부터 라는 뜻이다 예시를 보면 1번째부터 라는뜻
- 세 번째 인자값 = ~ 번째까지 라는 뜻이다 예시를 보면 1번째까지 라는뜻
- 정리하자면 1,1 은 1번째 1번째까지 라는 뜻이므로 test에서 t를 나타낸다.
- 응용하면 2,1 은 2번째부터 1번째까지 즉 test에서 두 번째 글자인 s를 나타낸다.
- 하나만 더해보면 2,2는 2번째부터 2번째 까지 라는 뜻이므로 test에서 두 번째인 e부터 그 이후 2번째라는 뜻이므로 es라는 문자가 출력된다.
- 그럼 여기서 우리는 첫 번째 인자값이 물어보고 싶은 것 이기 때문에 test를 빼고 sql 질의문을 입력하면 된다.
- substr( ( sql 질의문) , 1 , 1)으로 만들어주면 된다.
- 여기서 이제 우리는 새로운 게임을 배워보자
- 바로 숫자 확률 게임으로 범위를 줄이는 것이다. 이건 up and down 게임과 동일하다.
- 내가 질문을 할 때 질문 횟수는 정해져 있는데 a~z 또는 A~Z까지 일일이 물어볼 수는 없을 것이다.
- 물론 Blind SQLI는 횟수는 무제한이지만 일일이 쳐봐야 한다면 그만한 노동도 없을 것이다.
- 그래서 우리는 일일이 물어보는 수고로움을 덜어주기 위해 up and down 게임으로 문자를 유추할 것이다.
- 하지만 문자를 가지고 up and down 게임을 할 수 있을까? → 불가능하지는 않지만 번거로움도 많고 헷갈릴 위험이 있다…
- 그래서 이 문자를 표현하기 쉽게 숫자로 만들어 볼 건데 문자를 숫자로 변환하는 방법은 ascii 코드가 있다.

- 이 코드표를 보면 특수기호까지 모두 포함하였을 때 33번부터 126번까지이다.
- ascii 함수는 다음과 같다.
- ascii('a')라고 입력하면 위의 표를 참고하여 97이 나올 것이다.
- 그럼 내가 a라는 문자를 숫자로 찾고 싶을 때는 ascii(’a’) = 97이라고 입력하면 이 문장은 참이 된다.
- 이러한 메커니즘을 통하여 ascii( sql 질의 ) > 0이라고 구문을 만들면 내가 질의하고 싶은 쿼리를 넣게 된다면 그 구문의 뜻하는 문자가 0 보다 크다면 참이 나올 것이고 그렇지 않다면 거짓이 나올 것이다.
- 위에서 만든 substr 함수를 sql 질의 표시된 곳에 넣으면 된다.
- ascii(substr(( sql 질의문),1,1)) > 0
- 위의 쿼리를 이제 맨 처음 만들어 놓았던 normaltic' and ( 여기에 조건을 넣는다 ) and '1'='1 여기에 괄호 속에 대입하면 된다
- 최종 공격 format
- normaltic' and (ascii(substr(( SQL 질의문 넣는 곳 ),1,1)) > 0) and '1'='1
4. 바이너리 서치
- 이제 우리가 원하는 단어를 찾기만 하면 된다.
- 예를 들어 normaltic이라는 단어를 찾도록해보자
- select 'normaltic’
- 우리가 만들어 놓은 공격 format에 sql 질의문 넣는 곳에 넣으면 된다.
- normaltic' and (ascii(substr((select 'normaltic’ ),1,1)) > 0) and '1'='1
- 이때 n이라는 단어의 숫자를 뭔지 모른다고 치자
- 이럴 때 우리는 33 ~ 126의 중간값으로 찾을 것이다
- 그럼 공격 format 은 다음과 같다.
- normaltic' and (ascii(substr((select 'normaltic'),1,1)) > 70) and '1'='1
- 이런 식으로 찾다가 보면 다음과 같이 답을 알 수 있다.
- 아스키코드에서 n은 110이다. 이랬을 때 우리는 저 정보를 모르는 상태에서 단어를 찾다 보면 109는 존재하는 아이디라고 하는데 110으로 하였을 때는 존재하지 않는 아이디라고 나올 것이다.
- 이 말인즉슨 110보다는 작고 109보다는 크다라는 것인데 이 숫자는 바로 110일 것이다
- 헷갈린다면 110을 넣고 > 기호가 아닌 = 기호를 넣어보면 존재하는 아이디 즉, 참인 결과가 나올 것이다
- 이런 식으로 우리는 모든 정보를 추출 가능하다.
5. DB 이름 추출
- 이제 DB이름부터 차근차근히 데이터를 추출해 보자
- DB이름 추출하는 쿼리문은 다음과 같다
- select database()
- 이 쿼리문을 우리가 만들어 놓은 공격 format에 대입하면 된다
- normaltic' and (ascii(substr((select database()),1,1)) > 0) and '1'='1
- 넣는 곳에 쿼리를 넣자.
- normaltic' and (ascii(substr((select database()),1,1)) > 0) and '1'='1
- 바이너리 서치를 하면서 한 글자씩 찾으면 된다.
6. 테이블 이름 추출
- 다음으론 테이블 이름을 추출하자
- 테이블 이름을 추출하는 쿼리문은 다음과 같다.
- select table_name from information_schema.tables where table_schema = 'DB이름' limit 1
- 이 쿼리문을 공격 format에 대입하면 다음과 같다
- normaltic' and (ascii(substr(( select table_name from information_schema.tables where table_schema = 'DB이름' limit 1 ),1,1)) > 0) and '1'='1
- 바이너리 서치를 통해 알아내면 된다.
7. 칼럼 이름 추출
- 칼럼이름을 추출하자
- 컬럼 이름을 추출하는 쿼리문은 다음과 같다.
- select column_name from information_schema.columns where table_name = '테이블이름' limit 1
- 이 쿼리문을 공격 format에 대입하면 다음과 같다
- normaltic' and (ascii(substr(( select column_name from information_schema.columns where table_name = '테이블이름' limit 1 ),1,1)) > 0) and '1'='1
- 바이너리 서치를 통해 알아내면 된다.
8. 원하는 정보 추출
- 우리가 만들어 놓은 공격 format에 찾은 내용들을 조합하여 대입하면 된다.
- normaltic' and (ascii(substr(( select id from game ),1,1)) > 0) and '1'='1
- 예를 들어서 game 테이블의 id 칼럼의 내용을 서치 하는 과정
- 바이너리 서치를 통하여 알아내면 된다.
Blind SQL Injection의 자동화 도구
- 위에 process를 통해서 알 수 있듯이 에러 하나만으로도 DB의 정보를 모두 추출할 수 있다는 장점이 있지만 사람이 하나하나 수작업으로 몇 천 번이 될 수도 있을 만큼의 질문이 있을 수도 있다.
- 이러한 점을 간단하게 수행하고자 우리는 자동화 도구를 만들어서 사용하는 것이 바람직한 거 같다.
'모의해킹 스터디 > 개념 정리' 카테고리의 다른 글
| SQL Injection Point 찾기 (2) | 2024.12.11 |
|---|---|
| Error based SQL Injection Process (0) | 2024.12.03 |
| Error based SQL Injection (0) | 2024.12.03 |