FTP,SMTP,VNC Fingerprints

This commit is contained in:
Sarah Jamie Lewis 2016-06-05 11:54:01 -07:00
parent 49095c586a
commit 56c267c66e
9 changed files with 110 additions and 39 deletions

View File

@ -1,15 +1,15 @@
package config package config
import ()
type OnionscanConfig struct { type OnionscanConfig struct {
TorProxyAddress string TorProxyAddress string
DirectoryDepth int DirectoryDepth int
Fingerprint bool
} }
func Configure(torProxyAddress string, directoryDepth int) *OnionscanConfig { func Configure(torProxyAddress string, directoryDepth int, fingerprint bool) *OnionscanConfig {
onionScan := new(OnionscanConfig) onionScan := new(OnionscanConfig)
onionScan.TorProxyAddress = torProxyAddress onionScan.TorProxyAddress = torProxyAddress
onionScan.DirectoryDepth = directoryDepth onionScan.DirectoryDepth = directoryDepth
onionScan.Fingerprint = fingerprint
return onionScan return onionScan
} }

12
main.go
View File

@ -24,6 +24,7 @@ func main() {
jsonReport := flag.Bool("jsonReport", false, "print out a json report providing a detailed report of the scan.") 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") 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)") 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() flag.Parse()
@ -42,13 +43,9 @@ func main() {
} }
onionScan := new(OnionScan) onionScan := new(OnionScan)
onionScan.Config = config.Configure(*torProxyAddress, *directoryDepth) onionScan.Config = config.Configure(*torProxyAddress, *directoryDepth, *fingerprint)
scanReport, err := onionScan.Scan(hiddenService) scanReport, err := onionScan.Scan(hiddenService)
if err != nil {
log.Fatalf("Error running scanner: %s", err)
}
if *jsonReport { if *jsonReport {
report.GenerateJsonReport(*reportFile, scanReport) report.GenerateJsonReport(*reportFile, scanReport)
} }
@ -56,4 +53,9 @@ func main() {
if *simpleReport { if *simpleReport {
report.GenerateSimpleReport(*reportFile, scanReport) report.GenerateSimpleReport(*reportFile, scanReport)
} }
if !*jsonReport && err != nil {
log.Fatalf("Error running scanner: %s", err)
}
} }

View File

@ -2,11 +2,11 @@ package main
import ( import (
"errors" "errors"
"fmt"
"github.com/s-rah/onionscan/config" "github.com/s-rah/onionscan/config"
"github.com/s-rah/onionscan/protocol" "github.com/s-rah/onionscan/protocol"
"github.com/s-rah/onionscan/report" "github.com/s-rah/onionscan/report"
"github.com/s-rah/onionscan/utils" "github.com/s-rah/onionscan/utils"
"log"
"strings" "strings"
) )
@ -57,8 +57,12 @@ func (os *OnionScan) Scan(hiddenService string) (*report.OnionScanReport, error)
mdbps := new(protocol.MongoDBProtocolScanner) mdbps := new(protocol.MongoDBProtocolScanner)
mdbps.ScanProtocol(hiddenService, os.Config, report) 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 { 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.") return nil, errors.New("Unable to connect to this Tor Hidden Service on any known protocol.")
} }

View File

