Dailydave mailing list archives
Re: Mutating to avoid structural analysis
From: Halvar Flake <halvar () gmx de>
Date: Wed, 19 Dec 2007 01:05:26 +0100
Hey Dave, all, I am kinda busy at the moment, so replies will be late / brief. 1. Obfuscation on the callgraph alone will break _some_ part of the diffing, without rendering it useless -- you still have a ton of structure on the flowgraphs. 2. Breaking structural comparison is possible, but requires more than inserting 4 lines of C code into your existing codebase (which is sufficient for breaking behavioral classification). 3. Even for a 'modest' obfuscation such as the one proposed, one needs to go through some binary rewriting or at least major preprocessing voodoo. 4. You should make your dispatcher NP-hard to analyze. And quick to dispatch. Constant table lookups are likely to be optimized away. So I guess what I am saying is: I think that in order to break structural classification, you have to do some 'real' work -- rewrite your binary, build an obfuscating compiler back-end or something along the lines. Which is more than for most other approahces. Cheers, Halvar
So flying home from JFK I was wondering this... Given that avoiding "behavioral signatures" is a matter of calling random NOP-like API calls (i.e. CreateFile + CloseHandle == 1 NOP), Halvar's program classification techniques involve a structural differencing engine. This has advantages (see his talk for details) in that program structure closely reflects the semantic meaning of a program, as interpreted by a compiler. So the obvious way, from what I can tell, to defeat a structural differencing algorithm would be to do a static or dynamic analysis of your target program, and for each CALL opcode, change the destination to a dispatcher function. This dispatcher function can then be built to do a O(1) table lookup to find the true destination of the call. So now all your functions call one function D. Your call graph is meaningless without reverse engineering the dispatcher function and reconstructing it, or doing dynamic analysis of the whole program (assuming you can get decent code coverage). For bonus points you could mutate your dispatcher function by putting it as a never-used basic block in lots of other functions. You'd probably also want to do some other easy obfuscation. So my question is this: is defeating a structural based fingerprint of a program more difficult to do than defeating behavioral based fingerprints. -dave
_______________________________________________ Dailydave mailing list Dailydave () lists immunitysec com http://lists.immunitysec.com/mailman/listinfo/dailydave _______________________________________________ Dailydave mailing list Dailydave () lists immunitysec com http://lists.immunitysec.com/mailman/listinfo/dailydave
Current thread:
- Mutating to avoid structural analysis Dave Aitel (Dec 08)
- Re: Mutating to avoid structural analysis Stefan Wagner (Dec 09)
- Re: Mutating to avoid structural analysis Halvar Flake (Dec 19)