From 65c4a40a84203b2e49bef5ec2d48a5f76154a8f5 Mon Sep 17 00:00:00 2001 From: Margulan Moldabekov Date: Thu, 18 Jan 2018 17:05:46 +0600 Subject: [PATCH 1/2] show results for hash search too --- filescan.go | 5 +++-- hashsearch.go | 3 ++- urlscan.go | 1 - 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/filescan.go b/filescan.go index 607f142..2ea7605 100644 --- a/filescan.go +++ b/filescan.go @@ -25,7 +25,9 @@ func sha256sum(filename string) string { func printFileResult(result *govt.FileReport) { color.Set(color.FgHiYellow) - fmt.Printf("%s file scan results:\n", *filename) + if len(*filename) > 0 { + fmt.Printf("%s file scan results:\n", *filename) + } if !*waitFile { fmt.Printf("sha256 hashsum: %s\n", result.Sha256) fmt.Printf("VirusTotal link: %s\n\n", result.Permalink) @@ -59,7 +61,6 @@ func scanFile(filename string) { // If file was previously scanned print results switch r.Status.ResponseCode { case 1: // Results exist - fmt.Printf("%d", r.Status.ResponseCode) printFileResult(r) case -2: // Scan in progress color.Set(color.FgHiRed) diff --git a/hashsearch.go b/hashsearch.go index d1c878f..1e0ccd7 100644 --- a/hashsearch.go +++ b/hashsearch.go @@ -25,7 +25,8 @@ func searchHash(hash string) { } else { if r.Positives > 0 { color.Set(color.FgHiRed) - fmt.Printf("\nGiven hash [%d/%d] is KNOWN by VirusTotal and has positive results\n", r.Positives, r.Total) + fmt.Printf("\nGiven hash is KNOWN by VirusTotal and has positive results [%d/%d]\n", r.Positives, r.Total) + printFileResult(r) color.Unset() } else { color.Set(color.FgHiGreen) diff --git a/urlscan.go b/urlscan.go index 4739905..dc5fb18 100644 --- a/urlscan.go +++ b/urlscan.go @@ -42,7 +42,6 @@ func scanUrl(urlname string) { // If file was previously scanned print results switch r.Status.ResponseCode { case 1: // Results exist - fmt.Printf("%d", r.Status.ResponseCode) printUrlResult(r) case -2: // Scan in progress color.Set(color.FgHiRed) From c451fc19bfc2e1ee1f4ce8dd4f4fff920414cdf7 Mon Sep 17 00:00:00 2001 From: Margulan Moldabekov Date: Thu, 18 Jan 2018 20:35:32 +0600 Subject: [PATCH 2/2] JSON support added --- filescan.go | 62 ++++++++++++++++++++++++++++++--------------------- hashsearch.go | 21 +++++++++-------- main.go | 3 +++ urlscan.go | 58 ++++++++++++++++++++++++++++------------------- 4 files changed, 87 insertions(+), 57 deletions(-) diff --git a/filescan.go b/filescan.go index 2ea7605..95fe655 100644 --- a/filescan.go +++ b/filescan.go @@ -7,6 +7,7 @@ import ( "fmt" "github.com/moldabekov/virusgotal/vt" "github.com/fatih/color" + "encoding/json" ) func sha256sum(filename string) string { @@ -24,27 +25,34 @@ func sha256sum(filename string) string { } func printFileResult(result *govt.FileReport) { - color.Set(color.FgHiYellow) - if len(*filename) > 0 { - fmt.Printf("%s file scan results:\n", *filename) - } - if !*waitFile { - fmt.Printf("sha256 hashsum: %s\n", result.Sha256) - fmt.Printf("VirusTotal link: %s\n\n", result.Permalink) - } - color.Set(color.FgHiCyan) - fmt.Printf("Detection ratio: %v/%v\n\n", result.Positives, result.Total) - for i := range result.Scans { - if result.Scans[i].Detected { - color.Set(color.FgHiRed, color.Bold) - fmt.Printf("AV: %s\nResult: %s\n\n", i, result.Scans[i].Result) - } else { - color.Set(color.FgHiGreen, color.Bold) - fmt.Printf("AV: %s\nDetected: %t\n\n", i, result.Scans[i].Detected) + if (!*jsonFile) && (!*jsonHash) { + color.Set(color.FgHiYellow) + if len(*filename) > 0 { + fmt.Printf("%s file scan results:\n", *filename) } + if !*waitFile { + fmt.Printf("sha256 hashsum: %s\n", result.Sha256) + fmt.Printf("VirusTotal link: %s\n\n", result.Permalink) + } + color.Set(color.FgHiCyan) + fmt.Printf("Detection ratio: %v/%v\n\n", result.Positives, result.Total) + for i := range result.Scans { + if result.Scans[i].Detected { + color.Set(color.FgHiRed, color.Bold) + fmt.Printf("AV: %s\nResult: %s\n\n", i, result.Scans[i].Result) + } else { + color.Set(color.FgHiGreen, color.Bold) + fmt.Printf("AV: %s\nDetected: %t\n\n", i, result.Scans[i].Detected) + } + } + color.Unset() + os.Exit(0) + } else { + j, err := json.MarshalIndent(result, "", " ") + check(err) + os.Stdout.Write(j) + os.Exit(0) } - color.Unset() - os.Exit(0) } func scanFile(filename string) { @@ -74,18 +82,22 @@ func scanFile(filename string) { report, err := vt.ScanFile(filename) check(err) color.Set(color.FgHiGreen, color.Bold) - fmt.Printf("Your file was submitted and scan was queued. Here are details:\n\n") - color.Set(color.Reset, color.FgHiCyan) - fmt.Printf("sha256 hash: %s\n", report.Sha256) - fmt.Printf("VirusTotal link: %s\n\n", report.Permalink) - color.Unset() + if !*jsonFile && !*jsonHash { + fmt.Printf("Your file was submitted and scan was queued. Here are details:\n\n") + color.Set(color.Reset, color.FgHiCyan) + fmt.Printf("sha256 hash: %s\n", report.Sha256) + fmt.Printf("VirusTotal link: %s\n\n", report.Permalink) + color.Unset() + } if *waitFile { // Wait for results if user wishes for m := 0; m <= 600; m += 30 { // m == minutes loader(fmt.Sprintf("waiting for results for %d seconds", m)) r, err := vt.GetFileReport(sha256sum(filename)) check(err) if r.Status.ResponseCode == 1 { - fmt.Printf("scan took ~ %d seconds\n", m) + if !*jsonFile && !*jsonHash { + fmt.Printf("scan took ~ %d seconds\n", m) + } printFileResult(r) } } diff --git a/hashsearch.go b/hashsearch.go index 1e0ccd7..8274e44 100644 --- a/hashsearch.go +++ b/hashsearch.go @@ -22,17 +22,20 @@ func searchHash(hash string) { fmt.Printf("Given hash isn't recognized by VirusTotal\n") color.Unset() os.Exit(1) - } else { - if r.Positives > 0 { - color.Set(color.FgHiRed) + } + if r.Positives > 0 { + color.Set(color.FgHiRed) + if !*jsonHash { fmt.Printf("\nGiven hash is KNOWN by VirusTotal and has positive results [%d/%d]\n", r.Positives, r.Total) - printFileResult(r) - color.Unset() - } else { - color.Set(color.FgHiGreen) - fmt.Printf("\nGiven hash is KNOWN by VirusTotal and has no positive results\n", r.Positives, r.Total) - color.Unset() } + printFileResult(r) + color.Unset() + } else { + color.Set(color.FgHiGreen) + fmt.Printf("\nGiven hash is KNOWN by VirusTotal and has no positive results\n", r.Positives, r.Total) + color.Unset() + } + if !*jsonHash { fmt.Printf("Direct link: %s\n\n", r.Permalink) } } diff --git a/main.go b/main.go index 6d2de5a..034adb9 100644 --- a/main.go +++ b/main.go @@ -14,14 +14,17 @@ var ( filename = filescan.Arg("FILE", "File to scan").Required().String() forceFile = filescan.Flag("force", "rescan file").Bool() waitFile = filescan.Flag("wait", "wait for results").Bool() + jsonFile = filescan.Flag("json","export results to JSON").Bool() urlscan = app.Command("url", "URL scanning mode") urlname = urlscan.Arg("URL", "URL to scan").Required().String() forceUrl = urlscan.Flag("force", "rescan URL").Bool() waitUrl = urlscan.Flag("wait", "wait for results").Bool() + jsonUrl = urlscan.Flag("json","export results to JSON").Bool() hashscan = app.Command("hash", "Search files by hash") hash = hashscan.Arg("HASH", "SHA1/SHA256/MD5 hash").Required().String() + jsonHash = hashscan.Flag("json","export results to JSON").Bool() ) func main() { diff --git a/urlscan.go b/urlscan.go index dc5fb18..3ad7de0 100644 --- a/urlscan.go +++ b/urlscan.go @@ -5,27 +5,35 @@ import ( "github.com/fatih/color" "fmt" "os" + "encoding/json" ) func printUrlResult(result *govt.UrlReport) { - color.Set(color.FgHiYellow) - fmt.Printf("%s scan results:\n", *urlname) - if !*waitUrl { - fmt.Printf("VirusTotal link: %s\n\n", result.Permalink) - } - color.Set(color.FgHiCyan) - fmt.Printf("Detection ratio: %v/%v\n\n", result.Positives, result.Total) - for i := range result.Scans { - if result.Scans[i].Detected { - color.Set(color.FgHiRed, color.Bold) - fmt.Printf("AV: %s\nResult: %s\n\n", i, result.Scans[i].Result) - } else { - color.Set(color.FgHiGreen, color.Bold) - fmt.Printf("AV: %s\nDetected: %t\n\n", i, result.Scans[i].Detected) + if !*jsonUrl { + color.Set(color.FgHiYellow) + fmt.Printf("%s scan results:\n", *urlname) + if !*waitUrl { + fmt.Printf("VirusTotal link: %s\n\n", result.Permalink) + } + color.Set(color.FgHiCyan) + fmt.Printf("Detection ratio: %v/%v\n\n", result.Positives, result.Total) + for i := range result.Scans { + if result.Scans[i].Detected { + color.Set(color.FgHiRed, color.Bold) + fmt.Printf("AV: %s\nResult: %s\n\n", i, result.Scans[i].Result) + } else { + color.Set(color.FgHiGreen, color.Bold) + fmt.Printf("AV: %s\nDetected: %t\n\n", i, result.Scans[i].Detected) + } } + color.Unset() + os.Exit(0) + } else { + j, err := json.MarshalIndent(result, "", " ") + check(err) + os.Stdout.Write(j) + os.Exit(0) } - color.Unset() - os.Exit(0) } func scanUrl(urlname string) { @@ -55,19 +63,23 @@ func scanUrl(urlname string) { //if !*waitUrl { report, err := vt.ScanUrl(urlname) check(err) - color.Set(color.FgHiGreen, color.Bold) - fmt.Printf("Your URL was submitted and scan was queued. Here are details:\n\n") - color.Set(color.Reset, color.FgHiCyan) - fmt.Printf("Link: %s\n", report.Url) - fmt.Printf("VirusTotal link: %s\n\n", report.Permalink) - color.Unset() + if !*jsonUrl { + color.Set(color.FgHiGreen, color.Bold) + fmt.Printf("Your URL was submitted and scan was queued. Here are details:\n\n") + color.Set(color.Reset, color.FgHiCyan) + fmt.Printf("Link: %s\n", report.Url) + fmt.Printf("VirusTotal link: %s\n\n", report.Permalink) + color.Unset() + } if *waitUrl { // Wait for results if user wishes for m := 0; m <= 600; m += 30 { loader(fmt.Sprintf("waiting for results for %d seconds", m)) r, err := vt.GetUrlReport(urlname) check(err) if r.Status.ResponseCode == 1 { - fmt.Printf("scan took ~ %d seconds\n", m) + if !*jsonUrl { + fmt.Printf("scan took ~ %d seconds\n", m) + } printUrlResult(r) } }