公众号现在只对常读和星标的公众号才展示大图推送,
建议大家把听风安全设为星标,否则可能就看不到啦!
----------------------------------------------------------------------
静态分析:程序静态分析(Program Static Analysis)是指在不运行代码的方式下,通过词法分析、语法分析、控制流、数据流分析等技术对程序代码进行扫描,验证代码是否满足规范性、安全性、可靠性、可维护性等指标的一种代码分析技术。
动态分析:动态分析方法则需要运行计算机病毒。常用的分析工具有RegShot、Process Monitor、OllyDbg等。
1
样本选取
md5:b746f7a8313da0ee4bff88f56de64fe4062d485b1ee83c39ef5c86fbafe0b98d
ATT&CK技术使用情况:
2
查看静态特征
使用die判断基础文件信息:
通过标记出来的信息可以判断出文件的类型以及文件为.net文件。
.net文件逆向可以使用dnspy这个软件来查看源代码,但是在分析中发现这是壳,需要先进行脱壳以后才能进行进一步分析。
3
脱壳
通过对文件的基本分析发现该文件使用了壳保护。所以进行分析的话要先进行脱壳。
脱壳可以结合沙箱来进行脱壳,首先使用微步进行查看:
可以知道该样本使用了WriteProcessMemory函数
BOOL WriteProcessMemory(
[in] HANDLE hProcess,
[in] LPVOID lpBaseAddress, 目标地址
[in] LPCVOID lpBuffer, ;预备写入的地址
[in] SIZE_T nSize, ;写入数据大小
[out] SIZE_T *lpNumberOfBytesWritten);
作用:将数据写入指定进程中的内存区域。
通过查找确定了可疑函数,对该函数下硬件断点:
下完断点后点击运行到断点:
查看stdcall窗口,其中的由上到下对应的参数都是WriteProcessMemory的参数。主要关注的是2,3,4这三个参数,通过这三个参数可以判断出我们需要dump文件的起始地址以及文件大小。
以下是多次运行到改断点参数的值:
040AF0F8 400
02887668 13800
0289B410 4200
0289F61C 200
0289F828 2000
通过这些参数我们可以知道该文件的大小是1A000,通过savedata这个参数可以对文件进行dump.
savedata 1234,0x040AF0F8,0x1A000
savedata命令格式:文件名,起始地址,文件大小
将dump出的文件载入IDA中发现可以看到函数,说明成功了。
4
恢复函数名
该样本将函数名进行隐藏,只有当需要调用该函数时才会接收索引值以及API函数名称的的hash值作为参数进而将函数名恢复。
sub_40317B函数中存在一段这样的汇编代码,这是通过PEB获取kernel32.dll地址汇编代码的一部分,通过这块可以判断出
下面时parse_export_tbl的函数,两部份结合起来就是通过peb来获取函数名的过程。
这块就时hash解码的过程
通过上述分析我们知道了sub_4030A5函数的主要作用就是通过索引值以及函数名的hash值来查找函数的,我们想要获取相关函数名可以通过对这个命名函数的返回值下断点进而来跟踪,同时他会直接通过call eax来调用函数,而不是将函数名恢复后调用原函数,所以通过运行程序后dump程序无发恢复函数名。
这是一个恢复的函数,
通过上述的对比可以知道是直接通过调用函数来实现功能的,而不是将函数恢复或者存储到某个地方以后再运行的,属于调用哪个函数便恢复哪个函数,进而防止一次性恢复后全部dump出来。
通过上述分析我们确定了恢复函数名与调用的地方,但是我们知道该样本的函数名是用一次恢复一次需要多次动调,这样比较麻烦,对于这种恢复函数名我们有四种方案。
1.一个一个动调恢复(费人)
2.收集到所有的函数名hash值,然后自己分析解密函数,自己编写脚本恢复(大佬你们谁写了发我。。)。
3.在xdb64中编写脚本,直接输出函数名和调用地址。
https://blog.csdn.net/yan_star/article/details/113621948这个文章写了怎么编写python脚本,感兴趣可以去看看。
4.通过下条件断点,使得直接输出函数名和调用函数地址。
关键节点有两个1.4030c0中存储的是函数名称
从这个截图中可以看到三个信息,1.下条件断点的地址 2.条件断点的内容 3.函数名。通过这我们可以获得函数名。
2.在403260处下条件断点,根据堆栈中的返回值我们可以知道哪个函数调用了该函数名恢复函数,进而方便我们后续恢复函数名。
这是几个输出列子,其中Loadllibrary是重复出现的,可以直接全文替换。
5
命令行参数检查
在执行操作前先判断命令行中是否存在“-u”如果存在则延迟10s执行。
6
网络初始化和互斥体创建
7
窃取信息
在该函数中,首先构造两个数组,一个是全局变量充当标识符,还有一个包含实际窃取数据的列程。
查看第一个窃密函数,其中执行的操作是首先判断是否存在这个软件,然后根据不同的版本再进行对应的窃密操作。
包装函数会给每个窃密函数绑定一个全局变量标识符,这样在解析被盗数据时,C2 服务器将知道如何处理/存储它。
firefox browsericedragon browsersafari browserk-meleon browser seamonkey browserflock browser
blackhawk browser
lunascape browser
browsers general dataopera browser
qtweb internet browser
qupzilla browser
internet explorer
opera passwordscyberfox browser
pale moon browser
waterfox browser
pidgin passwordssuperputty
ftpshell
notepadplusplus
myftp
ftpbox
sherrod ftp
ftpnow
nexusfile ftp
netsarang xftp
easyftp
sftpnetdrive
ableftp
jasftp
automize
ableftpcyberduck
fullsync
ftpinfo
linasftp
filezilla
staff ftp
blazeftp
fastream ftp
goftp
estsoft alftp
deluxe ftp
ghisler wcx ftp
ftpgetter
ws ftp
site xml filesfull tilt poker
pokerstars
expandrive
steed
flash fxp
insoftware novaftp
netdrive
ghisler wcx ftp
smart ftp
far manager ftp
bitvise bvsshclient
vnc
msecure
syncovery
freshwebmaster freshftp
bitkinex
ultrafxp
ftp now
securefx
odin secure ftp expert
nch software fling
nch software classicftp
kittyputty
mozilla thunderbird
foxmail
pocomail
incredimail
gmail notifier prodesksoft checkmail
winftp client
winscp
32bitftp
ftp navigator
softwarenetz mailing
operamail
postbox
mozilla fossamail
mailbox ini file
winchips user account
outlook
ymail2
trojita imap client
trulymail
spn filesto dodesklist
stickies images and rtfnotefly notes
conceptworld notezilla
microsoft sticky notes
keepass databasesenpass db filesmy roboform
1password
mikrotik winbox
8
建立连接以及信息发送
该函数主要负责将获取的信息保存到缓存区,并且获取本机的一些信息然后一同打包发送。
先根据互斥体进行判断是否是同一个机器,接着获取操作系统版本信息。
获取一些与机器相关的信息:
复制数据到缓存区。
建立通信的函数。
9
抓包C2分析
前置环境搭建。
由于上线包建立connect需要返回值,所以修改kali的ip,将他当作一个c2服务器,进而进行连接请求时会返回一个值,可以获得上线包。
kali的设置:kali中直接修改ip地址,使得ip为目标c2的地址。
使用python3启动一个服务
在kali的设置中选择网络适配器,先添加一个LAN区段,然后将kali的LAN区段设置为该区段。
设置完成保存快照,以便后续恢复。
win7的设置:同理,将win7也设置为同一网段下的ip:
将win7的LAN段也设置为与kali相同的区段。
抓包获取上线包成功。
如果是域名的话修改windows的hosts文件
C:WindowsSystem32driversetchosts
c2上线包详细分析
报文头的生成:
1.开始的两个值是[1,2],[3-4]定值,是直接传入的参数作为值输入
2.这部分的值前两个字节[1,2]代表的是是否是宽字节,宽字节则为1不是则为0,后面[3,6]个字节是表示的是后面字符串的长度,接着的[7,13]个字节表示是一个定值字符串:
3.这部分表示的值与第二部分的意义基本相同,[1,2]两个字节代表的是是否是宽字节,宽字节则为1不是则为0,后面4个字节[3,6]是表示的是后面字符串的长度,由于是宽字节则长度为本身字节长度的二倍,[7,20]这部分的值是用户的用户名。
4.这块的结构同上,表示主机名称
5.这块结构也同上代表的是域名
6.这两个字节表示的是屏幕的分辨率
7.这三个字符依次表示的是账户的权限,进程的权限以及系统的架构
8.这几个值是操作系统的版本号
9.这个k值是一个定值,他的前面是操作系统的版本号,他的值是k.r.o.t.i.k..W.i.n.b.o.x.的首字母,实际上完整字符是Mikrotik\winbox,由于存放操作系统版本号,所以将前4个字节覆盖了,定值
10.这几个值[1,2]由于是传入的定值参数,所以值为定值,紧跟着的[3,8]个字节直接填入0,最后四个字节[9,12]是获取的传入的a3的值,但由于该值赋值为0,所以最后四个字节也为0.
11.这段数据的结构与上述2,3,4,5结构一样,表示的是机器的GUID
12,这段数据[1,4]表示的是后面随机字符串的长度,[5,9]表示的是生成的字符串。
10
从凭证管理器窃取数据
该函数是LoKibot获取目标程序数据以后,尝试从 Windows Credential Manager 中窃取数据。
为了窃取凭证,Lokibot 将搜索以下目录中的所有文件。
下面是elevate_prives函数恢复函数名中的函数,可以知道
该函数的主要功能是提权。
find_file模块,根据传入的参数,先由CSIDL值标识的文件夹的路径或者扩展环境变量,接着根据路径查找文件。
最后将窃取的数据打包成一个新的报告数据包发向C2
11
持久化
为了持久化,Lokibot 将自身复制到%APPDATA%文件夹内的一个文件夹,创建一个新的运行密钥,并隐藏创建的目录和复制的可执行文件。
创建目录并复制原始可执行文件。
创建运行密钥并隐藏文件夹和可执行文件。
参考链接
https://jiuaidu.com/jianzhan/981416/(通过PEB获取函数值)
https://bbs.kanxue.com/thread-266678.htm
http://reversing.fun/posts/2021/06/08/lokibot.html
https://www.cnblogs.com/iBinary/p/16359195.html(X64Dbg 介绍->表达式)
原文始发于微信公众号(听风安全):LokiBot家族静态分析过程分享
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论