From 0a12cc0e519ba91efdb88dc74906df252951abc8 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Wed, 7 Oct 2015 16:13:25 +0000 Subject: [PATCH] Add a helper to submit files or URLs to VirusTotal Git for Windows has a long track record of bogus virus scanner reports. In fact, all of the reports turned out to be false positives (which is not a surprise, given that the releases were always prepared on a trusted, dedicated VM). One blatant example is where precious development time was spent on verifying that Git for Windows 2.5.1's `/cmd/git-gui.exe` (that was reported as infected with a Trojan) differs from its /cmd/git.exe` (that was reported as *uninfected*) only in the four bytes in the header that indicate a GUI vs a console program. So obviously the virus scanner's logic was kind of questionable, otherwise it would have flagged either both or none. In the process of trying to work with (or against) virus scanner developers, the idea cropped up that signing the executables might make a difference. To facilitate testing this hypothesis, this script was written. It requires an API key of https://www.virustotal.com/ (registration required) to be put into the `$HOME/_netrc` file as machine api.virustotal.com password Sadly, the test demonstrated that the PortableGit-2.6.1-64-bit.7z.exe file was flagged by the 'Jiangmin' engine as being infected by 'Trojan/Blocker.aifm' while PortableGit-2.6.1-32-bit.7z.exe was flagged by the 'Ad-Aware' engine with the 'Gen:TrojanHeur.FU.iK0@ayy4a0ki' label. For 2.6.0, it is even worse. The 32-bit portable Git is flagged by both 'Ad-Aware' (as 'Gen:Trojan.Heur.FU.iK0@aij9DHai' and 'Qihoo-360' (as 'HEUR/QVM20.1.Malware.Gen'), yet the 64-bit portable Git goes scot free. These different findings make no sense whatsoever, given that the portable Git installers are all *identical* self-extractors with the `.7z` archive appended. So again, the engines should have flagged them all, or none. At least now we have an easy-to-use script so that future analyses might be taking less time away from what this developer is really here for: developing Git for Windows. This closes https://github.com/git-for-windows/git/issues/451 Signed-off-by: Johannes Schindelin --- send-to-virus-total.sh | 44 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 send-to-virus-total.sh diff --git a/send-to-virus-total.sh b/send-to-virus-total.sh new file mode 100644 index 0000000..5ee7994 --- /dev/null +++ b/send-to-virus-total.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +die () { + echo "$*" >&2 + exit 1 +} + +form_param= +type= +case "$#,$1" in +1,http://*|1,https://*) + form_param=url="$1" + type=url + ;; +1,*) + test -f "$1" || + die "No such file: $1" + form_param=file="@$1" + type=file + ;; +*) + die "Usage: $0 | " + ;; +esac + +apikey=$(sed -n '/^machine api.virustotal.com$/,/^password/s/^password //p' \ + <$HOME/_netrc) +test -n "$apikey" || +die "No API key found for api.virustotal.com in $HOME/_netrc" + +response="$(curl --form apikey="$apikey" --form "$form_param" -i -L -X POST -0 \ + https://www.virustotal.com/vtapi/v2/$type/scan)" || +die "Error: $response" + +test -z "$SHOW_HEADER" || +printf "Header:\n%s\n" "$(echo "$response" | sed '/^$/q')" + +extract_json () { + echo "$1" | sed -n 's/.*"'"$2"'": *"\([^"]*\).*/\1/p' +} + +extract_json "$response" verbose_msg >&2 + +start "$(extract_json "$response" permalink)"