Showing posts with label mfc. Show all posts
Showing posts with label mfc. Show all posts

Wednesday, July 29, 2020

further into the emotet 1st level packer

emotet mfc
https://app.any.run/tasks/585ddd5e-0dde-421f-8b8a-e7dbaf4f8c05/
3F32E053657036D09C84D6DAD220EF50

my random notes on where i got and what i saw

Go into AfxDlgProc() set breakpoint on
call dword ptr [edx+144h]

step into the call (renamed to subEmotetDecryptor)
 this is likely the start of the Emotet Decryptor

subEmotetDecryptor()
- CDialog::OnInitDialog()
- GetSystemMenu()
- FromHandle()
- subMove1ValuetoEAX()
- call dword ptr [edx+0ch]
- AfxFindStringResourceHandle()
- subFindResource()
-- FindResourceA()
-- localFunction9()
--- LoadResource()
--- LockResource()
--- SizeOfResource()
--- localFunction10() [GetVersionExA, InterlockedExchange]
--- WideCharToMultiByte()
--- localFunction11()
---- call dword ptr [edx+8]
--- localFunction10() [GetVersionExA, InterlockedExchange]
--- WideCharToMultiByte()
--- localFunction6()
- AppendMenuA()
- AppendMenuA()
- "mshta.exe" stack string
- _wcslen()
- subLotsSubCalls1()
- _wcslen()
- subLotsSubCalls1()
- _wcslen()
- subLotsSubCalls1()
- subLotsSubCalls1b()
- subLotsSubCalls1b()
- subLotsSubCalls1b()
- LoadLibraryExW()
- long string "9xgnie40s......"
- subGetApis()
-- LoadLibraryExA()
--- stack string "VirtaAocExNuma"
--- stack string "kerne32.d"
--- LoadLibraryExA()
--- GetProcAddress
--- stack string "taskmgr.exe"
--- LoadLibraryExA()
--- GetCurrentProcess()
--- subFindResourceHandleCallPtr()
--- call ebp (1st unpacked code????)
---- subGetApiIntoEax (LoadLibraryA)
---- subGetApiIntoEax (GetProcAddress)
---- subGetApiIntoEax (VirtualAlloc)
---- subGetApiIntoEax (VirtualProtect)
---- subGetApiIntoEax (ZwFlushInstructionCache)
---- subGetApiIntoEax (GetNativeSystemInfo)
---- call ebx (GetNativeSystemInfo)
---- eax = 4096 (on my machine) - 1 = 4095 <== dwPageSize? size of page used by VirtualAlloc
---- ebx = 53248 (on my machine)
---- ecx = FFF + C200 = D1FF
---- edx = !FFF = FFFFF000
---- eax = eax + ebx = DFFF
---- ecx = ecx & edx = D000
---- eax = eax & edx = D000
---- if eax != ecx [exit]
---- call ebp (VirtualAlloc(null, 53248, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE), returns EAX = 00300000
---- call [esp+5Ch+var_3C] (LoadLibraryA("Kernel32.dll"), returns EAX=76140000
---- call esi (GetProcAddress(7614000, IsProcessorFeaturePresent), returns EAX=76155135
---- loop
----- call [esp+68h+var_2C] (VirtualProtect(0x00301000, 28160, PAGE_EXECUTE_READ)
----- call [esp+68h+var_2C] (VirtualProtect(0x00308000, 512, PAGE_READONLY)
----- call [esp+68h+var_2C] (VirtualProtect(0x00309000, 3072, PAGE_READWRITE)
----- call [esp+68h+var_2C] (VirtualProtect(0x0030B000, 512, PAGE_READONLY)
----- call [esp+68h+var_2C] (VirtualProtect(0x0030C000, 512, PAGE_READONLY)
---- call [esp+64h+var_28] (ZwFlushInstructionCache(0xFFFFFFFF, null, null)
---- call esi (local code debug038:0034244)
----- call localFunction1()
------ ***lots of calls to decryptApi() and many much more code***, i set breakpoints on decryptApi calls, they are below
------ GetProcessHeap(), returns EAX=0x00520000
------ GetModuleHandleA("NTDLL"), returns EAX=77910000
------ RtlAllocateHeap(0x00520000, HEAP_ZERO_MEMORY, 48)
------ GetProcessHeap()
------ RtlAllocateHeap(0x00520000, HEAP_ZERO_MEMORY, 48) <== lots of these, skipping them in the future
------ LoadLibraryW("advapi32.dll"), returns EAX=75D20000
------ GetProcessHeap() <== lots of these, skipping them in the future
------ HeapFree() <== lots of these, skipping them in the future
------ LoadLibraryW("crypt32.dll"), returns EAX=753C0000
------ LoadLibraryW("shell32.dll"), returns EAX=76480000
------ LoadLibraryW("shlwapi.dll"), returns EAX=760B0000
------ LoadLibraryW("urlmon.dll"), returns EAX=750C0000
------ LoadLibraryW("userenv.dll"), returns EAX=76080000
------ LoadLibraryW("wininet.dll"), returns EAX=75680000
------ LoadLibraryW("stsapi32.dll"), returns EAX=74B50000
------ OpenScManagerW(null, null, SC_MANAGER_ALL_ACCESS)
------ CloseServiceHandle()
------ SHGetFolderPathW()
------ GetModuleFileNameW(null) <-- gets full path of this exe
------ PathSkipRootW()
------ PathFindExtensionW()
------ lstrcpynW()
------ GetModuleFileNameW(null)
------ snwprintf()
------ FindFirstFileW("c:\windows\system32\")
------ loop
------- FindNextFileW()
-------  sometimes ==> PathFindExtensionW("12520437.cpx") <-- ran multiple file names, folders, dlls, etc.
------ FindClose()
------ GetCommandLineW()
------ CommandLineToArgW()
------ LocalFree()
------ GetModuleFileNameW(null)
------ CreateFileW("c:\users\win7\desktop\emotet.exe", FILE_READ_ATTRIBUTES, FILE_SHARE_READ) <-- name of this executable
------ GetFileInformationByHandleEx()
------ CloseHandle()
------ GetSystemTimeAsFileTime()
------ OpenScManagerW()
------ OpenServiceW(, "emotet", ) <-- name of current executable, returns NULL because doesn't exist
------ CloseServiceHandle()
------ GetTickCount()
------ lstrcpyW()
------ lstrlenW()
------ GetTickCount()
------ lstrcpyW()
------ lstrlenW()
------ GetCurrentProcessID()
------ memset(0x18E76Ch, 0, 30)
------ memset(0x18E76Ch, 0, 500)
------ memset(..)
------ lstrcpyW("c:\windows\syswow64\cmdl32\negoexts.exe", ..)
------ SHFileOperationW()

*** IDS thew a next step debugger exception here ***

----- call decryptApi()
----- call eax
---- *** more code ***
---- call eax (near the bottom)
- call dword ptr [edx+4]
- SendMessageA()
- SendMessageA()
- SendMessageA()
- call dword ptr [edx+140h]
- string "http://www.ucancode.net..."
- subFindResourceHandleCallPtr2()
- call dword ptr [eax+138h]
- Cwnd::GetDlgItem()
- GetWindowRect()
- Cwnd::ScreenToClient()

Tuesday, July 28, 2020

emotet mfc using CreateDlgIndirect lpDialogFunc call-back

emotet mfc starting point notes, trying to figure out where the malicious code starts
https://app.any.run/tasks/585ddd5e-0dde-421f-8b8a-e7dbaf4f8c05/
3F32E053657036D09C84D6DAD220EF50

WinMain()
-AfxGetThread()
-AfxGetModuleState()
-AfxWinInit()
--AfxGetModuleState()
--AfxGetModuleState()
--CWinApp::SetCurrentHandles()
--AfxGetModuleState()
--AfxInitThread()
---AfxGetModuleState()
---AfxGetThreadState()
---AfxMsgFilterHook()
--GetModuleHandleA(user32.dll)
--GetProcAddress(NotifyWinEvent)
-call dword ptr [eax+90h] (which is CWinApp::InitApplication)
-call dword ptr [eax+50h] (which is local function in .text)
-- AfxEnableControlContainer()
-- call localFunction1()
--- CDialog::CDialog()
--- call localFunction3()
---- CWnd::CWnd
---- call localFunction4() [just moves 1 memory slot]
---- call dword ptr [edx+0ch]
---- CToolTipCtrl::CToolTipCtrl()
---- GetSysColor
---- call localFunction5()
----- branches to possibly these items
------ localFunction6()
------- branches to possibly these items
-------- unknown_libname (mfc 3.1-14.0 32bit)
-------- AfxThrowOleException
------ call dword ptr [edx+4]
----- call dword ptr [eax+0ch]
--- CWnd::CWnd()
--- call ??_L@... (vector constructor iterator)
--- AfxGetModuleState()
--- AfxGetModuleState()
--- LoadIconA
-- CDialog::DoModal()
-- call localFunction2()
-if success
--call dword ptr [eax+54h] (which is CWinApp::Run)
-if failure
--call dword ptr [eax+68h] (which is CWinApp::ExitInstance)
-AfxWinTerm

my 1st assumption was to break on
 CWinApp::Run
that didn't work, emotet still installed service & never hit my breakpoint

so instead i end up looking at that local function in .text that calls
 AfxEnableControlContainer, DoModal
googling shows this template below is common in C# mfc code that does a "popup dialog box"
 CWinApp::InitInstance()
 AfxEnableControlContainer()
 CMainDialog dlg
 dlg.DoModal()
emotet doesn't show a modal (unless it's hidden?) but maybe there is hidden code in the modal???

trying to find a good breakpoint
- AfxEnableControlContainer is hit
- call localFunction1 is hit
- DoModal is hit
- call localFunction2 is NOT hit
malicious code appears to execute & exit when DoModal is called

Inside DoModal i first tried breakpoints at
 CDialog::PostModal
but it never hit my breakspoint, so malicious code ran before that

DoModal (still in the .text section)
- AfxGetModuleState()
- AfxGetModuleState()
- FindResourceA()
- LoadResource()
- LockResource()
- CDialog::PreModal()
- AfxUnhookWindowCreate()
- AfxHookWindowCreate()
- CWnd::FromHandle()
- CWnd::CreateDlgIndirect()
- ... more ...

Stepping thru DoModal, the malicious code runs after call to
 CWnd::CreateDlgIndirect()
so I need to dig more in there

msdn ( https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createdialogindirecta )
appears to indicate that there is a lpDialogFunc of type DLGPROC
 this can be a call-back procedure, i think there is where the malicious code is

CreateDlgIndirect()
- CreateDialogIndirectParamA(..., AfxDlgProc/lpDialogFunc, )
-- CreateDialogIndirectParamAorW()
--- call near ptr unk_76371801
--- call near ptr unk_763718E1
---- AfxDlgProc() <-- i think this is the CreateDlgIndirect using the call-back function
---- call dword ptr [edx+144h]
------ call localFunction7() in .text
------- CDialog::OnInitDialog()
------- GetSystemMenu()
------- FromHandle()
------- localFunction4()
------- call dword ptr [edx+0ch]
------- AfxFindStringResourceHandle()
------- localFunction8()  <-- possibly the start of the malicious code
-------- FindResourceA()
-------- localFunction9()
--------- LoadResource()
--------- LockResource()
--------- SizeOfResource()
--------- localFunction10() [GetVersionExA, InterlockedExchange]
--------- WideCharToMultiByte()
--------- localFunction11()
---------- call dword ptr [edx+8]
--------- localFunction10() [GetVersionExA, InterlockedExchange]
--------- WideCharToMultiByte()
--------- localFunction6()
------- AppendMenuA()
------- !!! DEFINITELY EVIL CODE !!!
------- (stack string for mshta.exe)