Skip to content

Commit 1a315dc

Browse files
author
Johannes Bader
authored
Merge pull request #4 from benji-york/master
This branch adds a --all-seeds option to the qadars DGA.
2 parents 1fb30b9 + 69d18ac commit 1a315dc

File tree

2 files changed

+76
-30
lines changed

2 files changed

+76
-30
lines changed

qadars/dga.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def dga(date, seed):
1818
c = 4*24*3600
1919
r = unix - (unix-c) % b
2020
for i in range(200):
21-
domain = ""
21+
domain = ""
2222
for _ in range(12):
2323
r = rand(r, seed)
2424
domain += charset[r % len(charset)]
@@ -28,19 +28,24 @@ def dga(date, seed):
2828
print(domain)
2929

3030
if __name__ == "__main__":
31+
seeds = ["89f5", "4449", "E1F1", "E1F2", "E08A", "E1F5"]
3132
parser = argparse.ArgumentParser()
32-
parser.add_argument("-d", "--date",
33+
parser.add_argument("-d", "--date",
3334
help="date for which to generate domains")
3435
parser.add_argument("-s", "--seed",
35-
help="seed as hexstring", choices={"89f5", "4449", "E1F1",
36-
"E1F2", "E08A", "E1F5"},
36+
help="seed as hexstring", choices=seeds,
3737
default="e08a")
38+
parser.add_argument("-a", "--all-seeds", action="store_true",
39+
help="use all seeds")
3840
args = parser.parse_args()
3941

4042
if args.date:
4143
d = datetime.strptime(args.date, "%Y-%m-%d")
4244
else:
4345
d = datetime.now()
44-
dga(d, int(args.seed,16))
45-
4646

47+
if not args.all_seeds:
48+
seeds = [args.seed]
49+
50+
for seed in seeds:
51+
dga(d, int(seed, 16))

tinba/dga.py

Lines changed: 65 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,66 @@
1-
seed ="yqokqFC2TPBFfJcG"
2-
seed += (17 - len(seed))*"\x00"
3-
seed_l = [ord(s) for s in seed]
4-
domain = "watchthisnow.xyz"
5-
print(domain)
6-
for i in range(100):
7-
domain_l = [ord(l) for l in domain]
8-
seed_sum = sum(seed_l[:16])
9-
new_domain = []
10-
tmp = seed_l[15] & 0xFF
11-
for i in range(12):
12-
while True:
13-
tmp += domain_l[i]
14-
tmp ^= (seed_sum & 0xFF)
15-
tmp += domain_l[i+1]
16-
tmp &= 0xFF
17-
if 0x61 < tmp < 0x7a:
18-
new_domain.append(tmp)
19-
break
20-
else:
21-
seed_sum += 1
22-
23-
for tld in ['pw', 'us', 'xyz', 'club']:
24-
domain = ''.join([chr(x) for x in new_domain]) + '.' + tld
1+
from __future__ import print_function
2+
3+
4+
def dga(seed, domain, tlds, num_domains):
5+
seed += (17 - len(seed))*'\x00'
6+
seed_l = [ord(s) for s in seed]
7+
yield domain
8+
for _ in range(num_domains):
9+
domain_l = [ord(l) for l in domain]
10+
seed_sum = sum(seed_l[:16])
11+
new_domain = []
12+
tmp = seed_l[15] & 0xFF
13+
for i in range(12):
14+
while True:
15+
tmp += domain_l[i]
16+
tmp ^= (seed_sum & 0xFF)
17+
tmp += domain_l[i+1]
18+
tmp &= 0xFF
19+
if 0x61 < tmp < 0x7a:
20+
new_domain.append(tmp)
21+
break
22+
else:
23+
seed_sum += 1
24+
25+
base_domain = ''.join([chr(x) for x in new_domain])
26+
for tld in tlds:
27+
domain = base_domain + '.' + tld
28+
yield domain
29+
30+
31+
if __name__ == '__main__':
32+
# There are several Tinba variants. This describes those variations and
33+
# source references for each.
34+
dga_configurations = [
35+
# http://garage4hackers.com/entry.php?b=3086
36+
('oGkS3w3sGGOGG7oc', 'ssrgwnrmgrxe.com', ('com',), 1000),
37+
# https://johannesbader.ch/2015/04/new-top-level-domains-for-tinbas-dga
38+
('jc74FlUna852Ji9o', 'blackfreeqazyio.cc', ('com', 'net', 'in', 'ru'), 100),
39+
# https://www.sophos.com/en-us/threat-center/threat-analyses/viruses-and-spyware/Troj~Tinba-EL/detailed-analysis.aspx
40+
# https://github.com/baderj/domain_generation_algorithms/commit/c7d154a39bb172c4632f7565e0c9380e8b36c18e
41+
('yqokqFC2TPBFfJcG', 'watchthisnow.xyz', ('pw', 'us', 'xyz', 'club'), 100),
42+
# https://github.com/baderj/domain_generation_algorithms/commit/c7d154a39bb172c4632f7565e0c9380e8b36c18e
43+
('j193HsnW72Yqns7u', 'j193hsne720uie8i.cc', ('com', 'net', 'biz', 'org'), 100),
44+
]
45+
46+
47+
# Hard-coded c2 domains:
48+
# (see https://www.symantec.com/security_response/writeup.jsp?docid=2014-092411-3132-99&tabid=2)
49+
hard_coded = []
50+
hard_coded.extend(
51+
('newstatinru.ru', 'justforyou0987.pw', 'phpsitegooddecoder.com'))
52+
53+
54+
# The page below mentions DNS requests to several domains that this DGA
55+
# does not generate. Perhaps they are hard-coded in some samples.
56+
# https://www.sophos.com/en-us/threat-center/threat-analyses/viruses-and-spyware/Troj~Wonton-MT/detailed-analysis.aspx
57+
hard_coded.extend(
58+
('santaluable.com', 'santanyr.com', 'ervaluable.com', 'larnasa.com'))
59+
60+
61+
for domain in hard_coded:
2562
print(domain)
63+
64+
for config in dga_configurations:
65+
for result in dga(*config):
66+
print(result)

0 commit comments

Comments
 (0)