近期,火绒安全实验室收到用户反馈称《Wallpaper Engine:壁纸引擎》下载的壁纸打开之后造成Steam账号异常,火绒安全工程师第一时间为用户提供技术支持,提取样本并进行分析。分析过程中发现该程序为正常壁纸文件捆绑了恶意的 Steam 盗号木马,用户在点击该程序时只会看到壁纸界面,但盗号木马在后台程序也会“悄悄”运行。目前,火绒安全产品可对上述病毒进行拦截查杀,请广大用户及时更新病毒库以提高防御能力。
![Image-0.png](/__local/8/F8/97/53A889F9DB16E79B56A15EF4C63_7AC9DEEB_2FAC.png?e=.png)
火绒查杀图
《Wallpaper Engine:壁纸引擎》曾被指责 "黄油" 与 "盗号木马”泛滥,在此,火绒工程师建议大家在下载壁纸时,尽量选择正规可信的壁纸程序,并保持火绒等安全软件的开启。
![Image-1.png](/__local/2/57/6E/CD02DFA79F46FEC39BD49C6AF2B_086E39FC_6B0AA.png?e=.png)
Wallpaper Engine
样本执行流程图如下所示:
![Image-2.png](/__local/F/AA/B2/81D86984B198B46C0EDA4372D82_0CFD21C3_10452.png?e=.png)
执行流程图
一、样本分析
文件打开后是一个以 HTML 后缀伪装的 exe 文件 "删掉HTML后缀后打开.exe" ,该 exe 实际上是一个自解压压缩包,并会在启动时执行 wehelpe.exe 和 rE.exe:
![Image-3.png](/__local/B/38/26/91758B5698B7A42F53F25042303_A2D4CA4F_CEE9.png?e=.png)
自解压压缩包
其中rE.exe 是《Wallpaper Engine:壁纸引擎》的正常壁纸程序,而 wehelpe.exe 则是由易语言编写的 Steam 恶意盗号木马:
![Image-4.png](/__local/9/00/B0/E443D219D97E2CB65C5194A998A_95630703_31A9.png?e=.png)
易语言程序入口点
前期准备:
样本在开始盗号前,会先设立一系列相关操作保证盗号流程顺利进行,其中包括提升权限、持久化、强制重新登录等操作,具体细节如下:
提权操作——获取 SE_DEBUG_NAME 权限,该权限允许跨进程操作,用于后续读取 Steam 内存:
![Image-5.png](/__local/5/2E/A5/49225F89866CAFDA2743688AEE5_7AAA70DF_6F47.png?e=.png)
权限提升
驻留操作——对 wehelpe.exe 和 wallpaper64 设立开机自启动注册表来进行驻留:
![Image-6.png](/__local/6/B7/A3/094973662EFC018E942C580962A_49C39F0E_6882.png?e=.png)
持久化操作
强制重新登录操作——设置 Steam 下 AutoLoginUser 字符为 0 ,这样会迫使用户重新登录,刷新 token 时效:
![Image-7.png](/__local/3/1E/37/93C73A0E3AE52DDADA89D6094F4_A1C5348A_1210E.png?e=.png)
清空用户名
内存遍历 Steam 搜寻 Token:
内存遍历 Steam 搜寻 Token 是以线程方式进行的,首先遍历搜寻 steam.exe 的进程号,如果不存在则以 steamchina.exe 进行代替:
![Image-8.png](/__local/B/2A/01/B9C1C784915EB55A827FF2F848E_2112E92F_91C8.png?e=.png)
遍历 Steam 进程
样本会根据前面获取到的 Steam 程序句柄,通过下图中的 search_from_steam_and_get_address(sub_4041A9)函数搜索 Steam 进程内存,获取 Token 标签出现的所有地址,存储在参数数组中并返回出现的次数:
(出于安全法律法规考虑,相关分析细节不予公开)
![Image-9.png](/__local/8/B7/CA/F5DB827AAA6DD1640A756942A6A_B1E06203_3A3A.png?e=.png)
定位 Token 标志
![Image-10.png](/__local/2/5D/83/B77BC1CFF3FF6187FE408D976D4_F2F9EE43_834C.png?e=.png)
Token定位
随后根据前面获取到的次数,循环遍历每个 Token 所在的地址,获取完整的字符串:
(出于安全法律法规考虑,相关分析细节不予公开)
![Image-11.png](/__local/6/BB/C9/3C2F89916A031555C396E63AC68_8F748B89_9B74.png?e=.png)
定位用户 Token
Steam 中 Token 解析:
Steam 中的 Token 以标识符 { "typ": "JWT", "alg": "EdDSA" } 开头,并以 "."(2E) 连接 Token 主体和其它内容,它们都以 base64 形式存在于 Steam 进程的内存中。
![Image-12.png](/__local/B/6F/78/7FAB4D32544D81CD00C3D2C59C2_8249D9FA_5D64.png?e=.png)
Token 举例
其中,对于 Token 字段的解析如下:
•"iss": 表示签发者(issuer),即颁发该令牌的实体。
•"sub": 表示主题(subject),即令牌所代表的用户或实体。
•"aud": 表示观众(audience),即令牌预期接收者。
•"exp": 表示过期时间(expiration time),即令牌过期时间戳。
•"nbf": 表示不生效时间(not before),即令牌生效时间戳,在此时间之前令牌无效。
•"iat": 表示发布时间(issued at),即令牌发布时间戳。
•"jti": 表示 JWT ID,即令牌唯一标识符。
•"oat": 表示令牌签发时间(original issued at),即令牌最初签发时间戳。
•"per": 表示权限(permissions),即令牌所具有的权限级别。
•"ip_subject": 表示主题的 IP 地址,即主体的 IP 地址。
•"ip_confirmer": 表示确认者的 IP 地址,即对令牌进行确认的实体IP 地址。
下图是本机测试 Steam 进程中提取的两种类型Token:
•一种是由 Steam 签发的用于用户与系统之间通信的 Token,"aud" 字段值 "client"、"web"、"renew"、"deriver" 表示可用于客户端应用程序、Web 应用程序、续订令牌、生成其它令牌等操作。
•另一种是用于机器之间通信的 Token,"aud" 字段值为 "machine",常用于不同服务之间通信。
![Image-13.png](/__local/0/92/D6/95264074672D176A215F54BC9A1_E31BE646_47D5.png?e=.png)
Token 比较
数据上传:
随后样本会解密出要接收数据的网址及一些分隔符,以 "<sub值>|xxxx|ey.txt|xxxx|<sub值>----Token 标识……" 的方式拼接以备上传:
![Image-14.png](/__local/4/DE/BB/1CFBD71ECFD129437AFD377D6AA_3225424B_2F09.png?e=.png)
拼接字符串
传输数据的行为是通过调用 com 组件的形式进行的,并根据参数来决定使用哪种传输协议,这里以 POST 协议传输给 121.62.21.160 地址(已失效):
![Image-15.png](/__local/2/45/33/D90E2429998014519A154B6842B_98F5D5CF_114E1.png?e=.png)
传输数据
除了在 sub_402843(遍历 Steam 内存的函数)内传输数据外,在外层中,也会根据是否获取到用户 Token 来决定是否传输同样的内容给另一个 C2 139.155.239.174(已失效),判断的依据是查看 sub_402842 返回的是否为 "----"(未找到用户 Token 的标志):
![Image-16.png](/__local/7/F6/A9/E0BAD1C0AEF767CBC001E5E1E63_DB4AFC2B_68DB.png?e=.png)
传输数据
二、附录
C&C:
![Image-17.png](/__local/2/95/9F/9A2D4B5C6C29BE1EE00EBB170E2_DEC9D1BA_599.png?e=.png)
HASH:
![Image-18.png](/__local/0/58/DA/4BC80E2F829585EE1B0CBFC9536_D83DC904_EFB.png?e=.png)