这writeup是断断续续写下来的,最近事情比较多,所以也拖得比较久 (然后就没想到又拖了快4个月——2021.3.14)
在今年的flareon上,再次ak,这次排名是107,希望能拿到那根钥匙吧T_T (收到了 yeah!),去年的牌居然给我寄丢了,气死我了
再次是简单回顾总结整个比赛 (其实就是流水账writeup)
因为官方的wp已经很详细了,所以这篇会很流水账,主要记录一些跟官方不一样的东西,或者有学到的新的奇淫技巧
感觉今年的难度比去年的要高一些
官方WP:https://www.fireeye.com/blog/threat-research/2020/10/flare-on-7-challenge-solutions.html
1_-_fidler
第一题是个用python写的喂猫猫游戏
因为都是用python写的,源码一目了然,并且这题就算不会逆向,也可以直接玩通关,不用很久
想让知道详情的可以直接查看官方wp
https://www.fireeye.com/content/dam/fireeye-www/blog/pdfs/flareon7-challenge1-solution.pdf
我当时直接拼了个脚本
1 | def decode_flag(frob): |
有趣的是,因为我太菜了,这个脚本拼了一段时间,当我刚刚拼凑好脚本,游戏那边也刚好通关跑出flag来了= =
2–garbage.exe
这题卡了很多人,也卡了我有点时间
首先,PE文件是损坏的,但是我们不知道是哪里损坏
直接扔进ida,会发现经过upx加壳的,直接通过upx会提示invalid overlay size
这个报错的话,因为之前大概看过一下upx的源码,好像差不多意思就是其中一个加壳的chunk大小跟header中的size不一样了
找各种工具看了很久才发现,文件最后的xml没了一块
1 | <?xml version='1.0' encoding='UTF-8' standalone='yes'?> |
好吧,猜这个损坏是文件最后被截掉了一块,因为通过各种工具查看各种头都是好的,除了下面这些invalid
于是根据PE文件头中的文件大小在后面padding了一堆0,然后就可以用upx解压了
虽然解压出来有些地址有问题,但是并不影响看懂程序的逻辑,很快就弄出来了
这里就不贴代码了
但是,注意到一个东西,在message中包含了一句:
You should be able to get it working again, reverse engineer it, and acquire the flag.
似乎是可以把它恢复成可运行的binary,官方文档也介绍了其中的方法
在upx脱壳后,通过CFF explorer其实可以看到,在Import table中import的函数都是能看到的,但是缺失了import的dll名称
因此根据import的函数就可以推断出dll分别是kernel32.dll和shell32.dll
修复后,再把configuration File删掉(因为是少了一段的,这个configrue会导致程序错误)
就能够正常跑起来了 (CFF explorer真好用)
3-Wednesday
是一个类似flappy bird的憨憨小游戏,上下通过障碍物
txt里面介绍了怎么玩
好吧,那直接猜一下当达到XX分数的时候给flag
直接祭出cheat engine!
找到了分数,然后改大……诶,没什么反应
试了一轮,还是老老实实去逆吧。
发现这个是通过nim写的
https://github.com/Vladar4/nimgame2/blob/master/nimgame2/nimgame.nim
看了下感觉语法有点像脚本语言,但其实际还是编译出来的exe,因而没办法直接恢复出源码,只能照着上面示例代码慢慢看
时间有点太久了,不太记得具体逆的过程中遇到了什么问题,这里大致描述一下我的思路。
首先逆到逻辑发现总共分数达到296的时候就能够getflag,但是试过直接cheat engine修改成296没反应
或者最后出来winner的界面,但是没有flag
再细逆,发现flag是从障碍物的排序解码过来的,但是我没理清游戏操作原理,所以最后还是选择了patch
patch位置如图,对应了两个操作的patch,1、操作的cmp;2、reseteverything
patch完后,我就等他自动跑了,这个时候撞到柱子不会死,而且也不会因为撞柱而重置
最后getflag
官方wp提到了3种方法,
找到flag buffer,然后静态解;
patch program
- 写bot
当然也有头铁的老哥直接玩通关了……
找了下,bot的代码
https://github.com/TWVyY3VyaW8K/shitty-wednesday-solution
这是通过图像识别做的,这样就完全不用逆了,其中有个关键的库叫pyautogui,看着好像还挺好用
4-report.xls
这题给了个excel文件
一开始以为是普通的excel宏,结果发现还是too naive
按照正常的VBA分析,把宏代码去混淆,看完逻辑解密出来一个stomp.mp3
然后就什么都没发现了
而事实上,这个stomp.mp3可以算是一个hint
有个叫做 VBA stomping 的东西,参考
https://zanderchang.github.io/2019/04/30/VBA-Stomping%E7%AE%80%E4%BB%8B/
简单来说,在excel宏上,打开office实际执行的不是宏代码,而是文档文件中的p-code
p-code是宏代码的编译版本
如果文档中的p-code与当前系统上的VBA版本兼容,那实际执行的是储存的p-code,宏编辑器中显示的是反编译的p-code
而如果在不同版本的excel上打开,p-code不可重用,VBA源码将重新编译成p-code
使用 VBA Stomping 技术的恶意文档只能使用用于创建文档时相同的 VBA 版本执行。
因此,这个excel中实际的flag代码要从p-code中恢复,而光通过宏编辑器是看不到的
我使用了https://github.com/bontchev/pcodedmp 反编译p-code
然后就很容易得到flag了
5-TKApp
题目文件是个 TKApp.tpk
tpk…我首先反应怎么像apk这样,而且file了一下发现实际也是zip
查了下这个似乎是三星智能手表的应用
搭模拟器太麻烦了。。直接静态搞吧
解压出来能看到很多文件
其中最关键的是当中的一个TKApp.dll
这个dll是.net的,直接用dnspy分析
实际上整个过程没什么太大的难点,纯粹就是分析代码,然后从app的配置文件、xml等地方去找一些资源值,然后拼凑出来key
按AES处理一下就出来flag了,详细可以看官方wp
6-codeit
这题开始有点麻烦了
整个应用是输入文字,然后会显示出来文字对应的二维码
反编译后发现,他是通过AutoIt写的应用
AutoIt is a freeware BASIC-like scripting language designed for general scripting and automating the Windows GUI.
这还是个脚本语言,搜了一轮后,用工具把脚本提出来了
具体用的是什么工具,,时间有点久远忘了,我文件夹里面还留着这两个工具
https://github.com/SanseoLab/ejExtractor
https://github.com/nazywam/AutoIt-Ripper
官方wp中也提到了两种
https://github.com/fireeye/flare-vm/issues/172
https://gitlab.com/x0r19x91/autoit-extractor
这个不太重要,能顺利吧Autoit脚本提取出来就行了
因为这个Autoit脚本经过了很严重的混淆,我写了个脚本patch一下,输出的语法肯定不对的,但是能静态逆着舒服很多
1 | #... some global constant |
逆着发现,每次生成二维码的时候,都会在当前目录有文件创建,然后马上又被删除
因为对windows不熟悉,我用了种很笨的办法。。用frida hook WIN API
让他不删除掉那个文件
1 | var DeleteFileA = Module.findExportByName("kernel32.dll", 'DeleteFileA'); |
而实际上,通过官方的wp得知,其实直接设置当前文件夹权限就行了
然后发现被删掉的图片其实就是开头welcome的那张图,bmp格式,但是后面代码也会引用到了这张图
代码会经过一系列操作,通过GetComputerNameA
的结果计算密钥,进行解密生成带flag的二维码
这一步卡了很久,怎么能确定ComputerName?
万万没想到这一步是靠猜的
当中有一步是引用了上面提到的图片,然后对图片前面一部分字节进行处理
看了下,这似乎是LSB
因为那堆数据是 0xFF和0xFE混搭
于是,图片隐写提取出来aut01tfan1999
试了下把计算机名改成这个,然后再生成二维码,发现出来的就是flag了
L00ks_L1k3_Y0u_D1dnt_Run_Aut0_Tim3_0n_Th1s_0ne!@flare-on.com
7-re_crowd
题目给的是一个流量包
首先,通过http的请求可以还原出他访问的网站,这个网站是题目自己编写的网站,描述了一些背景
因为网站的漏洞,服务器上的 C:\accounts.txt 被偷了
那么就接着分析流量吧
从流量包种能看到大量的像这样的http请求
看着很奇怪,特别是PROPFIND这种请求方式,以及"(Not <locktoken:write1>)"
这种字段
那么上网上搜,就能发现有个IIS的漏洞利用方式跟这段数据包非常像
漏洞详情参考https://paper.seebug.org/259/
CVE-2017-7269
这个漏洞能达成RCE
由于存在很多个类似的流量包,我按顺序把这些流量包下了下来,放在一起比较,就能发现
这些流量包最后的ascii字符都是一样的,而前面一段,则是按顺序,每一次都比上一次少2字节
分析完那个漏洞,感觉这个过程应该是在爆破路径,前面的乱码就对应的padding,后面开始是shellcode
但是这段shellcode,直接丢进IDA看,感觉非常乱,看不出来
尝试把前面VVYAIAIAIAIAIAIAIAIAIAIAIAIAIAIA
搜一下,发现这是alpha shellcode
简单来说,就是用可见字符组成的shellcode
而前面则是自解码的shellcode片段
在网上能找到这些shellcode的编码器,但是找不到解码器,所以照这编码器,我写了个逆
1 | def shellcode_decoder(s): |
但其实实际上,官方的做法是通过shellcodeRunner去进行调试,然后再dump出来(我太菜了)
当时没有直接调试成功,应该是设置的问题,以后试试用shellcodeRunner这个工具
shellcode解密出来,可以发现这是个下载器,从流量中找到下一段shellcode,
由于当中还包含了通过对api hash,然后比对调用特定的win api
根据hash找到了这么一个网站,直接找就完事了
https://hiddencodes.wordpress.com/2014/08/22/windows-api-hash-list-1/
然后很快,就找到flag了
h4ve_you_tri3d_turning_1t_0ff_and_0n_ag4in@flare-on.com
关于最后的hash,这其实是恶意代码中常用的伎俩
官方wp中提到有很多工具可以拿来搜
- We can use the IDA Pro shellcode_hashes_search_plugin.py Python script available at https://github.com/fireeye/flare-ida
- We can use an emulation tool such as scdbg (https://github.com/dzzie/SCDBG)
- We can resolve the APIs dynamically in a debugger
8-Aardvark
这题非常无语
直接打开发现报错了,逆进去发现,这似乎是要跟WSL交互
从pe的资源节释放出来一个elf,这个elf将运行在WSL里面,然后作为井字棋的AI
玩家需要赢了才能getflag
首先,这个AI写的很好,在井字棋这种情况下能保证输不了,玩家最多跟它打平
看了看getflag的逻辑,是从系统中取了一堆信息内容运算后得出的
居然是跟系统相关的?那么还是动态跑起来
这里,我就直接尝试在WSL中安装了gdb,然后attach到AI进程
跑到check的分支,直接修改了寄存器的值。。
然后发现就输出flag了,这里多得看了眼twitter,有人说,如果你得到一个有点乱的flag,不要怀疑,尝试提交一下
没想到就真的就是这个flag
`c1ArF/P2CjiDXQIZ@flare-on.com`
这题出的确实一般,下面根据官方wp的内容补充一些相关的技术知识
WSL与Windows的交互
这里交互方式是通过Unix socket,
socket(AF_UNIX, SOCK_STREAM, 0);
,绑定的名称为496b9b4b.ed5
在Win7的时候,似乎是不支持AF_UNIX的,而在Window 10 17063版本后,Windows支持AF_UNIX了
https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/
这让window支持通过Unix Socket跨进程通信
WSL链接
CoCreateInstance
通过指定 COM Class ID and Interface ID,与WSL链接,根据windows版本的不同,其接口函数也不太一样
题目中适配了Windows 10 1803, 1809, 1903, 1909, 2004, or 20H2
flag生成中使用到的环境信息
因为flag是通过环境信息xor得来的,那怎么保证的flag唯一性?
首先,题目中有对WSL版本检查,elf跑的环境只能是WSL1
而当中用到的4种环境信息:
/proc/modules
WSL1中没有这个目录,跳过/proc/mounts
中根目录类型,WSL中是wslfs
或lxfs
,最后都是fs,用fs异或/proc/version_signature
信息,WSL前面固定是Microsoft- VDSO shared library 的program header的virtual address,四个固定的0xffffffffff70
/proc
下文件i-number,因为WSL下的i-number高16位肯定都是0
所以,题目就是通过这种办法跑出flag(Q:这是否可以用来当作识别WSL环境的特征呢?)
9-crackinstaller
对于像我这样不熟悉windows的来说,这题很复杂
题目总共给的就一个文件 crackstaller.exe
这个文件的行为像一个dropper
他里面内嵌(embedded)了3个二进制文件
首先crackstaller其实是整个crackme的安装器
在mian之前,会释放出C:\Windows\System32\cfs.dll
以及加载DriverBootstrap
,其具体表现还是一个PE文件,实际是一个.sys
在官方wp中他把这两个binary叫做 capcom.sys
和driver.sys
官方wp说到,binary里面用到了chacha20解密,然后再进行lznt1解压缩
在实际逆向过程,调试直接跳过了这步
其在释放出capcom.sys后,会通过DeviceIoControl
调用0xAA013044
的处理
实际上capcom.sys的作用是disable SMEP(Supervisor Mode Execution Prevention)
并且同时,会在capcom上加载driver.sys
整个过程,实际上是关闭了SMEP保护,然后加载driver.sys到用户层,通过文件头找到DriverBootstrap调用
其实相当于运行了一个shellcode
而运行shellcode之前,crackstaller通过一系列操作吧driver.sys加载到内存上,为了保证其能正常运行,并且把导入函数通过参数的方式传入DriverBootstrap
而中间还有个非常鸡贼的操作
把整个driver.sys搜索一遍,把0xDC16F3C3B57323 patch成 “BBACABA”
在逆driver.sys的时候能发现,这个其实是解密出password的密钥,所以也难怪我一开始直接逆怎么都解不出真实值
driver.sys通过CmRegisterCallbackEx((PEX_CALLBACK_FUNCTION)Function, &Altitude, a1, a1, &Cookie, 0i64);
注册了个回调函数
这个函数,搜了一大堆文档,最后发现是
which is called every time a thread performs an operation on the registry.
里面用ZwCreateKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes, 0, &Class, 0, Argument2->Disposition);
Class里面包含了解密出来的password H@n $h0t FiRst!
这一步ZwCreateKey其实我完全没理解是在干什么
官方wp说,他把password储存 in a registry class string (class type string?)
当使用RegCreateKeyEx
创建key时,lpClass可以被忽略,被设置成NULL
lpClass
A pointer to a buffer that receives the user-defined class of the key. This parameter can be NULL.
官方wp写到因为这个参数从来不会被使用,所以数据可以储存在里面,并且通过regedit、reg.exe等工具都不会返回class strings
正确的提取方式是下面的代码
1 | void PrintPassword() |
而剩下的部分,就是注册得到的COM server credHelper.dll
通过COM与该server交互,就能读到flag
当然,我当时并不懂COM,完全靠猜,把credHelper.dll翻了个底朝天找出来的= =
并且时通过静态解出来,这题如果能调到DriverBootstrap,能省很多事
而整个crackstaller的本质作用是安装了一个COM server,本身并不具备正常crackme拥有的输入
因此如果要正常交互还是需要用户写一个COM client去跟他交互,再从注册表读出flag
这题如果没搞懂的话强烈建议去看官方wp,包括里面描述到的COM细节
另外,在解密一些字符串的时候,我用到了flare团队中的一些ida插件,用来自动解密字符串
1 | from __future__ import print_function |
10-break
终于迎来了一道ELF的题目,原本以为这会比较常规一些,没想到,作者这操作也太魔鬼了
首先,粗略的看一下main函数,会发现只是一个非常简单的strcmp
借用官方wp的图,输入这个字符串会提示错误
那当然不可能这么简单啦
那么看一下.init,会发现两个函数
一个叫parent_sub
另一个叫first_fork
而在里面还会出现另一个second_chlid,通过fork创建了两个子进程,总共算起来是3个进程
在运行起来后通过ps就能看出来
1 | root 154 0.0 0.0 3644 540 pts/2 t+ 10:27 0:00 ./break |
首先,我们区分三个进程为parent、first_child、second_child
在这三个进程中
first_child —–(ptrace attach)——-> parent
second_child –(ptrace attach)——> first_child
接下来说一下每个ptrace都在做什么
first_child: 通过ptrace_me(PTRACE_SYSEMU, parent_pid, 0, 0)
捕获parent进程的syscall
并根据不同的syscall进行不同的运算
1 | v25 = 0x1337CAFE * (v15.orig_eax ^ 0xDEADBEEF); |
second_child: 通过PTRACE_PEEKDATA
、PTRACE_GETREGS
等捕获SIGSEGV
,并根据栈上的数据进行运算
并根据arg1的值选择不同的计算,返回值放到eax上,这有点类似一个VM fetch instruction然后解析执行的过程
1 | if ( data == SIGSEGV ) // 0xB7F |
因为second_child捕获的是first_child中的SIGSEGV,所以正常情况下second_child都是处于Sleep状态
而first_child捕获的是parent中的系统调用,在没有系统调用的情况下也是处于Sleep状态
这个从开始通过ps查看的进程信息就能看出
S interruptible sleep (waiting for an event to complete)
在first_child开始时,会通过ptrace_me(PTRACE_POKEDATA, parent_pid, (int)sub_8048CDB, 0xB0F)
把sub_8048CDB开头字节patch掉,而这个函数正是main函数进去调用的strcmp的函数
1 | _BOOL4 __cdecl sub_8048CDB(char *s1) |
当开头被patch掉后,main函数执行到这里的时候,会产生Illegal Instruction
错误,而这个错误正好被first_child捕获
1 | if ( (stat_loc[0] & 0xFF00) >> 8 == SIGILL )// Illegal Instruction |
而通过这个处理,把parent的执行流控制到函数rm_rf
上
这个函数非常鸡贼
1 | _BOOL4 __cdecl rm_rf(char *userinput) |
乍一看,他还会先执行rm -rf --no-preserve-root /
,算是个恶趣味了
但是实际上,execve这个系统调用会被first_child捕获,进行的实际是别的操作
如果哪个人把first_child这个进程kill掉了,那么,恭喜~获得 rm -rf /
大礼包
在看到下面的memcmp,其实就能想到我直接调试到这然后直接读内存不就好了
但是,这整个程序是通过ptrace驱动的
而linux上的调试器也是通过ptrace实现的,一个经典的反调试是,当一个进程已经被ptrace,就不能再被另一个进程ptrace
所以有反调试会通过ptrace自己来反调试,但是这种反调试很好过,只要把ptrace自己的代码patch掉就好了
但是这题不行,因为整个执行流都需要靠ptace去驱动,这没办法去掉。
开始我是在想通过虚拟机之类的方法捕获执行流的,但是发现qemu对其中一些系统调用并没有模拟好,包括ptrace的一些功能
导致整个题目没法正常跑通。后来也想过使用frida等工具进行插桩,但是实际上frida也是通过ptrace再插桩的
也想过用pintool等一些工具去尝试,当时忘了什么原因,也报了一些错误。
最后其实是通过libc hook来输出一些中间值的。
简单来说就是通过LD_PRELOAD=$(pwd)/libchook.so ./10_-_break/break
对libc进行hook
stage1
通过这个方式直接输出了第一部分的flag
w3lc0mE_t0_Th3_l
官方wp提到了另外一种方法,就是通过linux的mem接口
stage2
然后stage2,stage2是对代码段一大块区域进行解密的操作。然后这一大块的前32字节就是stage2的flag
这个函数里面会发现这样的调用
0804C40C: ((void (__cdecl *)(void *, int *))MEMORY[0])(&loc_804C3C4, &v5);
这个调用乍一看毫无道理,函数地址为0,但是这样的代码会引起segmentfault
SIGSEGV会被ptrace捕获,下面是first_child中捕获SIGSEGV的代码
1 | if ( (stat_loc[0] & 0xFF00) >> 8 == SIGSEGV ) |
实际上,这就是一个从当前地址到第一个参数0x804C3C4
的循环,循环次数为16
而这个函数的运算则是使用了许多奇怪的系统调用,而实际上这些系统调用都被替换成first_child中的操作
而当时我好像也没太识别出这个这是什么算法,就直接抄写并写了个逆,中间还因为一些抄写错误卡了一段时间= =
最后还是通过libc hook进行验证才写对的
Flag2: 4nD_0f_De4th_4nd_d3strUct1oN_4nd
也贴一下代码吧,官方wp提到,这个一个Custom ARX Feistel Cipher
1 | #!/usr/bin/python3 |
stage3
同样的代码,把后续代码段的代码也解密出来了
其实当时这个后续代码段我没看出来是怎么跳转过去的,然后没搞懂就直接顺着代码继续逆了
现在看官方wp
说的是下面代码的栈溢出,原本v30是0,会导致SIGSEGV被second_child捕获,从而调用到second_child中的cmp
但实际上,这个栈溢出会一直到很后边才会停止,这个取决于outbuf[i]是否为0,而数据中第一个出现0的地方前面存在一个疑似地址的值
而这个值刚好溢出到把v30给覆盖了,而覆盖成0x08053b70,恰好为解密后的代码的入口点Orz
这题目的操作真的太骚了
而当时这个函数,有些函数逆着发现,存在类似进位的操作,猜测这是一个大整数库,照着这个思路很快就把他算术逻辑逆出来了
甚至当中胡乱解密解出来了一张图片的提示,让我发现其中一个函数其实是除法23333
最后逆出来的算术如下
1 | const1 = 0xd1cc3447d5a9e1e6adae92faaea8770db1fab16b1568ea13c3715f2aeba9d84f |
获得最终的flag
`w3lc0mE_t0_Th3_l4nD_0f_De4th_4nd_d3strUct1oN_4nd_n0_puppi3s@flare-on.com `
11-rabbithole
这题也是够狠
flareon官方直接把一个现成的病毒进行去毒处理,然后做成一道题给我们
首先把我自己的做题过程记录下来吧,整个过程花了很长时间,重复造了一些轮子。
首先题目拿到手的是一个.dat的文件
file一下
NTUSER.DAT: MS Windows registry file, NT/2000 or above
数据库文件,对windows不是很熟悉,于是网上瞎找这文件的打开方式,后来发现其实是可以直接从regedit中打开的
这其实是user registry hive
,这个文件通常储存在%USERPROFILE%
中,在win10下就是C:/Users/<username>
里面
参考Registry Hives - Win32 apps | Microsoft Docs
这个似乎就是每个用户自己的注册表数据
然后我便开始瞎翻注册表,但是什么都没发现,里面的内容实在太多了
然后就转想,开始网上搜索关于registry hive取证的内容
很巧,最后被我找到了fireeye自己的一篇文章
SAIGON, the Mysterious Ursnif Fork | FireEye Inc
这个时候看twitter上的讨论,一堆大佬在劝:善用搜索引擎,能为你省很多时间。
看着很像呀,我还以为他们说的就是这个文章,于是我开始翻注册表,尝试找到类似开机启动的东西
但是也还是什么都没发现,最后引起我的注意是Software/Timerpro
这名字看着像个定时器软件呀(事实证明,too naive,并且这真是巧合了)
注册表这项里面,第一项就是一个powershell脚本
开逆!
这个脚本在做一些类似dll注入的操作,而dll则是从base64解码出来
开始逆dll,发现。。真的复杂,有许多操作都不知道在干什么,而且,他也不是一个标准的dll格式
整个文件格式很奇怪,但是按照正常的文件头偏移计算,又能索引到关键的地址
用了上面文章中附录的一个脚本,转换成了PE文件 Shellcode Converter Script
代码很长一段,就不贴上来了,查看源码到SAIGON, the Mysterious Ursnif Fork | FireEye Inc
整个dll也带一些混淆,像通过文件头的索引找到某个section,对section进行解密操作
这个解密操作能够解密出来使用到的一些字符串内容。而xor解密的密钥则是跟文件的timestamp相关
前面一系列解析文件头也包含了从文件头中找到这个timestamp
然后,上面提到的那片文章给了我很大的帮助,他在文件末尾有嵌入了一些文件
这个dll中,总共有两个embedded file
并且,当中有用到的解压算法 aplib,文章中也有提到,这让我省了很多算法识别的时间
两个embbedded file中,第一个是一个RSA public key,第二个是一堆字符串
并且,通过XorShiftRng
随机数算法,用sid作为种子的一部分,利用embbeded file中的字符串作为字符串表
生成特定的字符串,用这个作为注册表中的key值,所以其实之前看到的Timerpro是随机数生成的字段,然后被我误解成一个软件了。。。
当时还搜了好久这个软件,结果啥都没搜到
而这个sid,则是从注册表中查找S-1-5-21-3823548243-3100178540-2044283163-1006
而RSA public key,则是用作其中一部分数据的解密,作为密钥使用serpent算法进行解密
关于这个加密算法,我当时没有找到有现成的库,是找到了一个serpent的python代码
而一开始没看仔细,直接使用ECB模式解密,发现失败,后来突然想到,会不会是CBC模式,然后手动改成了CBC模式
初始化IV用0,解出
而在Timerpro底下,包含了Columncurrent
、Languagetheme
两个项,里面存着都是加密压缩过的PX文件,一个目录存32位,一个目录存64位,通过上面提到的方式解密出来
什么是PX文件?其实是有点像一开始dump出来的dll,都不是一个正规的PE文件,但是通过病毒的加载器,能成功跑起来
这个时候,我需要找到解析这些文件片段的方法
网上搜了一圈
https://research.checkpoint.com/2020/gozi-the-malware-with-a-thousand-faces/
https://github.com/0ver-fl0w/ISFB_Tools
https://github.com/hasherezade/funky_malware_formats
好家伙,才发现我网上搜了一堆的算法,拼凑起来的脚本,人家早就整理好了= =,毕竟这是个现成的病毒样本
浪费了贼多时间= =
做到这我才知道他们说的善用搜索引擎的意思……
在解出来后,主要关注几个
这些文件跟开始的dll很类似,都用着相同的字符串加密方式,以及相同的embedded file嵌入方式
1 | RowmapGuiprotocol: (run time library)(rtl.dll) |
其实这个病毒主要是怎么驱动起来的我也说不清楚,整个过程分析得我很混乱,并且由于我刚开始分析的是64位文件夹下的,没有关注32位文件夹下的,以为他们完全一样
但是32位文件夹下还包含了一个配置文件,这个配置文件写明了最后储存到注册表的flag的加密密钥
一直到最后卡住,找twitter的大佬询问才解决。
然后,通过serpent解出储存在注册表中的flag
`r4d1x_m4l0rum_357_cup1d1745@flare-on.com`
由于这个病毒是从真实病毒修改而来的,而很多大佬本身就是做病毒研究的工作,因此,这题对他们来说做起来应该非常快
而很多人都有提到,善用搜索引擎,因为确实是非常多人已经把里面算法、脚本打包好了
这里再说一下开始时应该怎么分析。
开始我是靠猜找到Timerpro这个关键的注册表项
而实际上,有更加靠谱的办法。。
微软有个工具叫autorun
Autoruns for Windows - Windows Sysinternals | Microsoft Docs
这个工具可以分析windows中所有自动启动项,包括注册表、定时任务等等
借用官方wp的图,通过这个工具,能发现
一个自动运行的脚本,而那串base64解码出来,正是Timerpro注册表项
iex (gp 'HKCU:\SOFTWARE\Timerpro').D
写在最后
最后这题,大佬们对这个病毒做了去毒操作,,真的太强了Orz
并且patch了所有密钥相关的数据,避免病毒与原server交互
整个过程其实我写得很流水账,因为感觉这题没有什么特别的技巧可言,更多是在逆向过程学到一个又一个的骚操作
病毒分析真是有意思
这片流水账wp也从2020年10月拖到2021年4月,emmmm半年了,因为之前忙毕设忙得焦头烂额
不知道21年还有没有空继续打flareon了:)
Respect!