Gabriel Steinbach

April 22, 2008

Wie erkennt ein Programm ob es infiziert ist ?

Gespeichert unter: tec.log.file, www.log.file — Schlagworte: , , , , , , , , , — gabrielstagebuch @ 5:51 Uhr nachmittags

by SnakeByte [ SnakeByte@kryptocrew.de ]

Dieses Tutorial richtet sich an die Programmieren unter euch,
die eine Viruserkennung in ihr Programm einbinden wollen, so
daß es eine Warnung ausgibt, wenn das Programm von einem Virus
infiziert wurde. Dies kann auf mehrere Arten geschehen und ich werde
euch hier ein paar Beispiele in Assember und Visual Basic zeigen.

Dies benötigt normalerweise nicht viel Platz und kann euch helfen den
Benutzer darüber zu informieren, daß euer Programm vielleicht verändert wurde,
egal ob es nun gecrackt, mit einem Virus infiziert oder mit einem File-Joiner
bearbeitet worden ist.

Zuallererst muss man sich darüber Gedanken machen, was ein Virus verändert,
wenn er eine Datei befällt:

- Größe
- Anfangswerte der Register
- Datei an sich

Fangen wir zuerst mit der Größe an. Das Problem hierbei ist, das sie bis zum
Ende der Entwicklung des Programmes nicht feststeht. Auch beim Einfügen des Checks
kann es noch zu Veränderungen der Größe kommen, so das es ausser bei Assemblerprogrammen
recht schwer ist, diese als feste Größe in das Programm einzufügen.
In Assemblerprogrammen kann man allerdings irgendeinen Wert nehmen und diesen nachträglich
per Hexeditor recht einfach ändern. Eine Routine zum überprüfen der eigenen Größe
würde in Win32Asm zum Beispiel so aussehen:

——-8<————
.Code

lea esi, DateiName
lea eax, [WIN32_FIND_DATA]
push eax
push esi
call FindFirstFileA

push eax
call FindClose

cmp dword ptr [WFD_nFileSizeLow], 12345678h

.Data
DateiName db “NamedesProgs”,0

FILETIME STRUC
FT_dwLowDateTime dd ?
FT_dwHighDateTime dd ?
FILETIME ENDS

WIN32_FIND_DATA label byte
WFD_dwFileAttributes dd ?
WFD_ftCreationTime FILETIME ?
WFD_ftLastAccessTime FILETIME ?
WFD_ftLastWriteTime FILETIME ?
WFD_nFileSizeHigh dd ?
WFD_nFileSizeLow dd ?
WFD_dwReserved0 dd ?
WFD_dwReserved1 dd ?
WFD_szFileName db 260d dup (?)
WFD_szAlternateFileName db 13 dup (?)
WFD_szAlternateEnding db 03 dup (?)

——-8<————

Für die 12345678h setzt man dann später die richtige Größe ein.
Man sollte hier auf jeden Fall einen Wert wie 12345678h verwenden, da sich
dieser mit einem Hexeditor später leicht finden lässt.

In Hochsprachen wie Visual Basic ist es schwer per Hexeditor einen Wert wiederzufinden.
Hier ist es sinnvoller eine .INI Datei mit dem Programm zu liefern, die die Dateigröße
enthält. Oder man erstellt diese .INI Datei beim Ersten starten des Programmes,
wobei hier die Gefahr besteht, das das Programm schon vorher infiziert wurde.
Ok, hier das Ganze also in VB:

