From 56c267c66e8b8e4c536bece03a7012f275d186e7 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Sun, 5 Jun 2016 11:54:01 -0700 Subject: [PATCH] FTP,SMTP,VNC Fingerprints --- config/onionscan_config.go | 6 ++--- main.go | 12 +++++---- onionscan.go | 8 ++++-- protocol/ftp_scanner.go | 15 +++++++++-- protocol/http_scanner.go | 13 +++++---- protocol/smtp_scanner.go | 13 ++++++++- protocol/vnc_scanner.go | 26 ++++++++++++++++++ report/onionscanreport.go | 54 ++++++++++++++++++++++--------------- scans/standard-page-scan.go | 2 ++ 9 files changed, 110 insertions(+), 39 deletions(-) create mode 100644 protocol/vnc_scanner.go diff --git a/config/onionscan_config.go b/config/onionscan_config.go index d34308e..fffcdb9 100644 --- a/config/onionscan_config.go +++ b/config/onionscan_config.go @@ -1,15 +1,15 @@ package config -import () - type OnionscanConfig struct { TorProxyAddress string DirectoryDepth int + Fingerprint bool } -func Configure(torProxyAddress string, directoryDepth int) *OnionscanConfig { +func Configure(torProxyAddress string, directoryDepth int, fingerprint bool) *OnionscanConfig { onionScan := new(OnionscanConfig) onionScan.TorProxyAddress = torProxyAddress onionScan.DirectoryDepth = directoryDepth + onionScan.Fingerprint = fingerprint return onionScan } diff --git a/main.go b/main.go index 70f1d48..f968672 100644 --- a/main.go +++ b/main.go @@ -24,6 +24,7 @@ func main() { 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, "whether to conduct a full scan, or just fingerprint possible ports") flag.Parse() @@ -42,13 +43,9 @@ func main() { } onionScan := new(OnionScan) - onionScan.Config = config.Configure(*torProxyAddress, *directoryDepth) + onionScan.Config = config.Configure(*torProxyAddress, *directoryDepth, *fingerprint) scanReport, err := onionScan.Scan(hiddenService) - if err != nil { - log.Fatalf("Error running scanner: %s", err) - } - if *jsonReport { report.GenerateJsonReport(*reportFile, scanReport) } @@ -56,4 +53,9 @@ func main() { if *simpleReport { report.GenerateSimpleReport(*reportFile, scanReport) } + + if !*jsonReport && err != nil { + log.Fatalf("Error running scanner: %s", err) + } + } diff --git a/onionscan.go b/onionscan.go index 2ab23da..98444cb 100644 --- a/onionscan.go +++ b/onionscan.go @@ -2,11 +2,11 @@ package main import ( "errors" - "fmt" "github.com/s-rah/onionscan/config" "github.com/s-rah/onionscan/protocol" "github.com/s-rah/onionscan/report" "github.com/s-rah/onionscan/utils" + "log" "strings" ) @@ -57,8 +57,12 @@ func (os *OnionScan) Scan(hiddenService string) (*report.OnionScanReport, error) mdbps := new(protocol.MongoDBProtocolScanner) mdbps.ScanProtocol(hiddenService, os.Config, report) + //VNC + vncps := new(protocol.VNCProtocolScanner) + vncps.ScanProtocol(hiddenService, os.Config, report) + if !report.WebDetected && !report.SSHDetected && !report.RicochetDetected && !report.BitcoinDetected && !report.IRCDetected && !report.FTPDetected && !report.SMTPDetected && !report.MongoDBDetected { - fmt.Printf("Unable to connect to this Tor Hidden Service on any known protocol.\n") + log.Printf("Unable to connect to this Tor Hidden Service on any known protocol.\n") return nil, errors.New("Unable to connect to this Tor Hidden Service on any known protocol.") } diff --git a/protocol/ftp_scanner.go b/protocol/ftp_scanner.go index 37a807f..92d7108 100644 --- a/protocol/ftp_scanner.go +++ b/protocol/ftp_scanner.go @@ -1,6 +1,9 @@ package protocol import ( + "bufio" + "crypto/sha1" + "encoding/hex" "github.com/s-rah/onionscan/config" "github.com/s-rah/onionscan/report" "h12.me/socks" @@ -12,14 +15,22 @@ type FTPProtocolScanner struct { func (sps *FTPProtocolScanner) ScanProtocol(hiddenService string, onionscanConfig *config.OnionscanConfig, report *report.OnionScanReport) { // FTP - log.Printf("Checking %s FTP(22)\n", hiddenService) - _, err := socks.DialSocksProxy(socks.SOCKS5, onionscanConfig.TorProxyAddress)("", hiddenService+":21") + log.Printf("Checking %s FTP(21)\n", hiddenService) + conn, err := socks.DialSocksProxy(socks.SOCKS5, onionscanConfig.TorProxyAddress)("", hiddenService+":21") if err != nil { log.Printf("Failed to connect to service on port 21\n") report.FTPDetected = false } else { // TODO FTP Checking report.FTPDetected = true + reader := bufio.NewReader(conn) + banner, err := reader.ReadString('\n') + if err == nil { + report.FTPBanner = banner + hash := sha1.Sum([]byte(banner)) + report.FTPFingerprint = hex.EncodeToString(hash[:]) + log.Printf("Found FTP Banner: %s (%s)", banner, report.FTPFingerprint) + } } } diff --git a/protocol/http_scanner.go b/protocol/http_scanner.go index 29396e4..1b487e9 100644 --- a/protocol/http_scanner.go +++ b/protocol/http_scanner.go @@ -65,11 +65,14 @@ func (hps *HTTPProtocolScanner) ScanProtocol(hiddenService string, onionscanConf hps.ScanPage(hiddenService, "/server-status", report, scans.ApacheModStatus) hps.ScanPage(hiddenService, "/", report, scans.StandardPageScan) - log.Printf("\tScanning Common and Referenced Directories\n") - directories := append(CommonDirectories, report.PageReferencedDirectories...) - utils.RemoveDuplicates(&directories) - for _, directory := range directories { - hps.ScanPage(hiddenService, directory, report, scans.CheckDirectoryListing(onionscanConfig.DirectoryDepth)) + if onionscanConfig.Fingerprint == false { + log.Printf("\tScanning Common and Referenced Directories\n") + directories := append(CommonDirectories, report.PageReferencedDirectories...) + utils.RemoveDuplicates(&directories) + + for _, directory := range directories { + hps.ScanPage(hiddenService, directory, report, scans.CheckDirectoryListing(onionscanConfig.DirectoryDepth)) + } } } log.Printf("\n") diff --git a/protocol/smtp_scanner.go b/protocol/smtp_scanner.go index 08328fa..2267a34 100644 --- a/protocol/smtp_scanner.go +++ b/protocol/smtp_scanner.go @@ -1,6 +1,9 @@ package protocol import ( + "bufio" + "crypto/sha1" + "encoding/hex" "github.com/s-rah/onionscan/config" "github.com/s-rah/onionscan/report" "h12.me/socks" @@ -13,13 +16,21 @@ type SMTPProtocolScanner struct { func (sps *SMTPProtocolScanner) ScanProtocol(hiddenService string, onionscanConfig *config.OnionscanConfig, report *report.OnionScanReport) { // SMTP log.Printf("Checking %s SMTP(25)\n", hiddenService) - _, err := socks.DialSocksProxy(socks.SOCKS5, onionscanConfig.TorProxyAddress)("", hiddenService+":25") + conn, err := socks.DialSocksProxy(socks.SOCKS5, onionscanConfig.TorProxyAddress)("", hiddenService+":25") if err != nil { log.Printf("Failed to connect to service on port 25\n") report.SMTPDetected = false } else { // TODO SMTP Checking report.SMTPDetected = true + reader := bufio.NewReader(conn) + banner, err := reader.ReadString('\n') + if err == nil { + report.SMTPBanner = banner + hash := sha1.Sum([]byte(banner)) + report.SMTPFingerprint = hex.EncodeToString(hash[:]) + log.Printf("Found SMTP Banner: %s (%s)", banner, report.SMTPFingerprint) + } } } diff --git a/protocol/vnc_scanner.go b/protocol/vnc_scanner.go new file mode 100644 index 0000000..d94f03b --- /dev/null +++ b/protocol/vnc_scanner.go @@ -0,0 +1,26 @@ +package protocol + +import ( + "github.com/s-rah/onionscan/config" + "github.com/s-rah/onionscan/report" + "h12.me/socks" + "log" +) + +type VNCProtocolScanner struct { +} + +func (vncps *VNCProtocolScanner) ScanProtocol(hiddenService string, onionscanConfig *config.OnionscanConfig, report *report.OnionScanReport) { + // MongoDB + log.Printf("Checking %s VNC(5900)\n", hiddenService) + _, err := socks.DialSocksProxy(socks.SOCKS5, onionscanConfig.TorProxyAddress)("", hiddenService+":5900") + if err != nil { + log.Printf("Failed to connect to service on port 5900\n") + report.VNCDetected = false + } else { + log.Printf("Detected possible VNC instance\n") + // TODO: Actual Analysis + report.VNCDetected = true + } + +} diff --git a/report/onionscanreport.go b/report/onionscanreport.go index 16b98eb..030bdc5 100644 --- a/report/onionscanreport.go +++ b/report/onionscanreport.go @@ -17,36 +17,48 @@ type ExifImage struct { } type OnionScanReport struct { + HiddenService string `json:"hiddenService"` + + // Summary WebDetected bool `json:"webDetected"` SSHDetected bool `json:"sshDetected"` RicochetDetected bool `json:"ricochetDetected"` IRCDetected bool `json:"ircDetected"` FTPDetected bool `json:"ftpDetected"` SMTPDetected bool `json:"smtpDetected"` + BitcoinDetected bool `json:"bitcoinDetected"` + MongoDBDetected bool `json:"mongodbDetected"` + VNCDetected bool `json:"vncDetected"` - BitcoinDetected bool `json:"bitcoinDetected"` - MongoDBDetected bool `json:"mongodbDetected"` + // Web Specific + ServerPoweredBy string `json:"serverPoweredBy"` + ServerVersion string `json:"serverVersion"` + FoundApacheModStatus bool `json:"foundApacheModStatus"` + RelatedOnionServices []string `json:"relatedOnionServices"` + RelatedClearnetDomains []string `json:"relatedOnionDomains"` + LinkedSites []string `json:"linkedSites"` + InternalPages []string `json:"internalPages"` + IP []string `json:"ipAddresses"` + OpenDirectories []string `json:"openDirectories"` + ExifImages []ExifImage `json:"exifImages"` + InterestingFiles []string `json:"interestingFiles"` + PageReferencedDirectories []string `json:"pageReferencedDirectories"` + PGPKeys []string `json:"pgpKeys"` + Hashes []string `json:"hashes"` + Snapshot string `json:"snapshot"` + PageTitle string `json:"pageTitle"` + ResponseHeaders map[string]string `json:"responseHeaders"` - HiddenService string `json:"hiddenService"` - ServerPoweredBy string `json:"serverPoweredBy"` - ServerVersion string `json:"serverVersion"` - FoundApacheModStatus bool `json:"foundApacheModStatus"` - RelatedOnionServices []string `json:"relatedOnionServices"` - RelatedClearnetDomains []string `json:"relatedOnionDomains"` - LinkedSites []string `json:"linkedSites"` - InternalPages []string `json:"InternalPages"` - IP []string `json:"ipAddresses"` - OpenDirectories []string `json:"openDirectories"` - ExifImages []ExifImage `json:"exifImages"` - InterestingFiles []string `json:"interestingFiles"` - PageReferencedDirectories []string `json:"pageReferencedDirectories"` - PGPKeys []string `json:"pgpKeys"` + // SSH + SSHKey string `json:"sshKey"` - Hashes []string `json:"hashes"` - SSHKey string `json:"sshKey"` - Snapshot string `json:"snapshot"` - PageTitle string `json:"pageTitle"` - ResponseHeaders map[string]string `json:"responseHeaders"` + // FTP + FTPFingerprint string `json:"ftpFingerprint"` + FTPBanner string `json:"ftpBanner"` + + // SMTP + SMTPFingerprint string `json:"smtpFingerprint"` + SMTPBanner string `json:"smtpBanner"` } func LoadReportFromFile(filename string) (OnionScanReport, error) { diff --git a/scans/standard-page-scan.go b/scans/standard-page-scan.go index 3679e87..db44c5f 100644 --- a/scans/standard-page-scan.go +++ b/scans/standard-page-scan.go @@ -79,6 +79,7 @@ func StandardPageScan(scan Scanner, page string, status int, contents string, re } log.Printf("\tScanning for CSS Fonts and Background Images\n") + utils.RemoveDuplicates(&cssLinks) for _, cssUrl := range cssLinks { log.Printf("\tScanning CSS file: %s\n", cssUrl) _, cssContents, _ := scan.ScrapePage(report.HiddenService, utils.WithoutProtocol(cssUrl)) @@ -87,6 +88,7 @@ func StandardPageScan(scan Scanner, page string, status int, contents string, re log.Printf("\tScanning for Links\n") domains = append(domains, utils.ExtractDomains(contents)...) + utils.RemoveDuplicates(&domains) for _, domain := range domains { baseUrl, _ := url.Parse(domain) if baseUrl.Host != "" && utils.WithoutSubdomains(baseUrl.Host) != utils.WithoutSubdomains(report.HiddenService) {