bbot 2.2.0.5279rc0__py3-none-any.whl → 2.2.0.5311rc0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of bbot might be problematic. Click here for more details.
- bbot/__init__.py +1 -1
- bbot/cli.py +1 -1
- bbot/core/engine.py +2 -2
- bbot/core/event/base.py +23 -2
- bbot/core/helpers/bloom.py +8 -1
- bbot/core/helpers/dns/helpers.py +2 -2
- bbot/core/helpers/helper.py +4 -3
- bbot/core/helpers/misc.py +11 -5
- bbot/core/helpers/regexes.py +2 -1
- bbot/core/helpers/web/web.py +1 -1
- bbot/modules/anubisdb.py +1 -1
- bbot/modules/baddns.py +1 -1
- bbot/modules/bevigil.py +2 -2
- bbot/modules/binaryedge.py +1 -1
- bbot/modules/bufferoverrun.py +2 -3
- bbot/modules/builtwith.py +2 -2
- bbot/modules/c99.py +4 -2
- bbot/modules/certspotter.py +4 -2
- bbot/modules/chaos.py +4 -2
- bbot/modules/columbus.py +1 -1
- bbot/modules/crt.py +4 -2
- bbot/modules/digitorus.py +1 -1
- bbot/modules/dnscaa.py +3 -3
- bbot/modules/fullhunt.py +1 -1
- bbot/modules/hackertarget.py +4 -2
- bbot/modules/internal/excavate.py +2 -3
- bbot/modules/internal/speculate.py +1 -1
- bbot/modules/leakix.py +4 -2
- bbot/modules/myssl.py +1 -1
- bbot/modules/otx.py +4 -2
- bbot/modules/passivetotal.py +4 -2
- bbot/modules/rapiddns.py +2 -7
- bbot/modules/securitytrails.py +4 -2
- bbot/modules/shodan_dns.py +1 -1
- bbot/modules/subdomaincenter.py +1 -1
- bbot/modules/templates/subdomain_enum.py +3 -3
- bbot/modules/trickest.py +1 -1
- bbot/modules/virustotal.py +2 -7
- bbot/modules/zoomeye.py +5 -3
- bbot/presets/spider.yml +4 -0
- bbot/scanner/manager.py +1 -2
- bbot/scanner/preset/args.py +3 -3
- bbot/scanner/preset/path.py +3 -1
- bbot/scanner/preset/preset.py +10 -4
- bbot/scanner/scanner.py +7 -2
- bbot/scanner/target.py +236 -434
- bbot/test/test_step_1/test_bloom_filter.py +2 -0
- bbot/test/test_step_1/test_cli.py +7 -0
- bbot/test/test_step_1/test_dns.py +2 -1
- bbot/test/test_step_1/test_events.py +16 -2
- bbot/test/test_step_1/test_helpers.py +17 -0
- bbot/test/test_step_1/test_presets.py +50 -36
- bbot/test/test_step_1/test_python_api.py +4 -0
- bbot/test/test_step_1/test_scan.py +8 -2
- bbot/test/test_step_1/test_target.py +227 -129
- bbot/test/test_step_2/module_tests/test_module_dastardly.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_ffuf_shortnames.py +1 -1
- {bbot-2.2.0.5279rc0.dist-info → bbot-2.2.0.5311rc0.dist-info}/METADATA +4 -4
- {bbot-2.2.0.5279rc0.dist-info → bbot-2.2.0.5311rc0.dist-info}/RECORD +62 -62
- {bbot-2.2.0.5279rc0.dist-info → bbot-2.2.0.5311rc0.dist-info}/LICENSE +0 -0
- {bbot-2.2.0.5279rc0.dist-info → bbot-2.2.0.5311rc0.dist-info}/WHEEL +0 -0
- {bbot-2.2.0.5279rc0.dist-info → bbot-2.2.0.5311rc0.dist-info}/entry_points.txt +0 -0
|
@@ -3,39 +3,31 @@ from ..bbot_fixtures import * # noqa: F401
|
|
|
3
3
|
|
|
4
4
|
@pytest.mark.asyncio
|
|
5
5
|
async def test_target(bbot_scanner):
|
|
6
|
-
import
|
|
6
|
+
from radixtarget import RadixTarget
|
|
7
7
|
from ipaddress import ip_address, ip_network
|
|
8
|
-
from bbot.scanner.target import
|
|
8
|
+
from bbot.scanner.target import BBOTTarget, ScanSeeds
|
|
9
9
|
|
|
10
10
|
scan1 = bbot_scanner("api.publicapis.org", "8.8.8.8/30", "2001:4860:4860::8888/126")
|
|
11
11
|
scan2 = bbot_scanner("8.8.8.8/29", "publicapis.org", "2001:4860:4860::8888/125")
|
|
12
12
|
scan3 = bbot_scanner("8.8.8.8/29", "publicapis.org", "2001:4860:4860::8888/125")
|
|
13
13
|
scan4 = bbot_scanner("8.8.8.8/29")
|
|
14
14
|
scan5 = bbot_scanner()
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
assert "
|
|
19
|
-
assert "
|
|
20
|
-
assert "
|
|
21
|
-
assert "
|
|
22
|
-
assert "
|
|
23
|
-
assert "
|
|
24
|
-
assert "
|
|
25
|
-
|
|
26
|
-
assert
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
assert scan1.make_event("https://[2001:4860:4860::8888]:80", dummy=True) in scan1.target
|
|
32
|
-
assert scan1.make_event("[2001:4860:4860::8888]:80", "OPEN_TCP_PORT", dummy=True) in scan1.target
|
|
33
|
-
assert scan1.make_event("[2001:4860:4860::888c]:80", "OPEN_TCP_PORT", dummy=True) not in scan1.target
|
|
34
|
-
assert scan1.target in scan2.target
|
|
35
|
-
assert scan2.target not in scan1.target
|
|
36
|
-
assert scan3.target in scan2.target
|
|
37
|
-
assert scan2.target == scan3.target
|
|
38
|
-
assert scan4.target != scan1.target
|
|
15
|
+
|
|
16
|
+
# test different types of inputs
|
|
17
|
+
target = BBOTTarget("evilcorp.com", "1.2.3.4/8")
|
|
18
|
+
assert "www.evilcorp.com" in target.seeds
|
|
19
|
+
assert "www.evilcorp.com:80" in target.seeds
|
|
20
|
+
assert "http://www.evilcorp.com:80" in target.seeds
|
|
21
|
+
assert "1.2.3.4" in target.seeds
|
|
22
|
+
assert "1.2.3.4/24" in target.seeds
|
|
23
|
+
assert ip_address("1.2.3.4") in target.seeds
|
|
24
|
+
assert ip_network("1.2.3.4/24", strict=False) in target.seeds
|
|
25
|
+
event = scan1.make_event("https://www.evilcorp.com:80", dummy=True)
|
|
26
|
+
assert event in target.seeds
|
|
27
|
+
with pytest.raises(ValueError):
|
|
28
|
+
["asdf"] in target.seeds
|
|
29
|
+
with pytest.raises(ValueError):
|
|
30
|
+
target.seeds.get(["asdf"])
|
|
39
31
|
|
|
40
32
|
assert not scan5.target.seeds
|
|
41
33
|
assert len(scan1.target.seeds) == 9
|
|
@@ -56,6 +48,36 @@ async def test_target(bbot_scanner):
|
|
|
56
48
|
assert scan1.make_event("https://[2001:4860:4860::8888]:80", dummy=True) in scan1.target.seeds
|
|
57
49
|
assert scan1.make_event("[2001:4860:4860::8888]:80", "OPEN_TCP_PORT", dummy=True) in scan1.target.seeds
|
|
58
50
|
assert scan1.make_event("[2001:4860:4860::888c]:80", "OPEN_TCP_PORT", dummy=True) not in scan1.target.seeds
|
|
51
|
+
assert scan1.target.seeds in scan2.target.seeds
|
|
52
|
+
assert scan2.target.seeds not in scan1.target.seeds
|
|
53
|
+
assert scan3.target.seeds in scan2.target.seeds
|
|
54
|
+
assert scan2.target.seeds == scan3.target.seeds
|
|
55
|
+
assert scan4.target.seeds != scan1.target.seeds
|
|
56
|
+
|
|
57
|
+
assert not scan5.target.whitelist
|
|
58
|
+
assert len(scan1.target.whitelist) == 9
|
|
59
|
+
assert len(scan4.target.whitelist) == 8
|
|
60
|
+
assert "8.8.8.9" in scan1.target.whitelist
|
|
61
|
+
assert "8.8.8.12" not in scan1.target.whitelist
|
|
62
|
+
assert "8.8.8.8/31" in scan1.target.whitelist
|
|
63
|
+
assert "8.8.8.8/30" in scan1.target.whitelist
|
|
64
|
+
assert "8.8.8.8/29" not in scan1.target.whitelist
|
|
65
|
+
assert "2001:4860:4860::8889" in scan1.target.whitelist
|
|
66
|
+
assert "2001:4860:4860::888c" not in scan1.target.whitelist
|
|
67
|
+
assert "www.api.publicapis.org" in scan1.target.whitelist
|
|
68
|
+
assert "api.publicapis.org" in scan1.target.whitelist
|
|
69
|
+
assert "publicapis.org" not in scan1.target.whitelist
|
|
70
|
+
assert "bob@www.api.publicapis.org" in scan1.target.whitelist
|
|
71
|
+
assert "https://www.api.publicapis.org" in scan1.target.whitelist
|
|
72
|
+
assert "www.api.publicapis.org:80" in scan1.target.whitelist
|
|
73
|
+
assert scan1.make_event("https://[2001:4860:4860::8888]:80", dummy=True) in scan1.target.whitelist
|
|
74
|
+
assert scan1.make_event("[2001:4860:4860::8888]:80", "OPEN_TCP_PORT", dummy=True) in scan1.target.whitelist
|
|
75
|
+
assert scan1.make_event("[2001:4860:4860::888c]:80", "OPEN_TCP_PORT", dummy=True) not in scan1.target.whitelist
|
|
76
|
+
assert scan1.target.whitelist in scan2.target.whitelist
|
|
77
|
+
assert scan2.target.whitelist not in scan1.target.whitelist
|
|
78
|
+
assert scan3.target.whitelist in scan2.target.whitelist
|
|
79
|
+
assert scan2.target.whitelist == scan3.target.whitelist
|
|
80
|
+
assert scan4.target.whitelist != scan1.target.whitelist
|
|
59
81
|
|
|
60
82
|
assert scan1.whitelisted("https://[2001:4860:4860::8888]:80")
|
|
61
83
|
assert scan1.whitelisted("[2001:4860:4860::8888]:80")
|
|
@@ -70,28 +92,34 @@ async def test_target(bbot_scanner):
|
|
|
70
92
|
assert scan2.target.seeds == scan3.target.seeds
|
|
71
93
|
assert scan4.target.seeds != scan1.target.seeds
|
|
72
94
|
|
|
73
|
-
assert str(scan1.target.get("8.8.8.9").host) == "8.8.8.8/30"
|
|
74
|
-
assert scan1.target.get("8.8.8.
|
|
75
|
-
assert
|
|
76
|
-
assert scan1.target.get("
|
|
77
|
-
assert str(scan1.target.get("
|
|
78
|
-
assert scan1.target.get("
|
|
79
|
-
|
|
80
|
-
target
|
|
95
|
+
assert str(scan1.target.seeds.get("8.8.8.9").host) == "8.8.8.8/30"
|
|
96
|
+
assert str(scan1.target.whitelist.get("8.8.8.9").host) == "8.8.8.8/30"
|
|
97
|
+
assert scan1.target.seeds.get("8.8.8.12") is None
|
|
98
|
+
assert scan1.target.whitelist.get("8.8.8.12") is None
|
|
99
|
+
assert str(scan1.target.seeds.get("2001:4860:4860::8889").host) == "2001:4860:4860::8888/126"
|
|
100
|
+
assert str(scan1.target.whitelist.get("2001:4860:4860::8889").host) == "2001:4860:4860::8888/126"
|
|
101
|
+
assert scan1.target.seeds.get("2001:4860:4860::888c") is None
|
|
102
|
+
assert scan1.target.whitelist.get("2001:4860:4860::888c") is None
|
|
103
|
+
assert str(scan1.target.seeds.get("www.api.publicapis.org").host) == "api.publicapis.org"
|
|
104
|
+
assert str(scan1.target.whitelist.get("www.api.publicapis.org").host) == "api.publicapis.org"
|
|
105
|
+
assert scan1.target.seeds.get("publicapis.org") is None
|
|
106
|
+
assert scan1.target.whitelist.get("publicapis.org") is None
|
|
107
|
+
|
|
108
|
+
target = RadixTarget("evilcorp.com")
|
|
81
109
|
assert not "com" in target
|
|
82
110
|
assert "evilcorp.com" in target
|
|
83
111
|
assert "www.evilcorp.com" in target
|
|
84
|
-
strict_target =
|
|
112
|
+
strict_target = RadixTarget("evilcorp.com", strict_dns_scope=True)
|
|
85
113
|
assert not "com" in strict_target
|
|
86
114
|
assert "evilcorp.com" in strict_target
|
|
87
115
|
assert not "www.evilcorp.com" in strict_target
|
|
88
116
|
|
|
89
|
-
target =
|
|
117
|
+
target = RadixTarget()
|
|
90
118
|
target.add("evilcorp.com")
|
|
91
119
|
assert not "com" in target
|
|
92
120
|
assert "evilcorp.com" in target
|
|
93
121
|
assert "www.evilcorp.com" in target
|
|
94
|
-
strict_target =
|
|
122
|
+
strict_target = RadixTarget(strict_dns_scope=True)
|
|
95
123
|
strict_target.add("evilcorp.com")
|
|
96
124
|
assert not "com" in strict_target
|
|
97
125
|
assert "evilcorp.com" in strict_target
|
|
@@ -99,16 +127,23 @@ async def test_target(bbot_scanner):
|
|
|
99
127
|
|
|
100
128
|
# test target hashing
|
|
101
129
|
|
|
102
|
-
target1 =
|
|
103
|
-
target1.add("evilcorp.com")
|
|
104
|
-
target1.add("1.2.3.4/24")
|
|
105
|
-
target1.add("https://evilcorp.net:8080")
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
target2
|
|
111
|
-
target2.add("
|
|
130
|
+
target1 = BBOTTarget()
|
|
131
|
+
target1.whitelist.add("evilcorp.com")
|
|
132
|
+
target1.whitelist.add("1.2.3.4/24")
|
|
133
|
+
target1.whitelist.add("https://evilcorp.net:8080")
|
|
134
|
+
target1.seeds.add("evilcorp.com")
|
|
135
|
+
target1.seeds.add("1.2.3.4/24")
|
|
136
|
+
target1.seeds.add("https://evilcorp.net:8080")
|
|
137
|
+
|
|
138
|
+
target2 = BBOTTarget()
|
|
139
|
+
target2.whitelist.add("bob@evilcorp.org")
|
|
140
|
+
target2.whitelist.add("evilcorp.com")
|
|
141
|
+
target2.whitelist.add("1.2.3.4/24")
|
|
142
|
+
target2.whitelist.add("https://evilcorp.net:8080")
|
|
143
|
+
target2.seeds.add("bob@evilcorp.org")
|
|
144
|
+
target2.seeds.add("evilcorp.com")
|
|
145
|
+
target2.seeds.add("1.2.3.4/24")
|
|
146
|
+
target2.seeds.add("https://evilcorp.net:8080")
|
|
112
147
|
|
|
113
148
|
# make sure it's a sha1 hash
|
|
114
149
|
assert isinstance(target1.hash, bytes)
|
|
@@ -116,11 +151,22 @@ async def test_target(bbot_scanner):
|
|
|
116
151
|
|
|
117
152
|
# hashes shouldn't match yet
|
|
118
153
|
assert target1.hash != target2.hash
|
|
154
|
+
assert target1.scope_hash != target2.scope_hash
|
|
119
155
|
# add missing email
|
|
120
|
-
target1.add("bob@evilcorp.org")
|
|
156
|
+
target1.whitelist.add("bob@evilcorp.org")
|
|
157
|
+
assert target1.hash != target2.hash
|
|
158
|
+
assert target1.scope_hash == target2.scope_hash
|
|
159
|
+
target1.seeds.add("bob@evilcorp.org")
|
|
121
160
|
# now they should match
|
|
122
161
|
assert target1.hash == target2.hash
|
|
123
162
|
|
|
163
|
+
# test default whitelist
|
|
164
|
+
bbottarget = BBOTTarget("http://1.2.3.4:8443", "bob@evilcorp.com")
|
|
165
|
+
assert bbottarget.seeds.hosts == {ip_network("1.2.3.4"), "evilcorp.com"}
|
|
166
|
+
assert bbottarget.whitelist.hosts == {ip_network("1.2.3.4"), "evilcorp.com"}
|
|
167
|
+
assert set([e.data for e in bbottarget.seeds.events]) == {"http://1.2.3.4:8443/", "bob@evilcorp.com"}
|
|
168
|
+
assert set([e.data for e in bbottarget.whitelist.events]) == {"1.2.3.4", "evilcorp.com"}
|
|
169
|
+
|
|
124
170
|
bbottarget1 = BBOTTarget("evilcorp.com", "evilcorp.net", whitelist=["1.2.3.4/24"], blacklist=["1.2.3.4"])
|
|
125
171
|
bbottarget2 = BBOTTarget("evilcorp.com", "evilcorp.net", whitelist=["1.2.3.0/24"], blacklist=["1.2.3.4"])
|
|
126
172
|
bbottarget3 = BBOTTarget("evilcorp.com", whitelist=["1.2.3.4/24"], blacklist=["1.2.3.4"])
|
|
@@ -137,14 +183,23 @@ async def test_target(bbot_scanner):
|
|
|
137
183
|
|
|
138
184
|
assert bbottarget1 == bbottarget2
|
|
139
185
|
assert bbottarget2 == bbottarget1
|
|
186
|
+
# 1 and 3 have different seeds
|
|
140
187
|
assert bbottarget1 != bbottarget3
|
|
141
188
|
assert bbottarget3 != bbottarget1
|
|
142
|
-
|
|
189
|
+
# until we make them the same
|
|
190
|
+
bbottarget3.seeds.add("evilcorp.net")
|
|
143
191
|
assert bbottarget1 == bbottarget3
|
|
144
192
|
assert bbottarget3 == bbottarget1
|
|
145
193
|
|
|
146
|
-
|
|
147
|
-
|
|
194
|
+
# adding different events (but with same host) to whitelist should not change hash (since only hosts matter)
|
|
195
|
+
bbottarget1.whitelist.add("http://evilcorp.co.nz")
|
|
196
|
+
bbottarget2.whitelist.add("evilcorp.co.nz")
|
|
197
|
+
assert bbottarget1 == bbottarget2
|
|
198
|
+
assert bbottarget2 == bbottarget1
|
|
199
|
+
|
|
200
|
+
# but seeds should change hash
|
|
201
|
+
bbottarget1.seeds.add("http://evilcorp.co.nz")
|
|
202
|
+
bbottarget2.seeds.add("evilcorp.co.nz")
|
|
148
203
|
assert bbottarget1 != bbottarget2
|
|
149
204
|
assert bbottarget2 != bbottarget1
|
|
150
205
|
|
|
@@ -156,15 +211,11 @@ async def test_target(bbot_scanner):
|
|
|
156
211
|
assert bbottarget8 != bbottarget9
|
|
157
212
|
assert bbottarget9 != bbottarget8
|
|
158
213
|
|
|
159
|
-
bbottarget10 = bbottarget9.copy()
|
|
160
|
-
assert bbottarget10 == bbottarget9
|
|
161
|
-
assert bbottarget9 == bbottarget10
|
|
162
|
-
|
|
163
214
|
# make sure duplicate events don't change hash
|
|
164
|
-
target1 =
|
|
165
|
-
target2 =
|
|
215
|
+
target1 = BBOTTarget("https://evilcorp.com")
|
|
216
|
+
target2 = BBOTTarget("https://evilcorp.com")
|
|
166
217
|
assert target1 == target2
|
|
167
|
-
target1.add("https://evilcorp.com:443")
|
|
218
|
+
target1.seeds.add("https://evilcorp.com:443")
|
|
168
219
|
assert target1 == target2
|
|
169
220
|
|
|
170
221
|
# make sure hosts are collapsed in whitelist and blacklist
|
|
@@ -173,10 +224,12 @@ async def test_target(bbot_scanner):
|
|
|
173
224
|
whitelist=["evilcorp.net:443", "http://evilcorp.net:8080"],
|
|
174
225
|
blacklist=["http://evilcorp.org:8080", "evilcorp.org:443"],
|
|
175
226
|
)
|
|
176
|
-
|
|
227
|
+
# base class is not iterable
|
|
228
|
+
with pytest.raises(TypeError):
|
|
229
|
+
assert list(bbottarget) == ["http://evilcorp.com:8080"]
|
|
177
230
|
assert list(bbottarget.seeds) == ["http://evilcorp.com:8080"]
|
|
178
|
-
assert
|
|
179
|
-
assert
|
|
231
|
+
assert set([e.data for e in bbottarget.whitelist]) == {"evilcorp.net:443", "http://evilcorp.net:8080/"}
|
|
232
|
+
assert set([e.data for e in bbottarget.blacklist]) == {"http://evilcorp.org:8080/", "evilcorp.org:443"}
|
|
180
233
|
|
|
181
234
|
# test org stub as target
|
|
182
235
|
for org_target in ("ORG:evilcorp", "ORG_STUB:evilcorp"):
|
|
@@ -205,16 +258,25 @@ async def test_target(bbot_scanner):
|
|
|
205
258
|
"http://www.evilcorp.net/",
|
|
206
259
|
"bob@fdsa.evilcorp.net",
|
|
207
260
|
}
|
|
208
|
-
assert set([e.data for e in bbottarget.whitelist.events]) == {
|
|
209
|
-
|
|
261
|
+
assert set([e.data for e in bbottarget.whitelist.events]) == {
|
|
262
|
+
"evilcorp.com",
|
|
263
|
+
"evilcorp.net",
|
|
264
|
+
"bob@www.evilcorp.com",
|
|
265
|
+
}
|
|
266
|
+
assert set([e.data for e in bbottarget.blacklist.events]) == {
|
|
267
|
+
"1.2.3.4",
|
|
268
|
+
"4.3.2.0/24",
|
|
269
|
+
"http://1.2.3.4/",
|
|
270
|
+
"bob@asdf.evilcorp.net",
|
|
271
|
+
}
|
|
210
272
|
assert set(bbottarget.seeds.hosts) == {ip_network("1.2.3.0/24"), "www.evilcorp.net", "fdsa.evilcorp.net"}
|
|
211
273
|
assert set(bbottarget.whitelist.hosts) == {"evilcorp.com", "evilcorp.net"}
|
|
212
|
-
assert set(bbottarget.blacklist.hosts) == {
|
|
213
|
-
assert bbottarget.hash == b"\
|
|
214
|
-
assert bbottarget.scope_hash == b"\
|
|
215
|
-
assert bbottarget.seeds.hash == b"\
|
|
216
|
-
assert bbottarget.whitelist.hash == b"\
|
|
217
|
-
assert bbottarget.blacklist.hash == b
|
|
274
|
+
assert set(bbottarget.blacklist.hosts) == {ip_network("1.2.3.4/32"), ip_network("4.3.2.0/24"), "asdf.evilcorp.net"}
|
|
275
|
+
assert bbottarget.hash == b"\xb3iU\xa8#\x8aq\x84/\xc5\xf2;\x11\x11\x0c&\xea\x07\xd4Q"
|
|
276
|
+
assert bbottarget.scope_hash == b"f\xe1\x01c^3\xf5\xd24B\x87P\xa0Glq0p3J"
|
|
277
|
+
assert bbottarget.seeds.hash == b"V\n\xf5\x1d\x1f=i\xbc\\\x15o\xc2p\xb2\x84\x97\xfeR\xde\xc1"
|
|
278
|
+
assert bbottarget.whitelist.hash == b"\x8e\xd0\xa76\x8em4c\x0e\x1c\xfdA\x9d*sv}\xeb\xc4\xc4"
|
|
279
|
+
assert bbottarget.blacklist.hash == b'\xf7\xaf\xa1\xda4"C:\x13\xf42\xc3,\xc3\xa9\x9f\x15\x15n\\'
|
|
218
280
|
|
|
219
281
|
scan = bbot_scanner(
|
|
220
282
|
"http://www.evilcorp.net",
|
|
@@ -227,72 +289,35 @@ async def test_target(bbot_scanner):
|
|
|
227
289
|
scan_events = [e for e in events if e.type == "SCAN"]
|
|
228
290
|
assert len(scan_events) == 2
|
|
229
291
|
target_dict = scan_events[0].data["target"]
|
|
292
|
+
|
|
293
|
+
assert target_dict["seeds"] == ["1.2.3.0/24", "bob@fdsa.evilcorp.net", "http://www.evilcorp.net/"]
|
|
294
|
+
assert target_dict["whitelist"] == ["bob@www.evilcorp.com", "evilcorp.com", "evilcorp.net"]
|
|
295
|
+
assert target_dict["blacklist"] == ["1.2.3.4", "4.3.2.0/24", "bob@asdf.evilcorp.net", "http://1.2.3.4/"]
|
|
230
296
|
assert target_dict["strict_scope"] == False
|
|
231
|
-
assert target_dict["hash"] ==
|
|
232
|
-
assert target_dict["
|
|
233
|
-
assert target_dict["
|
|
234
|
-
assert target_dict["
|
|
235
|
-
assert target_dict["
|
|
236
|
-
assert target_dict["hash"] == "0b9038e3ef0a3d1364df003bac6b0cbcd2cc27ba"
|
|
237
|
-
assert target_dict["scope_hash"] == "00f556fb2eeb23cbf071f9e965b71fe2542bdb77"
|
|
238
|
-
assert target_dict["seed_hash"] == "af2e8683a143adb4e7605894e2a001c2e33a4ac5"
|
|
239
|
-
assert target_dict["whitelist_hash"] == "a04166076e10d9b60aa7544fb037cd57c4764c43"
|
|
240
|
-
assert target_dict["blacklist_hash"] == "af0e8ae94a5a86beeea9a9db30af27238420552f"
|
|
241
|
-
|
|
242
|
-
# test target sorting
|
|
243
|
-
big_subnet = scan.make_event("1.2.3.4/24", dummy=True)
|
|
244
|
-
medium_subnet = scan.make_event("1.2.3.4/28", dummy=True)
|
|
245
|
-
small_subnet = scan.make_event("1.2.3.4/30", dummy=True)
|
|
246
|
-
ip_event = scan.make_event("1.2.3.4", dummy=True)
|
|
247
|
-
parent_domain = scan.make_event("evilcorp.com", dummy=True)
|
|
248
|
-
grandparent_domain = scan.make_event("www.evilcorp.com", dummy=True)
|
|
249
|
-
greatgrandparent_domain = scan.make_event("api.www.evilcorp.com", dummy=True)
|
|
250
|
-
target = Target()
|
|
251
|
-
assert big_subnet._host_size == -256
|
|
252
|
-
assert medium_subnet._host_size == -16
|
|
253
|
-
assert small_subnet._host_size == -4
|
|
254
|
-
assert ip_event._host_size == 1
|
|
255
|
-
assert parent_domain._host_size == 12
|
|
256
|
-
assert grandparent_domain._host_size == 16
|
|
257
|
-
assert greatgrandparent_domain._host_size == 20
|
|
258
|
-
events = [
|
|
259
|
-
big_subnet,
|
|
260
|
-
medium_subnet,
|
|
261
|
-
small_subnet,
|
|
262
|
-
ip_event,
|
|
263
|
-
parent_domain,
|
|
264
|
-
grandparent_domain,
|
|
265
|
-
greatgrandparent_domain,
|
|
266
|
-
]
|
|
267
|
-
random.shuffle(events)
|
|
268
|
-
assert target._sort_events(events) == [
|
|
269
|
-
big_subnet,
|
|
270
|
-
medium_subnet,
|
|
271
|
-
small_subnet,
|
|
272
|
-
ip_event,
|
|
273
|
-
parent_domain,
|
|
274
|
-
grandparent_domain,
|
|
275
|
-
greatgrandparent_domain,
|
|
276
|
-
]
|
|
297
|
+
assert target_dict["hash"] == "b36955a8238a71842fc5f23b11110c26ea07d451"
|
|
298
|
+
assert target_dict["seed_hash"] == "560af51d1f3d69bc5c156fc270b28497fe52dec1"
|
|
299
|
+
assert target_dict["whitelist_hash"] == "8ed0a7368e6d34630e1cfd419d2a73767debc4c4"
|
|
300
|
+
assert target_dict["blacklist_hash"] == "f7afa1da3422433a13f432c32cc3a99f15156e5c"
|
|
301
|
+
assert target_dict["scope_hash"] == "66e101635e33f5d234428750a0476c713070334a"
|
|
277
302
|
|
|
278
303
|
# make sure child subnets/IPs don't get added to whitelist/blacklist
|
|
279
|
-
target =
|
|
280
|
-
assert set(
|
|
281
|
-
target =
|
|
282
|
-
assert set(
|
|
283
|
-
target =
|
|
284
|
-
assert set(
|
|
285
|
-
target =
|
|
286
|
-
assert set(
|
|
304
|
+
target = RadixTarget("1.2.3.4/24", "1.2.3.4/28", acl_mode=True)
|
|
305
|
+
assert set(target) == {ip_network("1.2.3.0/24")}
|
|
306
|
+
target = RadixTarget("1.2.3.4/28", "1.2.3.4/24", acl_mode=True)
|
|
307
|
+
assert set(target) == {ip_network("1.2.3.0/24")}
|
|
308
|
+
target = RadixTarget("1.2.3.4/28", "1.2.3.4", acl_mode=True)
|
|
309
|
+
assert set(target) == {ip_network("1.2.3.0/28")}
|
|
310
|
+
target = RadixTarget("1.2.3.4", "1.2.3.4/28", acl_mode=True)
|
|
311
|
+
assert set(target) == {ip_network("1.2.3.0/28")}
|
|
287
312
|
|
|
288
313
|
# same but for domains
|
|
289
|
-
target =
|
|
290
|
-
assert set(
|
|
291
|
-
target =
|
|
292
|
-
assert set(
|
|
314
|
+
target = RadixTarget("evilcorp.com", "www.evilcorp.com", acl_mode=True)
|
|
315
|
+
assert set(target) == {"evilcorp.com"}
|
|
316
|
+
target = RadixTarget("www.evilcorp.com", "evilcorp.com", acl_mode=True)
|
|
317
|
+
assert set(target) == {"evilcorp.com"}
|
|
293
318
|
|
|
294
319
|
# make sure strict_scope doesn't mess us up
|
|
295
|
-
target =
|
|
320
|
+
target = RadixTarget("evilcorp.co.uk", "www.evilcorp.co.uk", acl_mode=True, strict_dns_scope=True)
|
|
296
321
|
assert set(target.hosts) == {"evilcorp.co.uk", "www.evilcorp.co.uk"}
|
|
297
322
|
assert "evilcorp.co.uk" in target
|
|
298
323
|
assert "www.evilcorp.co.uk" in target
|
|
@@ -300,10 +325,83 @@ async def test_target(bbot_scanner):
|
|
|
300
325
|
assert not "api.www.evilcorp.co.uk" in target
|
|
301
326
|
|
|
302
327
|
# test 'single' boolean argument
|
|
303
|
-
target =
|
|
328
|
+
target = ScanSeeds("http://evilcorp.com", "evilcorp.com:443")
|
|
304
329
|
assert "www.evilcorp.com" in target
|
|
330
|
+
assert "bob@evilcorp.com" in target
|
|
305
331
|
event = target.get("www.evilcorp.com")
|
|
306
332
|
assert event.host == "evilcorp.com"
|
|
307
333
|
events = target.get("www.evilcorp.com", single=False)
|
|
308
334
|
assert len(events) == 2
|
|
309
335
|
assert set([e.data for e in events]) == {"http://evilcorp.com/", "evilcorp.com:443"}
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
@pytest.mark.asyncio
|
|
339
|
+
async def test_blacklist_regex(bbot_scanner, bbot_httpserver):
|
|
340
|
+
|
|
341
|
+
from bbot.scanner.target import ScanBlacklist
|
|
342
|
+
|
|
343
|
+
blacklist = ScanBlacklist("evilcorp.com")
|
|
344
|
+
assert blacklist.inputs == {"evilcorp.com"}
|
|
345
|
+
assert "www.evilcorp.com" in blacklist
|
|
346
|
+
assert "http://www.evilcorp.com" in blacklist
|
|
347
|
+
blacklist.add("RE:test")
|
|
348
|
+
assert "RE:test" in blacklist.inputs
|
|
349
|
+
assert set(blacklist.inputs) == {"evilcorp.com", "RE:test"}
|
|
350
|
+
assert blacklist.blacklist_regexes
|
|
351
|
+
assert next(iter(blacklist.blacklist_regexes)).pattern == "test"
|
|
352
|
+
result1 = blacklist.get("test.com")
|
|
353
|
+
assert result1.type == "DNS_NAME"
|
|
354
|
+
assert result1.data == "test.com"
|
|
355
|
+
result2 = blacklist.get("www.evilcorp.com")
|
|
356
|
+
assert result2.type == "DNS_NAME"
|
|
357
|
+
assert result2.data == "evilcorp.com"
|
|
358
|
+
result2 = blacklist.get("www.evil.com")
|
|
359
|
+
assert result2 is None
|
|
360
|
+
with pytest.raises(KeyError):
|
|
361
|
+
blacklist.get("www.evil.com", raise_error=True)
|
|
362
|
+
assert "test.com" in blacklist
|
|
363
|
+
assert "http://evilcorp.com/test.aspx" in blacklist
|
|
364
|
+
assert not "http://tes.com" in blacklist
|
|
365
|
+
|
|
366
|
+
blacklist = ScanBlacklist("evilcorp.com", r"RE:[0-9]{6}\.aspx$")
|
|
367
|
+
assert "http://evilcorp.com" in blacklist
|
|
368
|
+
assert not "http://test.com/123456" in blacklist
|
|
369
|
+
assert not "http://test.com/12345.aspx?a=asdf" in blacklist
|
|
370
|
+
assert not "http://test.com/asdf/123456.aspx/asdf" in blacklist
|
|
371
|
+
assert "http://test.com/asdf/123456.aspx?a=asdf" in blacklist
|
|
372
|
+
assert "http://test.com/asdf/123456.aspx" in blacklist
|
|
373
|
+
|
|
374
|
+
bbot_httpserver.expect_request(uri="/").respond_with_data(
|
|
375
|
+
"""
|
|
376
|
+
<a href='http://127.0.0.1:8888/asdfevil333asdf'/>
|
|
377
|
+
<a href='http://127.0.0.1:8888/logout.aspx'/>
|
|
378
|
+
"""
|
|
379
|
+
)
|
|
380
|
+
bbot_httpserver.expect_request(uri="/asdfevilasdf").respond_with_data("")
|
|
381
|
+
bbot_httpserver.expect_request(uri="/logout.aspx").respond_with_data("")
|
|
382
|
+
|
|
383
|
+
# make sure URL is detected normally
|
|
384
|
+
scan = bbot_scanner("http://127.0.0.1:8888/", presets=["spider"], config={"excavate": True}, debug=True)
|
|
385
|
+
assert set([r.pattern for r in scan.target.blacklist.blacklist_regexes]) == {r"/.*(sign|log)[_-]?out"}
|
|
386
|
+
events = [e async for e in scan.async_start()]
|
|
387
|
+
urls = [e.data for e in events if e.type == "URL"]
|
|
388
|
+
assert len(urls) == 2
|
|
389
|
+
assert set(urls) == {"http://127.0.0.1:8888/", "http://127.0.0.1:8888/asdfevil333asdf"}
|
|
390
|
+
|
|
391
|
+
# same scan again but with blacklist regex
|
|
392
|
+
scan = bbot_scanner(
|
|
393
|
+
"http://127.0.0.1:8888/",
|
|
394
|
+
blacklist=[r"RE:evil[0-9]{3}"],
|
|
395
|
+
presets=["spider"],
|
|
396
|
+
config={"excavate": True},
|
|
397
|
+
debug=True,
|
|
398
|
+
)
|
|
399
|
+
assert scan.target.blacklist.blacklist_regexes
|
|
400
|
+
assert set([r.pattern for r in scan.target.blacklist.blacklist_regexes]) == {
|
|
401
|
+
r"evil[0-9]{3}",
|
|
402
|
+
r"/.*(sign|log)[_-]?out",
|
|
403
|
+
}
|
|
404
|
+
events = [e async for e in scan.async_start()]
|
|
405
|
+
urls = [e.data for e in events if e.type == "URL"]
|
|
406
|
+
assert len(urls) == 1
|
|
407
|
+
assert set(urls) == {"http://127.0.0.1:8888/"}
|
|
@@ -44,7 +44,7 @@ class TestDastardly(ModuleTestBase):
|
|
|
44
44
|
|
|
45
45
|
# get docker IP
|
|
46
46
|
docker_ip = await self.get_docker_ip(module_test)
|
|
47
|
-
module_test.scan.target.add(docker_ip)
|
|
47
|
+
module_test.scan.target.seeds.add(docker_ip)
|
|
48
48
|
|
|
49
49
|
# replace 127.0.0.1 with docker host IP to allow dastardly access to local http server
|
|
50
50
|
old_filter_event = module_test.module.filter_event
|
|
@@ -142,7 +142,7 @@ class TestFFUFShortnames(ModuleTestBase):
|
|
|
142
142
|
tags=["shortname-file"],
|
|
143
143
|
)
|
|
144
144
|
)
|
|
145
|
-
module_test.scan.target.seeds.
|
|
145
|
+
module_test.scan.target.seeds.events = set(seed_events)
|
|
146
146
|
|
|
147
147
|
expect_args = {"method": "GET", "uri": "/administrator.aspx"}
|
|
148
148
|
respond_args = {"response_data": "alive"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: bbot
|
|
3
|
-
Version: 2.2.0.
|
|
3
|
+
Version: 2.2.0.5311rc0
|
|
4
4
|
Summary: OSINT automation for hackers.
|
|
5
5
|
Home-page: https://github.com/blacklanternsecurity/bbot
|
|
6
6
|
License: GPL-3.0
|
|
7
|
-
Keywords: python,cli,automation,osint,neo4j,scanner,python-library,hacking,recursion,pentesting,recon,command-line-tool,bugbounty,subdomains,security-tools,subdomain-scanner,osint-framework,attack-surface,subdomain-enumeration,osint-tool
|
|
7
|
+
Keywords: python,cli,automation,osint,threat-intel,intelligence,neo4j,scanner,python-library,hacking,recursion,pentesting,recon,command-line-tool,bugbounty,subdomains,security-tools,subdomain-scanner,osint-framework,attack-surface,subdomain-enumeration,osint-tool
|
|
8
8
|
Author: TheTechromancer
|
|
9
9
|
Requires-Python: >=3.9,<4.0
|
|
10
10
|
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
@@ -20,7 +20,7 @@ Requires-Dist: ansible (>=7.3,<9.0)
|
|
|
20
20
|
Requires-Dist: ansible-runner (>=2.3.2,<3.0.0)
|
|
21
21
|
Requires-Dist: beautifulsoup4 (>=4.12.2,<5.0.0)
|
|
22
22
|
Requires-Dist: cachetools (>=5.3.2,<6.0.0)
|
|
23
|
-
Requires-Dist: cloudcheck (>=
|
|
23
|
+
Requires-Dist: cloudcheck (>=6.0.0.602,<7.0.0.0)
|
|
24
24
|
Requires-Dist: deepdiff (>=6.2.3,<8.0.0)
|
|
25
25
|
Requires-Dist: dnspython (>=2.4.2,<3.0.0)
|
|
26
26
|
Requires-Dist: httpx (>=0.27.0,<0.28.0)
|
|
@@ -35,7 +35,7 @@ Requires-Dist: pycryptodome (>=3.17,<4.0)
|
|
|
35
35
|
Requires-Dist: pydantic (>=2.4.2,<3.0.0)
|
|
36
36
|
Requires-Dist: pyjwt (>=2.7.0,<3.0.0)
|
|
37
37
|
Requires-Dist: pyzmq (>=26.0.3,<27.0.0)
|
|
38
|
-
Requires-Dist: radixtarget (>=
|
|
38
|
+
Requires-Dist: radixtarget (>=2.0.0.50,<3.0.0.0)
|
|
39
39
|
Requires-Dist: regex (>=2024.4.16,<2025.0.0)
|
|
40
40
|
Requires-Dist: setproctitle (>=1.3.3,<2.0.0)
|
|
41
41
|
Requires-Dist: socksio (>=1.0.0,<2.0.0)
|