@ -1,6 +1,9 @@
package protocol package protocol
import ( import (
"bufio"
"crypto/sha1"
"encoding/hex"
"github.com/s-rah/onionscan/config" "github.com/s-rah/onionscan/config"
"github.com/s-rah/onionscan/report" "github.com/s-rah/onionscan/report"
"h12.me/socks" "h12.me/socks"
@ -12,14 +15,22 @@ type FTPProtocolScanner struct {
func (sps *FTPProtocolScanner) ScanProtocol(hiddenService string, onionscanConfig *config.OnionscanConfig, report *report.OnionScanReport) { func (sps *FTPProtocolScanner) ScanProtocol(hiddenService string, onionscanConfig *config.OnionscanConfig, report *report.OnionScanReport) {
// FTP // FTP
log.Printf("Checking %s FTP(22)\n", hiddenService) log.Printf("Checking %s FTP(21)\n", hiddenService)
_, err := socks.DialSocksProxy(socks.SOCKS5, onionscanConfig.TorProxyAddress)("", hiddenService+":21") conn, err := socks.DialSocksProxy(socks.SOCKS5, onionscanConfig.TorProxyAddress)("", hiddenService+":21")
if err != nil { if err != nil {
log.Printf("Failed to connect to service on port 21\n") log.Printf("Failed to connect to service on port 21\n")
report.FTPDetected = false report.FTPDetected = false
} else { } else {
// TODO FTP Checking // TODO FTP Checking
report.FTPDetected = true 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)
}
} }
} }

View File

@ -65,13 +65,16 @@ func (hps *HTTPProtocolScanner) ScanProtocol(hiddenService string, onionscanConf
hps.ScanPage(hiddenService, "/server-status", report, scans.ApacheModStatus) hps.ScanPage(hiddenService, "/server-status", report, scans.ApacheModStatus)
hps.ScanPage(hiddenService, "/", report, scans.StandardPageScan) hps.ScanPage(hiddenService, "/", report, scans.StandardPageScan)
if onionscanConfig.Fingerprint == false {
log.Printf("\tScanning Common and Referenced Directories\n") log.Printf("\tScanning Common and Referenced Directories\n")
directories := append(CommonDirectories, report.PageReferencedDirectories...) directories := append(CommonDirectories, report.PageReferencedDirectories...)
utils.RemoveDuplicates(&directories) utils.RemoveDuplicates(&directories)
for _, directory := range directories { for _, directory := range directories {
hps.ScanPage(hiddenService, directory, report, scans.CheckDirectoryListing(onionscanConfig.DirectoryDepth)) hps.ScanPage(hiddenService, directory, report, scans.CheckDirectoryListing(onionscanConfig.DirectoryDepth))
} }
} }
}
log.Printf("\n") log.Printf("\n")
} }

View File

@ -1,6 +1,9 @@
package protocol package protocol
import ( import (
"bufio"
"crypto/sha1"
"encoding/hex"
"github.com/s-rah/onionscan/config" "github.com/s-rah/onionscan/config"
"github.com/s-rah/onionscan/report" "github.com/s-rah/onionscan/report"
"h12.me/socks" "h12.me/socks"
@ -13,13 +16,21 @@ type SMTPProtocolScanner struct {
func (sps *SMTPProtocolScanner) ScanProtocol(hiddenService string, onionscanConfig *config.OnionscanConfig, report *report.OnionScanReport) { func (sps *SMTPProtocolScanner) ScanProtocol(hiddenService string, onionscanConfig *config.OnionscanConfig, report *report.OnionScanReport) {
// SMTP // SMTP
log.Printf("Checking %s SMTP(25)\n", hiddenService) 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 { if err != nil {
log.Printf("Failed to connect to service on port 25\n") log.Printf("Failed to connect to service on port 25\n")
report.SMTPDetected = false report.SMTPDetected = false
} else { } else {
// TODO SMTP Checking // TODO SMTP Checking
report.SMTPDetected = true 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)
}
} }
} }

26
protocol/vnc_scanner.go Normal file
View File

@ -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
}
}

View File

