
MD5-Monomorphic Shellcode Packer - todos os payloads têm o mesmo hash MD5
════════════════════════════════════╦═══
╔═╦═╗ ╔═╗ ╔═╗ ╔═╗ ╔═╦═╗ ╔═╗ ╔══╔═╗ ╠═╗
═╩ ╩ ╩═╚═╝═╩ ╩═╚═╝═╩ ╩ ╩═╚═╝═╩ ╠═╝═╩ ╩═
════════════════════════════════╩═══════
By Retr0id
═══ MD5-Monomorphic Shellcode Packer ═══
USO: python3 monomorph.py input_file output_file [payload_file]
Ele empacota até 4KB de shellcode comprimido em um binário executável, quase instantaneamente. O arquivo de saída terá sempre o mesmo hash MD5: 3cebbe60d91ce760409bbe513593e401
Atualmente, apenas Linux x86-64 é suportado. Seria trivial portar essa técnica para outras plataformas, embora cada versão resultasse em um MD5 diferente. Também seria possível usar um arquivo poliglota multiplataforma como APE.
Exemplo de uso:
$ python3 monomorph.py bin/monomorph.linux.x86-64.benign bin/monomorph.linux.x86-64.meterpreter sample_payloads/bin/linux.x64.meterpreter.bind_tcp.bin
Pessoas anteriormente usaram colisões únicas para alternar um binário entre modos "bom" e "ruim". Monomorph leva esse conceito ao próximo nível.
Algumas pessoas ainda insistem em usar MD5 para referenciar amostras de arquivos, por várias razões que não fazem sentido para mim. Se alguma dessas pessoas acabar investigando código empacotado com Monomorph, elas vão ficar muito confusas.
Para cada bit que queremos codificar, um bloco MD5 colidente foi pré-calculado usando FastColl. Conforme resumido aqui, cada colisão nos dá um par de blocos que podemos trocar sem alterar o hash MD5 geral. O carregador verifica qual bloco foi escolhido em tempo de execução, para decodificar o bit.
Para codificar 4KB de dados, precisamos gerar 4*1024*8 colisões (o que leva algumas horas), ocupando 4MB de espaço no arquivo final.
Para acelerar isso, fiz algumas pequenas alterações no FastColl para torná-lo ainda mais rápido na prática, permitindo que seja executado em paralelo. Tenho certeza de que existem maneiras mais inteligentes de paralelizá-lo, mas minha abordagem ingênua é iniciar N instâncias simultaneamente e esperar que a primeira termine, matando todas as outras.
Como já fiz a pré-computação, reconfigurar o payload pode ser feito quase instantaneamente. A troca do estado dos blocos pré-computados é feita usando uma técnica implementada por Ange Albertini.
Sim. Não é nada furtivo, nem tenta ser. Você pode detectar os blocos de colisão usando detectcoll.