@@ -27,16 +27,30 @@ def fatal(msg, return_code=-1):
2727 exit (return_code )
2828
2929
30- def print_subdomain_result (url , ip , http_connection_headers = None , nearby = None , stream = sys .stdout ):
31- print ("Found: {} ({})" .format (url , ip ), file = stream )
30+ def print_subdomain_result (url , ip , http_connection_headers = None , nearby = None , stream = sys .stdout , printOutput = True ):
31+ if not printOutput :
32+ output = {}
33+ output ["subdomains" ] = {}
34+ output ["subdomains" ]["http" ] = ""
35+ output ["subdomains" ]["nearby" ] = ""
36+ if printOutput :
37+ print ("Found: {} ({})" .format (url , ip ), file = stream )
38+ else :
39+ output ["subdomains" ][url ] = ip
3240
3341 if http_connection_headers :
34- print ("HTTP connected:" , file = stream )
35- pprint .pprint (http_connection_headers , stream = stream )
42+ if printOutput :
43+ print ("HTTP connected:" , file = stream )
44+ pprint .pprint (http_connection_headers , stream = stream )
45+ else :
46+ output ["subdomains" ]["http" ]["url" ] = http_connection_headers
3647
3748 if nearby :
38- print ("Nearby:" , file = stream )
39- pprint .pprint (nearby , stream = stream )
49+ if printOutput :
50+ print ("Nearby:" , file = stream )
51+ pprint .pprint (nearby , stream = stream )
52+ else :
53+ output ["subdomains" ]["nearby" ] = nearby
4054
4155
4256def unvisited_closure ():
@@ -281,6 +295,10 @@ def update_resolver_nameservers(resolver, nameservers, nameserver_filename):
281295
282296
283297def fierce (** kwargs ):
298+ printOutput = kwargs .get ("printOutput" , True )
299+ if not printOutput :
300+ output = {}
301+
284302 resolver = dns .resolver .Resolver ()
285303
286304 resolver = update_resolver_nameservers (
@@ -295,12 +313,17 @@ def fierce(**kwargs):
295313 resolver ,
296314 range_ips ,
297315 )
298- if nearby :
316+ if nearby and printOutput :
299317 print ("Nearby:" )
300318 pprint .pprint (nearby )
319+ else :
320+ output ["nearby" ] = nearby
301321
302322 if not kwargs .get ("domain" ):
303- return
323+ if not printOutput :
324+ return
325+ else :
326+ return output
304327
305328 domain = dns .name .from_text (kwargs ['domain' ])
306329 if not domain .is_absolute ():
@@ -313,35 +336,59 @@ def fierce(**kwargs):
313336 else :
314337 domain_name_servers = []
315338
316- print ("NS: {}" .format (" " .join (domain_name_servers ) if ns else "failure" ))
339+ if printOutput :
340+ print ("NS: {}" .format (" " .join (domain_name_servers ) if ns else "failure" ))
341+ else :
342+ output ["NS" ] = " " .join (domain_name_servers ) if ns else "failure"
317343
318344 soa = recursive_query (resolver , domain , record_type = 'SOA' , tcp = kwargs ["tcp" ])
319345 if soa :
320346 soa_mname = soa [0 ].mname
321347 master = query (resolver , soa_mname , record_type = 'A' , tcp = kwargs ["tcp" ])
322348 master_address = master [0 ].address
323- print ("SOA: {} ({})" .format (soa_mname , master_address ))
349+ if printOutput :
350+ print ("SOA: {} ({})" .format (soa_mname , master_address ))
351+ else :
352+ output ["SOA" ] = "{} ({})" .format (soa_mname , master_address )
324353 else :
325- print ("SOA: failure" )
326- fatal ("Failed to lookup NS/SOA, Domain does not exist" )
354+ if printOutput :
355+ print ("SOA: failure" )
356+ fatal ("Failed to lookup NS/SOA, Domain does not exist" )
357+ else :
358+ output ["SOA" ] = "Failed to lookup NS/SOA, Domain does not exist"
359+ return output
327360
328361 zone = zone_transfer (master_address , domain )
329- print ("Zone: {}" .format ("success" if zone else "failure" ))
362+ if printOutput :
363+ print ("Zone: {}" .format ("success" if zone else "failure" ))
364+ elif not zone :
365+ output ["zone" ] = "failure"
330366 if zone :
331- pprint .pprint ({k : v .to_text (k ) for k , v in zone .items ()})
332- return
367+ if printOutput :
368+ pprint .pprint ({k : v .to_text (k ) for k , v in zone .items ()})
369+ return
370+ else :
371+ output ["zone" ] = {}
372+ for k , v in zone .items ():
373+ key = k .to_unicode ()
374+ output ["zone" ][key ] = {}
375+ output ["zone" ][key ] = v .to_text (k ).split ('\n ' )
376+ return output
333377
334378 random_subdomain = str (random .randint (1e10 , 1e11 )) # noqa DUO102, non-cryptographic random use
335379 random_domain = concatenate_subdomains (domain , [random_subdomain ])
336380 wildcard = query (resolver , random_domain , record_type = 'A' , tcp = kwargs ["tcp" ])
337381 wildcard_ips = set (rr .address for rr in wildcard .rrset ) if wildcard else set ()
338- print ("Wildcard: {}" .format (', ' .join (wildcard_ips ) if wildcard_ips else "failure" ))
382+ wildcard = query (resolver , random_domain , record_type = 'A' )
383+ if printOutput :
384+ print ("Wildcard: {}" .format (', ' .join (wildcard_ips ) if wildcard_ips else "failure" ))
385+ else :
386+ output ["Wildcard" ] = wildcard_ips if wildcard else "failure"
339387
340388 subdomains = get_subdomains (
341389 kwargs ["subdomains" ],
342390 kwargs ["subdomain_file" ]
343391 )
344-
345392 filter_func = None
346393 if kwargs .get ("search" ):
347394 filter_func = functools .partial (search_filter , kwargs ["search" ])
@@ -353,7 +400,6 @@ def fierce(**kwargs):
353400 expander_func = functools .partial (traverse_expander , n = kwargs ["traverse" ])
354401
355402 unvisited = unvisited_closure ()
356-
357403 for subdomain in subdomains :
358404 url = concatenate_subdomains (domain , [subdomain ])
359405 record = query (resolver , url , record_type = 'A' , tcp = kwargs ["tcp" ])
@@ -380,15 +426,22 @@ def fierce(**kwargs):
380426 filter_func = filter_func
381427 )
382428
429+ # TODO: Add this to lib
383430 print_subdomain_result (
384431 url ,
385432 ip ,
386433 http_connection_headers = http_connection_headers ,
387434 nearby = nearby
388435 )
436+ if "subdomains" not in output .keys ():
437+ output ["subdomains" ] = {}
438+ if not printOutput :
439+ output ["subdomains" ][url .to_text ()] = record .response .answer [0 ].to_text ()
389440
390441 if kwargs .get ("delay" ):
391442 time .sleep (kwargs ["delay" ])
443+ if not printOutput :
444+ return output
392445
393446
394447def parse_args (args ):
0 commit comments