Antivirus WP
It seems to be hard to reverse-engineer the anti-virus signature???
author: hack_chen
意识流做题
初步试探#
题目给出了一个纯文本文件 print_flag.cbc
和一个 shell 脚本文件 run.sh
docker run -v /home/ctf/clamav/:/test/ --rm -it clamav/clamav clamscan --bytecode-unsigned -d/test/print_flag.cbc /test/sample.exe
查了一下,这是开源病毒防护引擎 ClamAV加载字节码签名(bytecode signature)并对 /test/sample.exe
进行病毒扫描,其中字节码签名使用 ClamAV Bytecode Compiler (github.com)从 c/cpp 编译成的纯文本文件,可以识别文件特征并报告出有/无病毒。
找了 clambc 的各种资料,在 github 的一个 pdf 里找到了 debug 的办法,在函数 cli_vm_execute_jit
下断点
这个函数在哪呢,git clone
,直接搜索,找到了 libclamav.so
which clamscan
ldd /usr/bin/clamscan
找到 libclamav.so.12
,扔进 ida ,尝试调试,但是 clamav/clamav
太精简了,运行不了 dbgsrv
看clamav文档,换成了 clamav/clamav-debian
,但是没断到 cli_vm_execute_jit
审计源码的时候,找到了 bytecode 相关代码,在 bytecode.h
和 clambc.h
,也发现了打印出 IR 的办法
clambc --printbcir print_flag.cbc
,这里被坑了

这里有三个选项,只能三选一,不然只会打印 info,当时我一直以 --info
为前缀,结果没打出来。
没找到现成的 IR 解析器,那就搓一个(受到 Haskell decompiler 作者 u/gereeter 的启发,他在CTF比赛中搓了个反编译器)
初见端倪#
还好 IR 输出的格式比较规范,部分不好识别的、需要人工打表的部分不多。
把 IR 转换成 IDA 中熟悉的汇编流程图,就会好看很多,用 PyMermaid 和 mermaid.live
oldkingOK/clamav-ir-visualizer: Transform clamav ir to control flow graph (github.com)
也没必要很熟悉这个引擎,毕竟每次出的题都不一样,分析 IR 是本题的重点
理顺逻辑#
文件头判断(试出来的)#
以 MZ 开头的文件才会加载所给的字节码
文件长度判断#
字节码开头使用了 seek
函数,是个 clamAPI
函数,可以在源码里看到定义,是用来看文件大小的
- 如果不等于 396,就传递给
ClamAV
:识别到了病毒:PRINT_FLAG.Fake
- 如果等于 396,把文件进行加密,与密文比较,如果比较成功,就:
PRINT_FLAG.Real
,否则就什么都不输出
开整#
先想办法dump出密文、密钥,因为是在vm里的,所以想办法hook API
在 func0,调用了 setvirusname ,第一个参数是字符串指针,所以可以直接断在这,然后看看周围,就能dump出密文。
也调用了 read ,把文件读入待加密的字符串指针,这里可以保存这个指针,等到加密完成之后再打印出来
func1 是加密函数,很复杂,作者提示,只是简单的异或密钥流,所以其实已经解出来了