And also because malware builders seems to be fashion these days.
When malware writers give only bins and no builder, the only way to fuck them up is to codecave the bin for make it do what we want.
You have many advantages because you can remove bugs, add features... you are free.
For make this, you will need: .ollydbg, HexDecCharEditor v1.02 (or any other hex editor) and a minimum of intelligence.
For the coding part i've choose 2 languages: Visual Basic 6 and Assembly with masm32 and WinASM as IDE. (two extreme, one high and one low-level language)
So let's start.
The first step is to locate things you need to modify inside the malware (e.g: gate urls, timers, enc keys)
For malware, do to ethical issue i will chose a simple unNagMe coded fastly in ASM.
And like that you can try to modify things without the fear of being infected.
This executable can be downloaded with both sources code at the end of this post.
Run Ollydbg and load the executable inside to have a look and see what the code look's like
Pretty simple with a good zone of zero filled bytes, and we see strings are pointing to 0x403000 and 0x403023
We need to find a zone with enought nullbytes to insert our url, the zero filled place on the screenshot can be good but i've choose to add my strings under original one.
This green place can be good and used, i've used HexDecCharEditor to find it:
Now that we have found a place for our URL we need to modify the executable to make it go on our string.
(843, VA=0x403043)
Double click on the line and modify the code, then: Right Click>Copy to executable>All modification
A window appear: Click 'Copy all' then another window appear, right click on it and click "Save file".
Everything is cool now.
We just need to code a program who will edit our binary at 0x403043
For that i will modify some of my old VB6 and ASM codes
Basic interface:
Please note that for Visual Basic i've used a commonDialog mean the program is dependent of one ocx: COMDLG32.
The code for boths are a bit hardcoded and can be improved but that work and it's enought for me.
One the file is builded the hexed version is named "Malware.exe.ViR"
ASM Code, patch.asm:
.386
.model flat, stdcall
option casemap :none
include windows.inc
include user32.inc
include kernel32.inc
include shell32.inc
include advapi32.inc
include gdi32.inc
include comctl32.inc
include comdlg32.inc
include masm32.inc
include /masm32/macros/macros.asm
includelib user32.lib
includelib kernel32.lib
includelib shell32.lib
includelib advapi32.lib
includelib gdi32.lib
includelib comctl32.lib
includelib comdlg32.lib
includelib masm32.lib
includelib winmm.lib
DlgProc Proto :DWORD,:DWORD,:DWORD,:DWORD
List Proto :DWORD,:DWORD
Patch Proto :DWORD
Scan Proto
.data
ProgId db "RED WM",0
TargetName equ "- SomeAppName vX.XX.XXX -",0
TargetName2 equ "ExampleApp.exe",0
NameofTarget db TargetName,0
SecondN db "Malware.exe.ViR",0
Sequence db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
WBuffer db 256 dup(00)
PatchOffset dd 00000843h ; VA=403043
StartNfo db "* Close the application if open.",0
StartNfo2 db "* Just apply the patch.",0
StartNfo3 db "* Waiting for your order ...",0
;------------------------------------------------
Backup db "* Offsets patched, Creating Backup...",0
Success db "* Target patched successfully, n-j0y ;)",0
Version db "* Invalid File version, or already patched.",0
Nothing db "* Nothing patched, Aborted*",0
Searching db "* Analysing offsets...",0
ReadError db "* Can't Read the file.",0
WriteError db "* Nothing patched, Aborted*",0
OpenError db "* File Already open, close the file and retry.",0
;--------------------------------------------------------------------------------------------------------------
FileFilter db TargetName2,0
;--------------------------------------------------------------------------------------------------------------
.data?
hInstance HINSTANCE ?
hTarget HINSTANCE ?
hTargetMap HINSTANCE ?
ofn OPENFILENAME <>
RBuffer dd ?
BytesRead db ?
BytesWritten db ?
pMapView dd ?
FileSize dd ?
SearchOffset dd ?
hMapping dd ?
pMapping dd ?
TargetN db 512 dup(?)
inBytes db 512 dup(?)
alen dd ?
.const
IDD_CRACKME equ 101
IDC_PATCH equ 2001
IDC_EXIT equ 2002
IDC_ABOUT equ 2003
icon equ 2000
IDC_TARGET equ 2006
IDC_LISTBOX equ 1002
IDC_BYTES equ 2012
.code
xstart:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke InitCommonControls
invoke DialogBoxParam, hInstance, IDD_CRACKME, NULL, addr DlgProc, NULL
invoke ExitProcess,eax
align dword
DlgProc proc hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
;-------- Load Cursor ---------
invoke LoadCursor,hInstance,300
invoke SetCursor,eax
;------------------------------
.if uMsg == WM_INITDIALOG
invoke LoadIcon,hInstance,icon
invoke SendMessage,hWnd,WM_SETICON,ICON_SMALL, eax
invoke GetDlgItem,hWnd,IDC_BYTES
invoke SendMessage, eax, EM_SETLIMITTEXT,64,0
invoke SendMessage,hWnd,WM_SETICON,1,eax
invoke SetWindowText,hWnd, addr ProgId
invoke SetDlgItemText,hWnd,IDC_TARGET,addr NameofTarget
invoke List,hWnd,addr StartNfo
invoke List,hWnd,addr StartNfo2
invoke List,hWnd,addr StartNfo3
invoke SetFocus,eax
.elseif uMsg == WM_COMMAND
mov eax,wParam
.if eax==IDC_PATCH
invoke GetDlgItemText,hWnd,IDC_BYTES,addr WBuffer,sizeof WBuffer
.if eax == 0 || eax > 64
invoke List,hWnd,chr$("URL field is either empty or has more than 64 chars!")
ret
.endif
mov ofn.lStructSize,SIZEOF ofn
mov ofn.lpstrFilter,offset FileFilter
mov ofn.lpstrFile,offset TargetN
mov ofn.nMaxFile,512
mov ofn.Flags,OFN_FILEMUSTEXIST+OFN_PATHMUSTEXIST+\
OFN_LONGNAMES+OFN_EXPLORER+OFN_HIDEREADONLY
invoke GetOpenFileName,addr ofn
.if eax==TRUE
invoke CopyFile, addr TargetN, addr SecondN,TRUE
invoke Patch,hWnd
.endif
.elseif eax==IDC_EXIT
invoke SendMessage,hWnd,WM_CLOSE,0,0
.elseif eax==IDC_ABOUT
invoke MessageBox,hWnd,chr$("** RED CREW 2013"),chr$("About"),MB_ICONINFORMATION
.endif
.endif
.if uMsg==WM_RBUTTONDOWN
invoke ShowWindow,hWnd,SW_MINIMIZE
.endif
.if uMsg == WM_CLOSE
invoke EndDialog, hWnd, 0
.endif
xor eax,eax
ret
ret
DlgProc endp
List proc hWnd:HWND, pMsg:DWORD
invoke SendDlgItemMessage,hWnd,IDC_LISTBOX,LB_ADDSTRING,0,pMsg
invoke SendDlgItemMessage,hWnd,IDC_LISTBOX,WM_VSCROLL,SB_BOTTOM,0
Ret
List EndP
Patch proc hWnd:HWND
invoke GetFileAttributes,addr SecondN
.if eax!=FILE_ATTRIBUTE_NORMAL
invoke SetFileAttributes,addr SecondN,FILE_ATTRIBUTE_NORMAL
.endif
invoke CreateFile,addr SecondN,\
GENERIC_READ+GENERIC_WRITE,\
FILE_SHARE_READ+FILE_SHARE_WRITE,\
NULL,\
OPEN_EXISTING,\
FILE_ATTRIBUTE_NORMAL,\
NULL
.if eax!=INVALID_HANDLE_VALUE
mov hTarget,eax
invoke List,hWnd,addr Searching
invoke SetFilePointer,hTarget,PatchOffset,NULL,FILE_BEGIN
invoke ReadFile,hTarget,addr RBuffer,64,addr BytesRead,NULL
.if BytesRead==64
mov eax,dword ptr [RBuffer]
.if eax==dword ptr [Sequence]
invoke SetFilePointer,hTarget,PatchOffset,NULL,FILE_BEGIN
; invoke CopyFile, addr TargetN, addr BackupName,TRUE
invoke WriteFile,hTarget,addr WBuffer,64,addr BytesWritten,NULL
.if BytesWritten==64
invoke List,hWnd,addr Backup
invoke List,hWnd,addr Success
.else
.endif
.elseif eax==dword ptr [WBuffer]
invoke List,hWnd,addr Version
invoke List,hWnd,addr Nothing
.endif
.endif
.else
invoke List,hWnd,addr Searching
invoke List,hWnd,addr OpenError
invoke List,hWnd,addr Nothing
.endif
invoke CloseHandle,hTarget
Ret
Patch EndP
end xstart
.model flat, stdcall
option casemap :none
include windows.inc
include user32.inc
include kernel32.inc
include shell32.inc
include advapi32.inc
include gdi32.inc
include comctl32.inc
include comdlg32.inc
include masm32.inc
include /masm32/macros/macros.asm
includelib user32.lib
includelib kernel32.lib
includelib shell32.lib
includelib advapi32.lib
includelib gdi32.lib
includelib comctl32.lib
includelib comdlg32.lib
includelib masm32.lib
includelib winmm.lib
DlgProc Proto :DWORD,:DWORD,:DWORD,:DWORD
List Proto :DWORD,:DWORD
Patch Proto :DWORD
Scan Proto
.data
ProgId db "RED WM",0
TargetName equ "- SomeAppName vX.XX.XXX -",0
TargetName2 equ "ExampleApp.exe",0
NameofTarget db TargetName,0
SecondN db "Malware.exe.ViR",0
Sequence db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
WBuffer db 256 dup(00)
PatchOffset dd 00000843h ; VA=403043
StartNfo db "* Close the application if open.",0
StartNfo2 db "* Just apply the patch.",0
StartNfo3 db "* Waiting for your order ...",0
;------------------------------------------------
Backup db "* Offsets patched, Creating Backup...",0
Success db "* Target patched successfully, n-j0y ;)",0
Version db "* Invalid File version, or already patched.",0
Nothing db "* Nothing patched, Aborted*",0
Searching db "* Analysing offsets...",0
ReadError db "* Can't Read the file.",0
WriteError db "* Nothing patched, Aborted*",0
OpenError db "* File Already open, close the file and retry.",0
;--------------------------------------------------------------------------------------------------------------
FileFilter db TargetName2,0
;--------------------------------------------------------------------------------------------------------------
.data?
hInstance HINSTANCE ?
hTarget HINSTANCE ?
hTargetMap HINSTANCE ?
ofn OPENFILENAME <>
RBuffer dd ?
BytesRead db ?
BytesWritten db ?
pMapView dd ?
FileSize dd ?
SearchOffset dd ?
hMapping dd ?
pMapping dd ?
TargetN db 512 dup(?)
inBytes db 512 dup(?)
alen dd ?
.const
IDD_CRACKME equ 101
IDC_PATCH equ 2001
IDC_EXIT equ 2002
IDC_ABOUT equ 2003
icon equ 2000
IDC_TARGET equ 2006
IDC_LISTBOX equ 1002
IDC_BYTES equ 2012
.code
xstart:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke InitCommonControls
invoke DialogBoxParam, hInstance, IDD_CRACKME, NULL, addr DlgProc, NULL
invoke ExitProcess,eax
align dword
DlgProc proc hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
;-------- Load Cursor ---------
invoke LoadCursor,hInstance,300
invoke SetCursor,eax
;------------------------------
.if uMsg == WM_INITDIALOG
invoke LoadIcon,hInstance,icon
invoke SendMessage,hWnd,WM_SETICON,ICON_SMALL, eax
invoke GetDlgItem,hWnd,IDC_BYTES
invoke SendMessage, eax, EM_SETLIMITTEXT,64,0
invoke SendMessage,hWnd,WM_SETICON,1,eax
invoke SetWindowText,hWnd, addr ProgId
invoke SetDlgItemText,hWnd,IDC_TARGET,addr NameofTarget
invoke List,hWnd,addr StartNfo
invoke List,hWnd,addr StartNfo2
invoke List,hWnd,addr StartNfo3
invoke SetFocus,eax
.elseif uMsg == WM_COMMAND
mov eax,wParam
.if eax==IDC_PATCH
invoke GetDlgItemText,hWnd,IDC_BYTES,addr WBuffer,sizeof WBuffer
.if eax == 0 || eax > 64
invoke List,hWnd,chr$("URL field is either empty or has more than 64 chars!")
ret
.endif
mov ofn.lStructSize,SIZEOF ofn
mov ofn.lpstrFilter,offset FileFilter
mov ofn.lpstrFile,offset TargetN
mov ofn.nMaxFile,512
mov ofn.Flags,OFN_FILEMUSTEXIST+OFN_PATHMUSTEXIST+\
OFN_LONGNAMES+OFN_EXPLORER+OFN_HIDEREADONLY
invoke GetOpenFileName,addr ofn
.if eax==TRUE
invoke CopyFile, addr TargetN, addr SecondN,TRUE
invoke Patch,hWnd
.endif
.elseif eax==IDC_EXIT
invoke SendMessage,hWnd,WM_CLOSE,0,0
.elseif eax==IDC_ABOUT
invoke MessageBox,hWnd,chr$("** RED CREW 2013"),chr$("About"),MB_ICONINFORMATION
.endif
.endif
.if uMsg==WM_RBUTTONDOWN
invoke ShowWindow,hWnd,SW_MINIMIZE
.endif
.if uMsg == WM_CLOSE
invoke EndDialog, hWnd, 0
.endif
xor eax,eax
ret
ret
DlgProc endp
List proc hWnd:HWND, pMsg:DWORD
invoke SendDlgItemMessage,hWnd,IDC_LISTBOX,LB_ADDSTRING,0,pMsg
invoke SendDlgItemMessage,hWnd,IDC_LISTBOX,WM_VSCROLL,SB_BOTTOM,0
Ret
List EndP
Patch proc hWnd:HWND
invoke GetFileAttributes,addr SecondN
.if eax!=FILE_ATTRIBUTE_NORMAL
invoke SetFileAttributes,addr SecondN,FILE_ATTRIBUTE_NORMAL
.endif
invoke CreateFile,addr SecondN,\
GENERIC_READ+GENERIC_WRITE,\
FILE_SHARE_READ+FILE_SHARE_WRITE,\
NULL,\
OPEN_EXISTING,\
FILE_ATTRIBUTE_NORMAL,\
NULL
.if eax!=INVALID_HANDLE_VALUE
mov hTarget,eax
invoke List,hWnd,addr Searching
invoke SetFilePointer,hTarget,PatchOffset,NULL,FILE_BEGIN
invoke ReadFile,hTarget,addr RBuffer,64,addr BytesRead,NULL
.if BytesRead==64
mov eax,dword ptr [RBuffer]
.if eax==dword ptr [Sequence]
invoke SetFilePointer,hTarget,PatchOffset,NULL,FILE_BEGIN
; invoke CopyFile, addr TargetN, addr BackupName,TRUE
invoke WriteFile,hTarget,addr WBuffer,64,addr BytesWritten,NULL
.if BytesWritten==64
invoke List,hWnd,addr Backup
invoke List,hWnd,addr Success
.else
.endif
.elseif eax==dword ptr [WBuffer]
invoke List,hWnd,addr Version
invoke List,hWnd,addr Nothing
.endif
.endif
.else
invoke List,hWnd,addr Searching
invoke List,hWnd,addr OpenError
invoke List,hWnd,addr Nothing
.endif
invoke CloseHandle,hTarget
Ret
Patch EndP
end xstart
rsrc.rc:
;This Resource Script was generated by WinAsm Studio.
#define IDC_STATIC2011 2011
#define IDC_BYTES 2012
#define IDC_GROUPBOX2013 2013
#define IDC_GROUPBOX2015 2015
#define IDC_GROUPBOX2016 2016
2000 ICON DISCARDABLE "RED.ico"
1 24 DISCARDABLE "manifest.xml"
300 CURSOR DISCARDABLE "Crystal Clear arrow.cur"
101 DIALOGEX 0,0,311,136
FONT 8,"MS Sans Serif"
STYLE 0x80c00880
EXSTYLE 0x00000008
BEGIN
CONTROL "RED CREW",IDC_GROUPBOX2013,"Button",0x50000007,3,3,304,130,0x00000000
CONTROL "Control",IDC_GROUPBOX2016,"Button",0x50000007,230,65,64,59,0x00000000
CONTROL "Status",IDC_GROUPBOX2015,"Button",0x50000007,13,65,214,59,0x00000000
CONTROL "Patch",2001,"Button",0x50010000,240,77,42,13,0x00000000
CONTROL "About",2003,"Button",0x50010000,240,92,43,13,0x00000000
CONTROL "Target:",2004,"Static",0x50000001,13,15,23,10,0x00000000
CONTROL "",2006,"Edit",0x50010881,13,25,281,11,0x00000200
CONTROL "Exit",2002,"Button",0x50010000,240,108,43,13,0x00000000
CONTROL "",1002,"ListBox",0x50010140,20,77,201,38,0x00000200
CONTROL "URL:",IDC_STATIC2011,"Static",0x50000000,13,40,41,10,0x00000000
CONTROL "",IDC_BYTES,"Edit",0x50010081,13,49,281,11,0x00000200
END
102 DIALOGEX 10,10,206,113
FONT 8,"Tahoma"
STYLE 0x90480800
EXSTYLE 0x00000000
BEGIN
END
#define IDC_STATIC2011 2011
#define IDC_BYTES 2012
#define IDC_GROUPBOX2013 2013
#define IDC_GROUPBOX2015 2015
#define IDC_GROUPBOX2016 2016
2000 ICON DISCARDABLE "RED.ico"
1 24 DISCARDABLE "manifest.xml"
300 CURSOR DISCARDABLE "Crystal Clear arrow.cur"
101 DIALOGEX 0,0,311,136
FONT 8,"MS Sans Serif"
STYLE 0x80c00880
EXSTYLE 0x00000008
BEGIN
CONTROL "RED CREW",IDC_GROUPBOX2013,"Button",0x50000007,3,3,304,130,0x00000000
CONTROL "Control",IDC_GROUPBOX2016,"Button",0x50000007,230,65,64,59,0x00000000
CONTROL "Status",IDC_GROUPBOX2015,"Button",0x50000007,13,65,214,59,0x00000000
CONTROL "Patch",2001,"Button",0x50010000,240,77,42,13,0x00000000
CONTROL "About",2003,"Button",0x50010000,240,92,43,13,0x00000000
CONTROL "Target:",2004,"Static",0x50000001,13,15,23,10,0x00000000
CONTROL "",2006,"Edit",0x50010881,13,25,281,11,0x00000200
CONTROL "Exit",2002,"Button",0x50010000,240,108,43,13,0x00000000
CONTROL "",1002,"ListBox",0x50010140,20,77,201,38,0x00000200
CONTROL "URL:",IDC_STATIC2011,"Static",0x50000000,13,40,41,10,0x00000000
CONTROL "",IDC_BYTES,"Edit",0x50010081,13,49,281,11,0x00000200
END
102 DIALOGEX 10,10,206,113
FONT 8,"Tahoma"
STYLE 0x90480800
EXSTYLE 0x00000000
BEGIN
END
manifest.xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.9.2.0" processorArchitecture="x86" name="NoName" type="win32"/>
<description>NoDes</description>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*"/>
</dependentAssembly>
</dependency>
</assembly>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.9.2.0" processorArchitecture="x86" name="NoName" type="win32"/>
<description>NoDes</description>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*"/>
</dependentAssembly>
</dependency>
</assembly>
The end.
Don't hesitate to show examples of codes if you are motivated.
No password on archive because nothing is infected.
And if you want some fun: InjectMe #1, InjectMe #2
Other tutorials (in French sorry)
Etude sur l'indétection du Server de Bifrost 1.2d auprés des Antivirus
ShmeitCorp Memento 6: StartClean Patcher
Package download: http://temari.fr/PackageHex.zip
Well done, thanks you.
ReplyDeleteI like your blog in general, but why are you educating the script kiddies?
ReplyDeleteJust curious to see what they can do and with wich one
ReplyDeletenot educating the scrip kiddies alone he is educating researchers too . cant you see the positive side of the tutorial as well?
Delete@Anonymous He was referring to himself...
DeleteXylibox, awesome work as usual, just a few typos here and there, which is fine since English n'est pas votre premier langue.
DeleteFor instance just for reference a few corrections as a friend -
which (not wich)
"Please note that for Visual Basic I've used a commonDialog meaning the program is dependent on one ocx component: COMDLG32.
The code for both are a bit hardcoded and can be improved but it works and it is enough for me.
Once the file is built the hexed version is named "Malware.exe.ViR""
Btw I could help do full proofreading of your articles since I think they have a lot to offer. You can get in touch at fundun1000@gmail.com
ASM code is commented well-cleared but what about the VB6 code? How change the offset to patch? (Sorry I'm not a vb dev but I'm curious).
ReplyDeleteThanks Xyl'!