FTP,SMTP,VNC Fingerprints
This commit is contained in:
parent
49095c586a
commit
56c267c66e
|
@ -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
12
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.")
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue