You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
3.3 KiB

  1. package main
  2. import (
  3. "errors"
  4. "flag"
  5. "fmt"
  6. "github.com/s-rah/onionscan/config"
  7. "github.com/s-rah/onionscan/report"
  8. "io/ioutil"
  9. "log"
  10. "os"
  11. "strings"
  12. )
  13. func main() {
  14. flag.Usage = func() {
  15. fmt.Printf("Usage of %s:\n", os.Args[0])
  16. fmt.Printf(" onionscan [flags] hiddenservice | onionscan [flags] --list list\n")
  17. flag.PrintDefaults()
  18. }
  19. torProxyAddress := flag.String("torProxyAddress", "127.0.0.1:9050", "the address of the tor proxy to use")
  20. simpleReport := flag.Bool("simpleReport", true, "print out a simple report detailing what is wrong and how to fix it, true by default")
  21. reportFile := flag.String("reportFile", "", "the file destination path for report file - if given, the prefix of the file will be the scanned onion service. If not given, the report will be written to stdout")
  22. jsonReport := flag.Bool("jsonReport", false, "print out a json report providing a detailed report of the scan.")
  23. verbose := flag.Bool("verbose", false, "print out a verbose log output of the scan")
  24. directoryDepth := flag.Int("depth", 100, "depth of directory scan recursion (default: 100)")
  25. fingerprint := flag.Bool("fingerprint", true, "true disables some deeper scans e.g. directory probing with the aim of just getting a fingerprint of the service.")
  26. list := flag.String("list", "", "If provided OnionScan will attempt to read from the given list, rather than the provided hidden service")
  27. timeout := flag.Int("timeout", 120, "read timeout for connecting to onion services")
  28. batch := flag.Int("batch", 10, "number of onions to scan concurrently")
  29. flag.Parse()
  30. if len(flag.Args()) != 1 && *list == "" {
  31. flag.Usage()
  32. os.Exit(1)
  33. }
  34. if !*simpleReport && !*jsonReport {
  35. log.Fatalf("You must set one of --simpleReport or --jsonReport")
  36. }
  37. onionsToScan := []string{}
  38. if *list == "" {
  39. onionsToScan = append(onionsToScan, flag.Args()[0])
  40. log.Printf("Starting Scan of %s\n", flag.Args()[0])
  41. } else {
  42. content, err := ioutil.ReadFile(*list)
  43. if err != nil {
  44. log.Fatalf("Could not read onion file %s\n", *list)
  45. }
  46. onions := strings.Split(string(content), "\n")
  47. for _, onion := range onions[0 : len(onions)-1] {
  48. onionsToScan = append(onionsToScan, onion)
  49. }
  50. log.Printf("Starting Scan of %d onion services\n", len(onionsToScan))
  51. }
  52. log.Printf("This might take a few minutes..\n\n")
  53. onionScan := new(OnionScan)
  54. onionScan.Config = config.Configure(*torProxyAddress, *directoryDepth, *fingerprint, *timeout, *verbose)
  55. reports := make(chan *report.OnionScanReport)
  56. count := 0
  57. if *batch > len(onionsToScan) {
  58. *batch = len(onionsToScan)
  59. }
  60. // Run an initial batch of 100 requests (or less...)
  61. for count < *batch {
  62. go onionScan.Scan(onionsToScan[count], reports)
  63. count++
  64. }
  65. received := 0
  66. for received < len(onionsToScan) {
  67. scanReport := <-reports
  68. // After the initial batch, it's one in one out to prevent proxy overload.
  69. if count < len(onionsToScan) {
  70. go onionScan.Scan(onionsToScan[count], reports)
  71. count++
  72. }
  73. received++
  74. if scanReport.TimedOut {
  75. onionScan.Config.LogError(errors.New(scanReport.HiddenService + " timed out"))
  76. }
  77. file := *reportFile
  78. if file != "" {
  79. file = scanReport.HiddenService + "." + *reportFile
  80. }
  81. if *jsonReport {
  82. report.GenerateJsonReport(file, scanReport)
  83. } else if *simpleReport {
  84. report.GenerateSimpleReport(file, scanReport)
  85. }
  86. }
  87. }