@@ -323,7 +323,10 @@ def run_template(ctx: click.Context, template_path: str, target: str | None) ->
323323
324324@main .command ("bulk" )
325325@click .argument ("sources" , nargs = - 1 )
326- @click .option ("--shodan" , "shodan_query" , default = None , help = "Shodan search query (requires ARGUS_SHODAN_KEY)" )
326+ @click .option ("--shodan" , "shodan_query" , default = None , help = "Shodan query (requires ARGUS_SHODAN_KEY)" )
327+ @click .option ("--censys" , "censys_query" , default = None , help = "Censys query (requires ARGUS_CENSYS_ID + ARGUS_CENSYS_SECRET)" )
328+ @click .option ("--zoomeye" , "zoomeye_query" , default = None , help = "ZoomEye dork (requires ARGUS_ZOOMEYE_KEY)" )
329+ @click .option ("--fofa" , "fofa_query" , default = None , help = "FOFA query (requires ARGUS_FOFA_EMAIL + ARGUS_FOFA_KEY)" )
327330@click .option ("--preset" , type = click .Choice (["bulk" , "quick" , "web" , "full" , "recon" ]), default = "bulk" ,
328331 help = "Scan preset for each target" )
329332@click .option ("--concurrency" , type = int , default = 5 , help = "Max parallel scans" )
@@ -333,21 +336,27 @@ def run_template(ctx: click.Context, template_path: str, target: str | None) ->
333336def bulk_scan (
334337 sources : tuple [str , ...],
335338 shodan_query : str | None ,
339+ censys_query : str | None ,
340+ zoomeye_query : str | None ,
341+ fofa_query : str | None ,
336342 preset : str ,
337343 concurrency : int ,
338344 max_targets : int ,
339345 output_format : str ,
340346 no_confirm : bool ,
341347) -> None :
342- """Bulk scan multiple targets: files, CIDRs, ASNs, or Shodan queries.
348+ """Bulk scan multiple targets: files, CIDRs, ASNs, or OSINT queries.
343349
344350 \b
345351 Examples:
346352 argus bulk targets.txt
347353 argus bulk 192.168.1.0/24
348354 argus bulk AS12345
349355 argus bulk targets.txt 10.0.1.0/24 --preset web
350- argus bulk --shodan "org:MyCompany" --concurrency 3
356+ argus bulk --shodan "org:MyCompany"
357+ argus bulk --censys "services.port:443 AND labels:cloud"
358+ argus bulk --zoomeye "hostname:example.com"
359+ argus bulk --fofa 'domain="example.com"'
351360
352361 Generates individual reports per target + a combined summary.html.
353362 IMPORTANT: Only scan systems you have written permission to test.
@@ -371,25 +380,34 @@ def bulk_scan(
371380 config .bulk .max_concurrent = concurrency
372381 config .bulk .max_targets = max_targets
373382
374- # Build source list
375- all_sources = list (sources )
376- if shodan_query :
377- # Shodan handled via expand_shodan() separately
378- all_sources_for_expand = list (sources )
379- else :
380- all_sources_for_expand = all_sources
383+ has_query = any ([shodan_query , censys_query , zoomeye_query , fofa_query ])
381384
382- if not all_sources_for_expand and not shodan_query :
385+ if not sources and not has_query :
383386 console .print ("[red]No sources provided. Use positional args or --shodan.[/red]" )
384387 raise SystemExit (1 )
385388
386389 # Expand targets
387390 expander = TargetExpander (config )
388- if shodan_query :
389- targets = asyncio .get_event_loop ().run_until_complete (expander .expand_shodan (shodan_query ))
391+ targets : list [str ] = []
392+
393+ # Expand positional sources (file, CIDR, ASN, plain hosts)
394+ if sources :
390395 targets += asyncio .get_event_loop ().run_until_complete (expander .expand (list (sources )))
391- else :
392- targets = asyncio .get_event_loop ().run_until_complete (expander .expand (all_sources_for_expand ))
396+
397+ # Expand OSINT queries
398+ loop = asyncio .get_event_loop ()
399+ if shodan_query :
400+ console .print (f"[dim]Querying Shodan: { shodan_query } [/dim]" )
401+ targets += loop .run_until_complete (expander .expand_shodan (shodan_query ))
402+ if censys_query :
403+ console .print (f"[dim]Querying Censys: { censys_query } [/dim]" )
404+ targets += loop .run_until_complete (expander .expand_censys (censys_query ))
405+ if zoomeye_query :
406+ console .print (f"[dim]Querying ZoomEye: { zoomeye_query } [/dim]" )
407+ targets += loop .run_until_complete (expander .expand_zoomeye (zoomeye_query ))
408+ if fofa_query :
409+ console .print (f"[dim]Querying FOFA: { fofa_query } [/dim]" )
410+ targets += loop .run_until_complete (expander .expand_fofa (fofa_query ))
393411
394412 # Deduplicate & cap
395413 seen : set [str ] = set ()
0 commit comments