════════════════════════════════════╦═══
╔═╦═╗ ╔═╗ ╔═╗ ╔═╗ ╔═╦═╗ ╔═╗ ╔══╔═╗ ╠═╗
═╩ ╩ ╩═╚═╝═╩ ╩═╚═╝═╩ ╩ ╩═╚═╝═╩ ╠═╝═╩ ╩═
════════════════════════════════╩═══════
By Retr0id
═══ MD5-Monomorphic Shellcode Packer ═══
USAGE: python3 monomorph.py input_file output_file [payload_file]
## 它的作用是什么?
它将最多4KB的压缩shellcode打包成一个可执行二进制文件,几乎瞬间完成。输出文件将*始终*具有相同的MD5哈希值:`3cebbe60d91ce760409bbe513593e401`
目前仅支持Linux x86-64。将该技术移植到其他平台是很容易的,尽管每个版本最终会有不同的MD5。也可以使用像[APE](https://justine.lol/ape.html)这样的跨平台多语言文件。
用法示例:
$ python3 monomorph.py bin/monomorph.linux.x86-64.benign bin/monomorph.linux.x86-64.meterpreter sample_payloads/bin/linux.x64.meterpreter.bind_tcp.bin
## 为什么?
人们[之前](https://www.mscs.dal.ca/~selinger/md5collision/)曾使用单次碰撞在“好”和“坏”模式之间切换二进制文件。Monomorph将这一概念提升到了新的层次。
有些人仍然坚持使用MD5来引用文件样本,出于各种我无法理解的原因。如果这些人中有人最终调查了使用Monomorph打包的代码,他们会感到非常困惑。
## 它是如何工作的?
对于我们要编码的每个比特,都使用[FastColl](https://github.com/cr-marcstevens/hashclash/tree/master/src/md5fastcoll)预计算了一个碰撞的MD5块。如[此处](https://github.com/corkami/collisions/tree/master/hashquines#read-an-encoded-value)所述,每次碰撞为我们提供了一对可以互换的块,而不会改变整体MD5哈希。加载器在运行时检查选择了哪个块,以解码该比特。
为了编码4KB的数据,我们需要生成4\*1024\*8个碰撞(这需要几个小时),最终文件中会占用4MB的空间。
为了加速,我对FastColl做了一些小的调整,使其在实际中运行得更快,并且可以并行运行。我相信有更聪明的并行化方法,但我朴素的方法是同时启动N个实例,等待第一个实例完成,然后杀死所有其他实例。
由于我已经完成了预计算,重新配置payload几乎可以瞬间完成。使用Ange Albertini实现的[一种技术](https://github.com/corkami/collisions/blob/master/hashquines/scripts/collisions.py)来切换预计算块的状态。
## 可以检测到吗?
是的。它完全不具备隐蔽性,也没打算那样做。你可以使用[detectcoll](https://github.com/cr-marcstevens/hashclash/tree/collisiondetection/src/collisiondetection)来检测碰撞块。