Ich habe hier ein kleines Freeware-Tool welches vor Jahren mal ein
Russischer Entwickler programmiert hat und es daher nur teilweise in
Englisch übersetzt ist. Der Entwickler ist nicht mehr erreichbar, es
gibt auch keine Quelldateien dazu. Also möchte ich die Sache selbst in
die Hand nehmen :-)
Das Tool kommt in Form einer ca. 1MB großen EXE Datei daher, mit ein
paar DLLs im Gepäck, welche aber vermutlich nur Runtime und nicht
programmspezifisch sind(?): comdlg32.ocx, ConvertSys.dll, mscomctl.ocx,
mscomm32.ocx, mswinsck.ocx, msxml6.dll, scrun.dll
Als erstes habe ich mal versucht die EXE mit einem HexEditor zu
untersuchen, bin dort aber keinen Strings begegnet, ein paar wenige
Englische sind ja vorhanden und müssten sich im Programm ja finden, z.B.
"Procedure", "Information". Evtl. entschlüsselt sich die EXE nach dem
Start selbst?
Dann habe ich Ghidra installiert und es mal analysieren lassen. Das
findet zwar über den PE-Header eine Menge informationen aber letztlich
nur eine "entry()" Funktion aus der ich aber nicht recht schlau werde.
Decompiliert sie diese so aus:
1
/* WARNING: Instruction at (ram,0x0045280e) overlaps instruction at (ram,0x0045280d)
Das macht ergibt für mich keinen Sinn weil dort nichts zu passieren
scheint. Es wirkt eher so als würde sich außerhalb dieser Loop etwas tun
müssen. Auch komisch das Ghidra nicht anderes findet, das deutet für
mich darauf hin das hier eine Verschlüsselung im Spiel ist.
Jetzt kenne ich mich mit Ghidra und andere Disassemblern/Debuggern auf
Windows nicht so gut aus um von hier weiter zu kommen und hoffe auf
etwas Unterstützung aus dem Forum :-)
Kann man die Software nicht über einen Emulator/Debugger starten um
"mitzubekommen" was da intern vor sich geht? Ich denke wenn die
Anwendung erstmal im Arbeitsspeicher ist und läuft, dann müssten die
Strings auch erkennbar sein.
Olli Z. schrieb:> das deutet für> mich darauf hin das hier eine Verschlüsselung im Spiel ist.
Nicht unbedingt. Ich weiss nicht, wie alt das Programm ist. Eventuell
liegen die Zeichenketten als wchar_t vor. Dann kann man höchstens nach
"I.n.f.o.r.m.at.t.i.o.n" suchen. Die Zeichen sehen für mich allerdings
alles andere als russisch aus. Die sehen eher so aus, als würden sie
komplett fehlen und irgendein wilder Speicherbereich interpretiert.
Ich tippe auf VB-6.0 o. VC 6.0 .
Das sagen mir die DLL's.
Interessant finde ich die "ConvertSys.dll". Da ich die DLL nicht kenne
habe ich sie gegooglt und NUR Russische Ergebnisse bekommen.
Da die Russischer Schrift anders ist als die normale Schrift, muss(te)
man i.d.R. eine Russischen Sparset installieren.
Eine Software für die ich mal als Projektmanager (Anpassung der Software
in eine Spezial-Edition für unsere Firma) verantwortlich war, wurde auch
für Russland übersetzt, und der Programmierer sagte mir er müsste das
russische Sprachset nach installieren, damit das auch auf Russisch
sauber läuft. Und das war zu VB 6.0 /VC Zeit. Also so ca. Win-98/XP
Zeit.
Leider habe ich nicht mehr Infos/Tipps für dich.
Walter T. schrieb:> Die sehen eher so aus, als würden sie> komplett fehlen und irgendein wilder Speicherbereich interpretiert.
Hab das mal im Sandkisterl laufen lasse. Die Texte ändern sich, bei
(fast) jedem Start und es sind sogar Englische dabei....
Also Henkel dran und weit werfen!
PS:
Die stecken alle in der scrrun.dll.
Teo D. schrieb:> Hab das mal im Sandkisterl laufen lasse. Die Texte ändern sich, bei> (fast) jedem Start und es sind sogar Englische dabei....> Also Henkel dran und weit werfen!
nö.
Das ist ein Fehler in der Locate. Da wird versucht anhand von
Systemdaten die Sprache heraus zu finden. Das Problem ist, das der Coder
dafür die Übersetzungen machen muss.
Die Technik ist aber nicht sehr beliebt, viele Programmierer inkl. mir,
legen lieber Datenbanken o.ä. an, und geben die Sprachen da ein.
Der Vorteil ist, das der User unabhängig von der Sprache des Systems
seine Sprache auswählen kann. Man erkennt das als Laie daran, das das
Prg. meist nach Änderung der Sprache einen Neustart will.
Aber bei beiden gilt meist, das es wenn keine Übersetzung ist, die
Landessprache der Programmierers angezeigt wird. Was der User als
Englisch/Deutsch Mischung erkennt. Besonders wenn die Sprachdatei
veraltert ist.
Schlaumaier schrieb:> Interessant finde ich die "ConvertSys.dll". Da ich die DLL nicht kenne> habe ich sie gegooglt und NUR Russische Ergebnisse bekommen.
kommt von hier:
https://www.cryptosys.net/api.html
ein australischer Entwickler
https://di-mgt.com.au/
einfach unter Eigenschaften der DLL nachschauen
ExeInfoPe zeigt an dass die exe gepackt ist. mit einem Disassembler oder
Debugger wird das erst mal nichts.
gepackt wurde wohl mit UPX v3.0
ach ja debugger Sperre ist auch eingebaut
Detect It Easy meldet
- DotFix Nice Protect(-)[-]
- UPX(-)[modified]
Sowas machen die Russen gerne, ich würde sagen vergiss das Ganze.
Hab mal mit dem ResHacker geschaut.
Russisch geschriebene Ressourcen sind da mal
nicht dabei. Die original .exe enthält nur Icons
und die DLLs (außer die von VB habe ich nicht
getestet) enthalten auch nichts dergleichen.
Ich tauche langsam in die Materie ein und danke für die zahlreichen
Tipps! :-)
Also ganz klar ist das die EXE gepackt und ggf. auch verschlüsselt ist.
Das mit UPX scheint mir das kleinere Übel, denn das ist wohl ein
gängiges Packverfahren, ähnlich ZIP/LWZ, also keine Verschlüsselung. Das
Too, ExeinfoPE erkennt das und könnte wohl auch eine unkomprimierte
Variante sichern. Dann jedoch schlägt mein Virenscanner an und behauptet
einen Trojaner gefunden zu haben... hm.
Ich bin aber nicht sicher ob die Kompression um die innere App oder die
mit DotFix Protect geschütze Hülle der App liegt?
Und da wären wir schon beim DotFix Protect. Das ist wohl nicht
unknackbar. Letztlich setzt das auf die vom OS bereitstellten APIs um
einen laufenden Debugger zu erkennen( "isDebuggerPresent") Hier gibt es
wohl mehrere Ansätze das zu verhindern., z.b. mit einem Plugin für
OllyDebug
http://www.openrce.org/downloads/details/111/IsDebuggerPresent. Dabei
geht es wohl letztlich darum das Ergebnis der Funktion auf 0 zu stellen
;-)
Dann ist wohl auch die Signatur manipuliert, sodass OllyDgb das Program
nicht wirklich gut erkennt beim laden. Das lässt sich durch änderb des
AV Wertes auf 0x10 mittel PE Editor aber problemlos richten.
Olli Z. schrieb:> Dann jedoch schlägt mein Virenscanner an und behauptet> einen Trojaner gefunden zu haben... hm.
Du bist auf dem richtigen weg.. Dass der Virenscanner anschlägt würde
ich als Zeichen werten, dass du korrekt ausgepackt hast. Die Scanner
schlagen fast immer an wenn ein Debugger Schutz im Spiel ist, weil auch
alle Schadprogramme mit solchen Techniken arbeiten.
Willkommen in der Hackerwelt :-)
Olli Z. schrieb:> Also ganz klar ist das die EXE gepackt und ggf. auch verschlüsselt ist.
Es kann sein, nur so als Vermutung, das die DLL ein Teil der EXE
verschlüsselt. Immerhin stellt die solche Technik zu Verfügung lt Link.
Im 2. Link gibt es ein Unterlink der das in VB erklärt.
siehe :
Thomas Z. schrieb:> Schlaumaier schrieb:>> Interessant finde ich die "ConvertSys.dll". Da ich die DLL nicht kenne>> habe ich sie gegooglt und NUR Russische Ergebnisse bekommen.>> kommt von hier:> https://www.cryptosys.net/api.html> ein australischer Entwickler> https://di-mgt.com.au/>> einfach unter Eigenschaften der DLL nachschauen
Olli Z. schrieb:> Das mit UPX scheint mir das kleinere Übel
Das stimmt nur wenn es das Original UPX ist. Da wird gerne das Verfahren
geändert damit es nicht so einfach zu 'entpacken' ist.
Olli, ich würde die ausgepackte exe einfach mal in einer VM starten.
Wenn das Auspacken funktioniert hat, sollte die exe auch im ausgepackten
Zustand laufen.
Danach einfach nochmal durch Ghidra oder IDA jagen. Wenn du Glück hast
gibts dann schon Strings.
Thomas Z. schrieb:> gepackt wurde wohl...
Mein Rat wäre dabei: Programmiere das Ganze mit einem eigenem Projekt
nach - wenn du die eigentliche Nutz-Funktionalität mal herausgearbeitet
hast.
Das Wurschteln in Zeugs, wo dessen Programmierer zuvörderst an Packen,
Obfuskation und Debuggersperren gedacht hatten, ist immer unerfreulich.
Bei einem eigenen Projekt, wo du dich nur auf die eigentliche
Kernfunktion konzentrierst und all den eigentlich unnützen
Ringsherum-Kruscht wegläßt, wirst du besser vorankommen als mit Stochern
in solchem Zeugs.
Ich vermute mal, daß du aus dem ganzen Zeugs nur den Inhalt des
Unterverzeichnisses "data" benötigst.
W.S.
Egal ob UPX oder DotFix, der Code zum entpacken und entschlüssel muss ja
doch am Einsprungort stehen. Wenn dafür die Unterstützung externer Libs
benötigt wirdm, müssten diese doch entweder statisch gelinked oder nach
dem Start als erstes zugeladen werden. Im letzteren Fall müsste man ja
eindeutige Funktionsaufrufe erkennen können.
Soweit ich Dotfix verstanden habe ist ja deren Konzept eine beliebige
EXE "verschlüsselt einpacken" zu können, d.h. dieser Teil liegt um dem
Programmcode herum (Matroschka-Prinzip). Und hier wird dann auch die
Anti-Debugger Prüfung stattfinden.
Was ich noch nicht ganz verstehe, das ganze muss sich ja im
Arbeitsspeicher abspielen und am Ende das entschlüsselte, lauffähige
Program dort liegen. Gibt es denn eine Möglichkeit das von aussen zu
erkennen und zu dumpen? Vermutlich nicht, das wäre ja viel zu einfach
;-)
Olli Z. schrieb:> Vermutlich nicht, das wäre ja viel zu einfach> ;-)
Unter DOS war das eins meiner leichtestes Übungen. Aber unter Windows
kannst du das glaube ich vergessen.
Ich vermute das Kernel wird sich da einmischen wenn du versuchst auf
eine Speicheradresse zuzugreifen dir dir nicht gehört.
Aber wie du schon sagst das wäre sonst zu einfach. ;)
Olli Z. schrieb:> Was ich noch nicht ganz verstehe, das ganze muss sich ja im> Arbeitsspeicher abspielen und am Ende das entschlüsselte, lauffähige> Program dort liegen. Gibt es denn eine Möglichkeit das von aussen zu> erkennen und zu dumpen? Vermutlich nicht, das wäre ja viel zu einfach
Processhacker kann das, ganz einfach :-)
Bei sowas war das auch schon früher nicht einfach wenn es gut gemacht
war.
Überall "int 3" rein und dann für große Bereiche wo das drin ist zur
Laufzeit Code mehrfach entschlüsseln der den ursprünglichen Code als Key
verwendet um dann nochmal einfach nur den eigentlichen Code mit XOR zu
entschlüsseln. Das gibt dann ein Dilemma weil man entweder durch 100000
Haltepunkte musste oder dann garnicht wusste was die relevanten Teile
sind. Durch das verwenden von geändertem Code (z.B. NOPen der int3s)
konnte dann der Rest nicht mehr ausgepackt werden. Da musste man ewig
zur Laufzeit rummachen und den Code ändern. So ähnlich waren auch später
einige DOS-Viren aufgebaut.
Selbst so ein einfaches Verfahren würde ja heute unter Windows auch
jeden Virenscanner ärgern und, da bin ich mir recht sicher, nicht in
einem Prozess von einem anderen User debugbar sein, usw.
Olli Z. schrieb:> Also ganz klar ist das die EXE gepackt und ggf. auch verschlüsselt ist.
Die Verschlüsselung einer Exe ist SCHWACHSINN! Der Key müsste ja auch in
der Exe sein und wäre somit verfügbar. Ausnahme von dieser Regel sind
Sachen, die den Schlüssel aus einer externen Quelle beziehen, z.B. einem
dieser unsäglichen Kopierschutz-Dongles. Wobei Stand der Technik hier
ist: nicht nur der Schlüssel liegt im Dongle, sondern die komplette
Entschlüsselung und nicht der gesamte Code wird am Stück entschlüsselt,
sondern es sind immer nur kleine Stücke verschlüsselt, die dann "on
demand" entschlüsselt werden und der "Klartext" wird dann sehr schnell
auch wieder gelöscht.
Also: Verschlüsselung kannst du in deinem Fall wohl schon aus rein
theoretischen Erwägungen vergessen. Das Zeug ist einfach nur gepackt und
mit ein paar gängigen Anti-Debugger-Tricks gespickt.
> Too, ExeinfoPE erkennt das und könnte wohl auch eine unkomprimierte> Variante sichern. Dann jedoch schlägt mein Virenscanner an und behauptet> einen Trojaner gefunden zu haben... hm.
Würde micht jetzt nicht gerade sehr wundern, wenn da tatsächlich einer
drin wäre. Denn das ist ein übliches Anliegen solcher Exen: Malware
unerkannt unter die Leute zu bringen.
Thomas Z. schrieb:> Olli Z. schrieb:>> Dann jedoch schlägt mein Virenscanner an und behauptet>> einen Trojaner gefunden zu haben... hm.
So was macht man eh in einer VMM.
c-hater schrieb:> Also: Verschlüsselung kannst du in deinem Fall wohl schon aus rein> theoretischen Erwägungen vergessen. Das Zeug ist einfach nur gepackt und> mit ein paar gängigen Anti-Debugger-Tricks gespickt.
sehe ich auch so. Wobei in diesem Fall ziemlich einfache Varianten zum
Einsatz kommen. UPX ist sicher nicht mehr der StateOfArt Packer. Ich
ärgere mich schon seit Monaten mit einem Stück Software rum was mit
AsProtect geschützt ist.
Bis jetzt ziemlich erfolglos.
> Würde micht jetzt nicht gerade sehr wundern, wenn da tatsächlich einer> drin wäre.
mich schon die Leute die Malware bauen setzen modernere Sachen ein. Das
ist der typische false Alarm der bei so gut wie jedem Debugger Schutz
kommt.
Ok, sprechen wir also eher von Obfuscation :-)
Die einzige Chance die jemand hat seinen Code vor anderen zu sichern ist
diesen zu verschleiern und damit das Debugging/Reverse Engineering durch
Menschen zu erschweren. Bei Maschinencode könnte das auch durch eine VM
erfolgen die sich Bytes aus dem Codeblock liest und diese in Gänze oder
Teilweise über eine Lookuptable in die "echten" Befehle übersetzt und
ausführt.
So oder so muss alles was nötig ist letztlich im Programm stecken. Und
der Start einer EXE ist doch klar geregelt? Der Loader im OS muss die im
Header enthaltenen Libraries laden und an den entry() point springen,
welcher eben nicht der Start der eigentlichen Anwendung ist, sondern der
Verschleierungsroutine.
Um die tatsächliche Speicheradresse der geladenen Libraries durch den
Loader anpassbar zu machen müssen bestimmte Lookuptables unverschlüssel
sein. Also müsste ja zumindest klar sein welche Libs geladen werden.
Die am entry() enthaltenen Anweisungen sind dann vermutlich dazu da
etwaige Debugger zu erkennen, was wohl immer zu einer Beendigung des
Programms führt? Hier müsste man ja auch entsprechende Exit-Befehle
finden? Dann wird der Code wenigstens den nächsten auszuführenden Teil
entpacken, was er sicher nur im Arbeitsspeicher kann, wozu er sicher
weiteren Arbeitsspeicher braucht (malloc() artige Anweisung sollte zu
finden sein?) oder er entschlüsselt inplace durch eine einfache
Byte-Operation (xor, shift, lookuptable, algo).
Wie auch immer, die ersten Zeilen müssten einen gewissen Sinn ergeben.
Die genannten int3 und rdts() Aufrufe könnten eher zur
Debugger-Verhinderung dienen. Wer hat schon Lust eine Million mal F9 zu
drücken? ;-) Für eine CPU is das in Millisekunden erledigt.
Aufgrund des Alters des Tools (ca. 2010 eher früher) werden wohl die
damals gängigen Methoden zum Einsatz gekommen sein und die waren
hoffentlich noch nicht so ausgefeilt.
c-hater schrieb:> Die Verschlüsselung einer Exe ist SCHWACHSINN! Der Key müsste ja auch in> der Exe sein und wäre somit verfügbar
Kommt darauf an. Es gibt Compiler, die sowas machen können. XProfan
ist so einer. Es ist zwar auch ein Interpreter, der aber auch die
Runtime mit dem compilierten Code zur .exe zusammenlinkt. Dabei kann
dieser Zwischencode mit $P+ verschlüsselt werden.
Auszug aus der Hilfe :
1
Wenn die Direktive $P+ oder $P* im Programm vorkommt, wird der Zwischencode, den der Compiler erzeugt,
2
verschlüsselt abgespeichert. Texte, die im Programm vorkommen, können dann nicht mehr mit einem Hex-Editor
3
gelesen werden. So kann keiner Ihre Copyright-Meldungen oder andere Texte verändern. Dem Runtime-Modul
4
und dem Linker ist es egal, ob der Zwischencode (die PRC-Datei) verschlüsselt ist oder nicht.
5
Die Ablaufgeschwindigkeit des Programmes wird nicht beeinflußt, lediglich die Zeit, die das Programm vom
6
Aufruf bis zum Start braucht, wird bei $P+ ein wenig (aber unmerklich) und bei $P* etwas mehr erhöht, da
7
das Programm vor der Ausführung im Speicher entschlüsselt werden muss. Bei $P* ist die Verschlüsselung
8
aufwändiger. Außerdem wechselt von Profan-Version zu Profan-Version die Art der Verschlüsselung.
9
10
Voreingestellt ist $P+. Will man bewußt auf die Verschlüsselung verzichten, kann man sie mit $P- ausschalten.
11
Sobald allerdings Units im Programm eingebunden werden, bleibt ein $P- aus Sicherheitsgründen wirkungslos.
12
13
Anmerkung: In der kostenlosen Schulversion von XProfan bleibt die Verschlüsselung wirkungslos.
14
Ein Einbinden von Units ist dort nicht möglich.
15
16
Hinweis: Das "P" muss groß geschrieben sein!
17
Hinweis: In FreeProfan ist $P* ohne Bedeutung.
Ich wollte nur mal die Arbeitsweise darstellen. Also, als
Schwachsinn vom Autor RGH würde ich das nicht bezeichnen.
Olli Z. schrieb:> Dann wird der Code wenigstens den nächsten auszuführenden Teil> entpacken, was er sicher nur im Arbeitsspeicher kann
Und das entpacken ist damit kombiniert dass der streuwert des entpackten
Codes und größerer RAM Bereiche das secret für die Entschlüsselung des
nächsten Abschnitts ist. Wenn das geschachtelt ist kann man da nicht
einfach irgendwo aus jz jnz machen.
Dein Ansatz dass die Binary alles dabei hat um zu laufen ist richtig,
aber es gibt durch schnellere CPUs und überall schon im Betriebssystem
verfügbare Software so viele Möglichkeiten heute, dass das zu einem sehr
langwierigen Krampf werden kann.