
MD5-Monomorphic Shellcode Packer - tutti i payload hanno lo stesso hash MD5
════════════════════════════════════╦═══
╔═╦═╗ ╔═╗ ╔═╗ ╔═╗ ╔═╦═╗ ╔═╗ ╔══╔═╗ ╠═╗
═╩ ╩ ╩═╚═╝═╩ ╩═╚═╝═╩ ╩ ╩═╚═╝═╩ ╠═╝═╩ ╩═
════════════════════════════════╩═══════
By Retr0id
═══ MD5-Monomorphic Shellcode Packer ═══
UTILIZZO: python3 monomorph.py input_file output_file [payload_file]
## Cosa fa?
Comprime fino a 4KB di shellcode compresso in un binario eseguibile, quasi istantaneamente. Il file di output avrà *sempre* lo stesso hash MD5: `3cebbe60d91ce760409bbe513593e401`
Attualmente, è supportato solo Linux x86-64. Sarebbe banale portare questa tecnica su altre piattaforme, anche se ogni versione produrrebbe un MD5 diverso. Sarebbe anche possibile utilizzare un file poliglotta multipiattaforma come [APE](https://justine.lol/ape.html).
Esempio di utilizzo:
$ python3 monomorph.py bin/monomorph.linux.x86-64.benign bin/monomorph.linux.x86-64.meterpreter sample_payloads/bin/linux.x64.meterpreter.bind_tcp.bin
## Perché?
Alcuni hanno [precedentemente](https://www.mscs.dal.ca/~selinger/md5collision/) utilizzato singole collisioni per far oscillare un binario tra modalità "buona" e "cattiva". Monomorph porta questo concetto al livello successivo.
Alcune persone insistono ancora nell'usare MD5 per fare riferimento a campioni di file, per vari motivi che non mi sono chiari. Se qualcuno di loro finisse per indagare su codice impacchettato con Monomorph, si confonderebbe molto.
## Come funziona?
Per ogni bit che vogliamo codificare, è stato pre-calcolato un blocco MD5 collidente usando [FastColl](https://github.com/cr-marcstevens/hashclash/tree/master/src/md5fastcoll). Come riassunto [qui](https://github.com/corkami/collisions/tree/master/hashquines#read-an-encoded-value), ogni collisione ci fornisce una coppia di blocchi che possiamo scambiare senza modificare l'hash MD5 complessivo. Il loader verifica quale blocco è stato scelto a runtime per decodificare il bit.
Per codificare 4KB di dati, dobbiamo generare 4\*1024\*8 collisioni (ci vogliono alcune ore), occupando 4MB di spazio nel file finale.
Per accelerare il processo, ho apportato alcune piccole modifiche a FastColl per renderlo ancora più veloce in pratica, consentendo di eseguirlo in parallelo. Sono sicuro che ci siano modi più intelligenti per parallelizzarlo, ma il mio approccio ingenuo è avviare N istanze simultaneamente e attendere il completamento della prima, quindi uccidere tutte le altre.
Poiché ho già eseguito il pre-calcolo, riconfigurare il payload può essere fatto quasi istantaneamente. Lo scambio dello stato dei blocchi pre-calcolati viene eseguito utilizzando [una tecnica](https://github.com/corkami/collisions/blob/master/hashquines/scripts/collisions.py) implementata da Ange Albertini.
## È rilevabile?
Sì. Non è molto furtivo, né cerca di esserlo. Puoi rilevare i blocchi di collisione usando [detectcoll](https://github.com/cr-marcstevens/hashclash/tree/collisiondetection/src/collisiondetection).