96 lines
3.0 KiB
Go
96 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"github.com/s-rah/onionscan/config"
|
|
"github.com/s-rah/onionscan/report"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
func main() {
|
|
|
|
flag.Usage = func() {
|
|
fmt.Printf("Usage of %s:\n", os.Args[0])
|
|
fmt.Printf(" onionscan [flags] hiddenservice | onionscan [flags] --list list\n")
|
|
flag.PrintDefaults()
|
|
}
|
|
|
|
torProxyAddress := flag.String("torProxyAddress", "127.0.0.1:9050", "the address of the tor proxy to use")
|
|
simpleReport := flag.Bool("simpleReport", true, "print out a simple report detailing what is wrong and how to fix it, true by default")
|
|
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")
|
|
jsonReport := flag.Bool("jsonReport", false, "print out a json report providing a detailed report of the scan.")
|
|
verbose := flag.Bool("verbose", false, "print out a verbose log output of the scan")
|
|
directoryDepth := flag.Int("depth", 100, "depth of directory scan recursion (default: 100)")
|
|
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.")
|
|
list := flag.String("list", "", "If provided OnionScan will attempt to read from the given list, rather than the provided hidden service")
|
|
timeout := flag.Int("timeout", 120, "read timeout for connecting to onion services")
|
|
|
|
flag.Parse()
|
|
|
|
if len(flag.Args()) != 1 && *list == "" {
|
|
flag.Usage()
|
|
os.Exit(1)
|
|
}
|
|
|
|
if !*simpleReport && !*jsonReport {
|
|
log.Fatalf("You must set one of --simpleReport or --jsonReport")
|
|
}
|
|
|
|
onionsToScan := []string{}
|
|
if *list == "" {
|
|
onionsToScan = append(onionsToScan, flag.Args()[0])
|
|
log.Printf("Starting Scan of %s\n", flag.Args()[0])
|
|
} else {
|
|
content, err := ioutil.ReadFile(*list)
|
|
if err != nil {
|
|
log.Fatalf("Could not read onion file %s\n", *list)
|
|
}
|
|
onions := strings.Split(string(content), "\n")
|
|
onionsToScan = append(onionsToScan, onions...)
|
|
log.Printf("Starting Scan of %d onion services\n", len(onionsToScan)-1)
|
|
}
|
|
log.Printf("This might take a few minutes..\n\n")
|
|
|
|
onionScan := new(OnionScan)
|
|
onionScan.Config = config.Configure(*torProxyAddress, *directoryDepth, *fingerprint, *timeout)
|
|
|
|
reports := make(chan *report.OnionScanReport)
|
|
|
|
if !*verbose {
|
|
log.SetOutput(ioutil.Discard)
|
|
}
|
|
|
|
count := 0
|
|
max := 100
|
|
if max > len(onionsToScan)-1 {
|
|
max = len(onionsToScan) - 1
|
|
}
|
|
|
|
// Run an initial batch of 100 requests (or less...)
|
|
for count < max {
|
|
go onionScan.Scan(onionsToScan[count], reports)
|
|
count++
|
|
}
|
|
|
|
received := 0
|
|
for received < len(onionsToScan)-1 {
|
|
scanReport := <-reports
|
|
// After the initial batch, it's one in one out to prevent proxy overload.
|
|
if count < len(onionsToScan)-1 {
|
|
go onionScan.Scan(onionsToScan[count], reports)
|
|
count++
|
|
}
|
|
received++
|
|
|
|
if *jsonReport {
|
|
report.GenerateJsonReport(*reportFile, scanReport)
|
|
} else if *simpleReport {
|
|
report.GenerateSimpleReport(*reportFile, scanReport)
|
|
}
|
|
}
|
|
}
|