Moinsen,
als altgedienter
AV-Mensch (auch wenn ich seit einem reichlichen Jahr nicht mehr dabei bin), wollte ich mal ein paar Dinge einwerfen.
Ich habe für meinen mp3-Player mit InnoSetup einen Installer gebaut. Dieser wird seit gestern(?) vom Windows Defender als "Trojan:
Win32/Ludicrouz.C" erkannt. "False Positives" sind ja nichts neues, und grade bei Delphi kommt das immer wieder mal vor (z.B. auch mit den
Indy-Komponenten). Etwas blöd ist, dass es diesmal der Windows Defender ist, der sehr weit verbreitet sein dürfte. Außerdem ist blöd, dass das Microsoft-Formular zur Malware-Analyse den Upload verweigert ("Upload failed, please try again"), und mir somit eine Meldung dieses Fehlers (erstmal) nicht möglich ist (verschiedene Browser probiert, verschiedene
OS probiert, verschiedene Varianten probiert, z.B. auch zip mit Passwort wie im Formular angegeben, ...).
Also, bei Microsoft
könntest du Glück haben, weil die eigentlich immer recht gut dabei sind Fehlalarme auszumerzen.
Dann habe ich mir gedacht: Gut, veränderst du halt das Setup ein bisschen - vielleicht reicht das ja, um die Heuristik dann nicht mehr zu triggern. Interessanterweise hat das beim ersten Versuch geklappt. Ich habe im InnoSetup-Script die Zeile
Code:
#define MyAppPublisher "Daniel Gaußmann"
ausgetauscht durch
Code:
#define MyAppPublisher "Daniel Gausi Gaußmann"
Das hat tatsächlich gereicht, um den Windows Defender stumm zu schalten
. Laut VirusTotal ist eine McAfee-Variante damit immer noch nicht zufrieden, aber das soll mir egal sein.
Hmm, kleiner Reality Check (und ja, als FLOSS-Entwickler, oder "ISV" wie man dann bezeichnet wird, wobei das auch kommerzielle einschließt), haste damit ein Problem.
Erkennungen (detections) verbreiten sich innerhalb der Industrie - leider rasend schnell.
Auf VT hochladen ist auch nicht die geilste Idee, weil dort im Hintergrund Analysetools für
alle AVler bereitstehen (ich habe noch Zugriff) und sowas selbst geflaggt werden könnte, denn auch Malwareautoren machen genau das (allerdings sind viele davon auf eigene Dienste "im Darknet" umgeschwenkt, welche - wie VT - die Kommandozeilenscanner o.ä. der jeweiligen AVs benutzen).
Einerlei, Erkennungen verbreiten sich, egal ob Fehlalarm oder echt bösartig. Und das Problem ist, während sich mit VT und anderen Initiativen durchaus was herausgebildet hat, um innerhalb der Industrie Erkennungen zu teilen, gibt es keinerlei Möglichkeit allen Herstellern von AVs gleichzeitig die Meldung zukommen zu lassen, daß man Opfer eines Fehlalarms war.
Hier hilft aus meiner Sicht mittelfristig nur eine Regulierung durch die Politik,
denn einige sehen sich geradezu als Internet-Sheriffs.
Das Problem ist, daß Einspruch seitens der jeweiligen Autoren von - an sich - harmlosen Programmen nicht vorgesehen ist. Und da keiner für die Fehlalarme zur Verantwortung gezogen wird und bspw. die fälschliche Erkennung zu keinen negativen Folgen (außer bei
AV-Test und Konsorten) führt, wird lieber "über-erkannt".
Man kann also nur auf gesellschaftlicher Ebene einfordern, daß sich auch
AV-Hersteller für von ihnen zu verantwortende Rufschädigung geradestehen müssen.
Jetzt kann ich nachvollziehen, dass eine Malware-Heuristik bei einer nicht signierten Exe Alarm schlägt, wenn als Publisher z.B. "Microsoft" eingetragen ist.
Zwei Punkte:
- Zumindest für FLOSS ist signieren billig. Wahlweise certum.pl oder SignPath.
- Signaturen sind schon seit Jahren - kein Scherz! - durchgekaut. Es wurde ja schon mehrfach Malware gefunden die durch gestohlene oder "abhanden gekommene" Zertifikate signiert worden war. Von den Preimage-Angriffen aus MD5-Zeiten wollen wir mal ganz schweigen. Aus diesem Grunde wurde ja SHA-1 auch abgekündigt, weil zumindest mathematisch gewisse Schwächen ruchbar geworden waren.
Übrigens müssen die Catalog-Dateien bei Treibern genau aus diesem Grund von MS gegengezeichnet werden (früher nannte es sich Cross-Signing und stand nur zur Verfügung nachdem die WHQL-Tests durchlaufen wurden, jetzt gibt es auch die abgeschwächte Variante des Attestation Signing). Kurzum Microsoft sieht deine Treiber bevor sie dein Kunde zu Gesicht bekommt. Hat Vorteile. Bspw. bekommt man als Hersteller auch Zugriff auf die Minidumps von BSODs die der eigene Treiber mutmaßlich zu verantworten hatte.
Sowas ist "verdächtig", völlig klar. Aber wenn ich einen unbekannten Hobby-Entwickler durch einen anderen ersetze, sollte das doch keinen Unterschied machen, oder? Ich halte Antiviren-Software ja tendenziell eher für Schlangenöl, aber so blöd kann das ja nicht sein ...
AV-Software ist nicht Schlangenöl. Zumindest nicht jede. Aber ja, im Grunde ist es so, daß Heuristiken halt immer mehr "fangen" als sie prinzipiell sollen. Nachjustieren kann man ja immernoch
... ich habe selber Heuristiken für die Mini-Engine gebastelt, die ich für SWF-Dateien geschrieben hatte. Bei anderen Heuristiken war ich nur lesend unterwegs, da das als (u.a.) Engine-Entwickler nicht gerade meine Hauptaufgabe war.
Und da die Heuristiken auch noch schnell sein sollen - und die
AV-Engines ohnehin - werden auch gern Abkürzungen genommen. Jede Menge!
Und da - wie oben geschrieben - keiner für Fehlalarme zur Verantwortung gezogen werden, es sei denn die treten ausgerechnet bei einem der, meiner Meinung nach extrem verzerrten,
AV-Tests auch (z.B. von
AV-Test,
AV Comparatives, VB100).
Kombiniert man das zu einem Gesamtbild, erklärt sich einem Betrachter von außen recht schnell, warum es so läuft wie's läuft.
Signaturen (AuthentiCode) haben nicht viel gebracht und Packern wollte man
hiermit begegnen. In Sachen "saubere" Dateien wurde auf der VB2013
das hier vorgestellt. Auf meine explizite Nachfrage an Mark, bekam ich die Antwort, daß das nur für die dicken Haie im Becken sei (Adobe, Google, Microsoft, so die Größenordnung) und ein Zugang für ISVs, insbesondere FLOSS-Autoren nicht angedacht sei.
Dann ist mir aufgefallen, dass die neue Version (mit dem
längeren Publisher-String) ein paar Bytes
kleiner ist als die alte. Beim Blick in die beiden Binaries (z.B. mit HxD) sieht man, dass dieser (und andere) Strings mit einer konstanten Länge (
Unicode-String, aufgefüllt mit Leerzeichen) in der Datei zu finden sind - da ändert sich die Dateigröße also nicht.
Du weißt sicher wie Kompressionsalgorithmen funzen, oder? Das sollte also keine Überraschung sein.
Relativ am Ende (größenordnungsmäßig die letzten 10%) des Installers findet sich dann ein Teil mit größeren Binär-Unterschieden. Die Teile sind dabei echt verschieden, nicht einfach nur um ein paar Bytes verschoben, beginnend mit "Inno Setup Setup Data" (als AnsiString). Ich nehme mal an, dass in diesem Teil die Setup-Daten nochmal(?) in komprimierter(?) Form vorliegen, und dass der längere String in Kombination mit den anderen Strings insgesamt besser komprimiert werden kann. Weiter kann ich mir vorstellen, dass in diesem anderen "Bytehaufen" dann keine Muster mehr vorkommen, die auch in besagtem Trojaner vorkommen.
Mit InnoSetup habe ich mich noch nie beschäftigt. Aber das war doch FLOSS, oder? Schau doch in die Quellen. Meiner Erinnerung nach gibt es auch eine Menge Werkzeuge die das entpacken und dechiffrieren können (also das Skript usw.).
Jetzt ist es natürlich etwas komisch bzw. verdächtig, wenn ich schreibe "Ich hab da nur einen String ausgetauscht", und ein misstrauischer Anwender dann mal ein Diff macht und weitaus mehr Unterschiede findet.
Kompressionsalgorithmen ...
Hat damit jemand schon Erfahrung gesammelt, bzw. weiß, warum sich dieser letzte Teil im Installer so deutlich unterscheidet, wenn man nur eine String-Konstante ändert?
Ich würde auf folgende Unterschiede tippen:
- Reine Daten: Hashes, Zeitstempel ...
- Skript (was eventuell auch nochmal anhand deiner geänderten Ressource diese Änderung reflektiert)
Also im 010 sieht's so aus:
Code:
Result,Address A,Size A,Address B,Size B
Match,0h,BBE08h,0h,BBE08h
Difference,BBE08h,5h,BBE08h,5h
Match,BBE0Dh,13h,BBE0Dh,13h
Difference,BBE20h,4h,BBE20h,4h
Match,BBE24h,18Ch,BBE24h,18Ch
Difference,BBFB0h,15h,BBFB0h,15h
Match,BBFC5h,754900h,BBFC5h,754900h
Difference,8108C5h,Dh,8108C5h,Dh
Match,8108D2h,68h,8108D2h,68h
Difference,81093Ah,55B1h,81093Ah,55B8h
Match,815EEBh,B2625h,815EF2h,B2625h
... mit dem hier:
Code:
#!/usr/bin/env python3
import sys
def main(*args):
for fname in args:
print("Datei %s" % (fname))
with open(fname) as f:
md_dict = {}
for line in f:
tk = line.strip().split(",")
assert len(tk) == 5
if tk[0] in {"Result"}:
continue
curr = [int(x.strip("h"), 16) for x in tk[1:]]
tpname = tk[0]
if tpname not in md_dict:
md_dict[tpname] = []
md_dict[tpname].append((curr[1], curr[3],))
for k, v in md_dict.items():
first, second = sum([x[0] for x in v]), sum([x[1] for x in v])
print("{:10}: {:10} vs. {:10}".format(k, first, second))
if __name__ == "__main__":
main(*sys.argv[1:])
... bekommen wir folgende Ausgabe (ok.exe/bad.exe ... in der Reihenfolge):
Code:
$ ./compare.py Compare.csv
Datei Compare.csv
Match : 9187124 vs. 9187124
Difference: 21980 vs. 21987
Das ist ein schon recht kleiner Unterschied, oder?
Fazit:
- Gesellschaftlichen Druck aufbauen. Ziel muß es sein, daß auch AV-Hersteller für von ihnen begangene Rufschädigungen zur Rechenschaft gezogen werden [1]. Erst ab dem Zeitpunkt wird sich etwas bewegen, so daß auch für ISVs/Einzelautoren die Möglichkeit geschaffen wird über ein Formular alle Hersteller gleichzeitig über einen Fehlalarm zu unterrichten. Klar gibt's da Mißbrauchspotential. Aber die Rufschädigungen wenn etwas harmloses als bösartig erkannt wird, sind auch nicht ohne ...
- Kunden/Anwender auf das Treiben der AV-Hersteller hinweisen und ggf. bitten diese auch zu kontaktieren.
[1] Bei meiner Zwischenstation bei Lavasoft in Göteborg habe ich gelernt, daß eigentlich mehrfach wöchentlich Unterlassungsaufforderungen (cease & desist letters) ankamen, wenn sich einer der Adware-Hersteller auf den Schlips getreten fühlte. Bei
AV-Herstellern war das bis vor ein paar Jahren alles immer recht schwarzweiß, bis man anfing Potenziell unerwünschte Anwendungen (PUA) auch mit aufzunehmen. Da stellt sich dann halt die Frage ob
der seit anderthalb Jahrzehnten gepatchte Exploit nun wirklich noch gefährlich ist, oder
das Tutorial zu Window-Hooks mit einem Tastaturhook nicht brandgefährlich (die entpackte Variante davon mußte ich erst unlängst entfernen, weil ja nicht nur diese eine
URI bei Google Safe Browsing gesperrt wird, sondern
die komplette Domain mit allen Subdomains) ...