——-8<————
Public Declare Function FindFirstFile Lib “kernel32″ Alias “FindFirstFileA” (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long
Public Declare Function FindClose Lib “kernel32″ (ByVal hFindFile As Long) As Long
Public Declare Function GetPrivateProfileString Lib “kernel32″ Alias “GetPrivateProfileStringA” (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long

Public Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type

Public Type WIN32_FIND_DATA
dwFileAttributes As Long
ftCreationTime As FILETIME
ftLastAccessTime As FILETIME
ftLastWriteTime As FILETIME
nFileSizeHigh As Long
nFileSizeLow As Long
dwReserved0 As Long
dwReserved1 As Long
cFileName As String * 260
cAlternate As String * 14
End Type

Private Function SelfCheck() As Boolean

‘ Gibt ein True zurück, wenn die Größe gleich ist, ansonsten False
‘ wenn die Datei verändert wurde

Dim finddata As WIN32_FIND_DATA
Dim x As Long
Dim z As Long
Dim Size1 as string
Dim Size2 as string

SelfCheck = False

x = FindFirstFile(”MyFile.exe”, finddata)
DoEvents

If x <> -1 Then Size1 = finddata.nFileSizeLow

z = FindClose(x)

x = GetPrivateProfileString(”StartCheck”, “Size”, ” “, Size2, 255, “MyFile.ini”)

Size2 = Left$(Size2, InStr(Size2, Chr$(0)) - 1)

If Size1 = Size2 then SelfCheck = True

End Function

——-8<————

Die Anfangswerte der Register lassen sich auch nur in Assembler überprüfen, hier
hat EAX den gleichen Wert wie die Anfangs EIP. Dies lässt sich mit wenig Code überprüfen:

——-8<————
Main:
cmp eax, offset Main
jne Infected

;
; Normales Prog..
;

Infected:
; Error MSG !
——-8<————

Der Check an sich hat also nur 7 Bytes, ich denk die kann man Opfern. Zwar speichern
die meisten Viren die Register beim Start und setzen sie in ihren Originalzustand zurück,
aber da der Einsprungspunkt in den Code geändert wurde und nun auf den Virus zeigt, tut
dies auch EAX ;)

Das wohl sicherste ist per CRC32 oder ähnlichem eine Checksumme für die gesamte Datei zu
erstellen und diese per Hexeditor in das Programm einzufügen bzw aus einer Datei zu lesen.
Dadurch wird das Programm auf jede änderung aufmerksam. ( kann auch gegen ein Cracken
des Programmes schützen [ jedenfalls bei schlechten Crackern ] ;)
Der vielleicht einfachste Weg ist es dieses mit einem API zu machen:
CheckSumMappedFile aus der ImageHlp.dll
Dazu wird die Datei geöffnet und gemappt. Dann wird die API aufgerufen, die die
Checksumme der Datei ausgibt. Diese kann man dann mit der vorher gespeicherten Checksumme
vergleichen. Sind sie gleich ist die Datei im Orignialzustand, wenn nicht sollte das
Programm reagieren.

Einige werden nun sagen, ok, aber was ist mit Kompagnion Viren, die die Datei nur
umbenennen ? Ok, zum einen werden unsere Tests fehlschlagen, die den Namen der Datei
benutzen um die Größe zu ermitteln. Zum anderen leistet hier ein anderer API gute Dienste:

GetCommandLineA

Gibt die Kommandozeile mit der das Programm gestartet wurde zurück.
“C:\Pfad\Programm.exe /parameter 1 /wasauchimmer”
Durch diese kann man zum einen den aktuellen Namen erhalten, und wenn dieser nicht
mit dem Originalnamen übereinstimmt sucht man nach “Originalname.*” und wenn dann eine
EXE, COM oder BAT Datei gefunden wird, kann man recht sicher sein, das hier ein
Kompagnion Virus seine Finger im Spiel hatte.

Was ist mit Stealth Viren ? Nun unter Windows hab ich noch keinen Stealth Virus gesehen,
aber gegen diese hilft im Endeffekt nur das überprüfen des Anfangswertes von EAX,
da diese die Dateigröße ja zum Originalwert verändern.

Das wars dann auch schon wieder für dieses Mal.

cu SnakeByte

via linkpost thx to Anonymous

Keine Kommentare »

Noch keine Kommentare.

RSS-Feed für Kommentare zu diesem Beitrag. TrackBack URI

Einen Kommentar schreiben

Bloggen Sie auf WordPress.com.