@ -17,36 +17,48 @@ type ExifImage struct {
} }
type OnionScanReport struct { type OnionScanReport struct {
HiddenService string `json:"hiddenService"`
// Summary
WebDetected bool `json:"webDetected"` WebDetected bool `json:"webDetected"`
SSHDetected bool `json:"sshDetected"` SSHDetected bool `json:"sshDetected"`
RicochetDetected bool `json:"ricochetDetected"` RicochetDetected bool `json:"ricochetDetected"`
IRCDetected bool `json:"ircDetected"` IRCDetected bool `json:"ircDetected"`
FTPDetected bool `json:"ftpDetected"` FTPDetected bool `json:"ftpDetected"`
SMTPDetected bool `json:"smtpDetected"` SMTPDetected bool `json:"smtpDetected"`
BitcoinDetected bool `json:"bitcoinDetected"` BitcoinDetected bool `json:"bitcoinDetected"`
MongoDBDetected bool `json:"mongodbDetected"` MongoDBDetected bool `json:"mongodbDetected"`
VNCDetected bool `json:"vncDetected"`
HiddenService string `json:"hiddenService"` // Web Specific
ServerPoweredBy string `json:"serverPoweredBy"` ServerPoweredBy string `json:"serverPoweredBy"`
ServerVersion string `json:"serverVersion"` ServerVersion string `json:"serverVersion"`
FoundApacheModStatus bool `json:"foundApacheModStatus"` FoundApacheModStatus bool `json:"foundApacheModStatus"`
RelatedOnionServices []string `json:"relatedOnionServices"` RelatedOnionServices []string `json:"relatedOnionServices"`
RelatedClearnetDomains []string `json:"relatedOnionDomains"` RelatedClearnetDomains []string `json:"relatedOnionDomains"`
LinkedSites []string `json:"linkedSites"` LinkedSites []string `json:"linkedSites"`
InternalPages []string `json:"InternalPages"` InternalPages []string `json:"internalPages"`
IP []string `json:"ipAddresses"` IP []string `json:"ipAddresses"`
OpenDirectories []string `json:"openDirectories"` OpenDirectories []string `json:"openDirectories"`
ExifImages []ExifImage `json:"exifImages"` ExifImages []ExifImage `json:"exifImages"`
InterestingFiles []string `json:"interestingFiles"` InterestingFiles []string `json:"interestingFiles"`
PageReferencedDirectories []string `json:"pageReferencedDirectories"` PageReferencedDirectories []string `json:"pageReferencedDirectories"`
PGPKeys []string `json:"pgpKeys"` PGPKeys []string `json:"pgpKeys"`
Hashes []string `json:"hashes"` Hashes []string `json:"hashes"`
SSHKey string `json:"sshKey"`
Snapshot string `json:"snapshot"` Snapshot string `json:"snapshot"`
PageTitle string `json:"pageTitle"` PageTitle string `json:"pageTitle"`
ResponseHeaders map[string]string `json:"responseHeaders"` ResponseHeaders map[string]string `json:"responseHeaders"`
// SSH
SSHKey string `json:"sshKey"`
// FTP
FTPFingerprint string `json:"ftpFingerprint"`
FTPBanner string `json:"ftpBanner"`
// SMTP
SMTPFingerprint string `json:"smtpFingerprint"`
SMTPBanner string `json:"smtpBanner"`
} }
func LoadReportFromFile(filename string) (OnionScanReport, error) { func LoadReportFromFile(filename string) (OnionScanReport, error) {

View File

@ -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") log.Printf("\tScanning for CSS Fonts and Background Images\n")
utils.RemoveDuplicates(&cssLinks)
for _, cssUrl := range cssLinks { for _, cssUrl := range cssLinks {
log.Printf("\tScanning CSS file: %s\n", cssUrl) log.Printf("\tScanning CSS file: %s\n", cssUrl)
_, cssContents, _ := scan.ScrapePage(report.HiddenService, utils.WithoutProtocol(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") log.Printf("\tScanning for Links\n")
domains = append(domains, utils.ExtractDomains(contents)...) domains = append(domains, utils.ExtractDomains(contents)...)
utils.RemoveDuplicates(&domains)
for _, domain := range domains { for _, domain := range domains {
baseUrl, _ := url.Parse(domain) baseUrl, _ := url.Parse(domain)
if baseUrl.Host != "" && utils.WithoutSubdomains(baseUrl.Host) != utils.WithoutSubdomains(report.HiddenService) { if baseUrl.Host != "" && utils.WithoutSubdomains(baseUrl.Host) != utils.WithoutSubdomains(report.HiddenService) {