Title: Binary protection Alignment with IT Governance, IP protection and effective risk mitigation
1Binary protection Alignment with IT Governance,
IP protection and effective risk mitigation
Sebastian Holst Bill Leach. PreEmptive
Solutions Sebastian_at_preemptive.com
Bleach_at_preemptive.com
2Agenda
- Binary protection scope and magnitude
- Obfuscation a compensating control
- Contrasting algorithms with process
- Who obfuscates?
- Why, when and when-not to obfuscate?
- Inventory of obfuscation techniques
- Best practices
- Declarative obfuscation
- Continuous integration
- Considerations and accommodations
- Debugging
- Operations and support
- Patch management
- Summary
- What, when, how why
- Questions to leave with
3Technical, operational and regulatory drivers
- Threats from outside and from within
- Obligation to take every reasonable step
necessary to meet business objectives, mitigate
risk, protect information assets, and comply - No single solution possible
- Integration people, processes, systems, and
technology - Complex, overlapping (sometime conflicting)
regulations - GLBA, Sarbanes Oxley, USA Patriot Act, FISMA,
HIPAA, SEC 17a3 and 4, and many others. - Overlapping control frameworks
- Cobit, ITL, ISOCOSO, COSO ERM, OCEG
4IT Governance an operational approach
- Assess and adapt control practices
- Develop broad operational approach to governance,
risk and compliance management - Access control, authentication, encryption,
data/log collectionetcObfuscation - Access Control
- Guidance All access should be provided on a
least privileged or need-to-know basis. - Question Who needs to know your source code?
5When source binary
- Operational, financial and privacy
- Change control
- IP loss, attack vulnerability, revenue loss
- Source access control
- .NET and Java environments changed the rules
- SOURCE BINARY
Binary Access outside the
enterprise
Binary Access Inside
the enterprise
Source Access
6When source binary
- Operational, financial and privacy
- Change control
- IP loss, attack vulnerability, revenue loss
- Source access control
- .NET and Java environments changed the rules
- SOURCE BINARY
SOURCE Access outside the
enterprise
SOURCE Access Inside
the enterprise
Source Access
7Risk Management when and if IT matters
- Step I Risk assessment (partial list)
- Enterprise-wide and beyond (supply chain,
partners, etc.) - Identify and classify all information system
assets (i.e. data, systems, applications, and
hardware). - Identify all threats to those assets (e.g.,
internal and external unauthorized access,
malicious or unintentional damage) - Identify all vulnerabilities or weaknesses that
could allow the threats to harm or jeopardize
corporate or customer information and assets. - Review the adequacy of all current policies,
procedures, and risk mitigation controls. - Analyze the probability of each identified
threat. - Identify additional risk-based controls
appropriate to the identified threats. - Continuously and proactively monitor and adjust
the risk assessment to respond to changes in
threats, controls, and your organizational
activities
8Risk Management when and if IT matters
- Step II mitigate risks (partial list)
- Develop policies that specify
- Responsibilities and the assignment of those
responsibilities. - Guidance for implementing, assessing and auditing
controls - Enforcement policies and sanctions for
non-compliance. - Select specific controls based on your risk and a
cost benefit analysis. - Implement defense in depth layered controls and
testing to establish multiple lines of protection
9Smoke detectors, seatbelts and obfuscation
- Obfuscation as a compensating control
6. Analyze the probability of each identified
threat. 7. Identify additional risk-based
controls appropriate to the identified threats
- Select specific controls based on your risk and a
cost benefit analysis.
10Obfuscation algorithm versus process
If you cant describe what you are doing as a
process, you dont know what you are doing.
W. Edwards Deming
11Who obfuscates?
28 of Software Security Summit attendee companies
12Why and When to Obfuscate
- Obfuscate when
- The application contains Intellectual Property or
Trade Secrets. - When application enforces usage, license or other
metering - The application contains hints about IT
infrastructure (e.g. SQL statements, DB
connections strings, etc.) - Any time source code should not be freely
available. - Obfuscation
- Keeps out most attackers (just like a door lock)
- Will not keep out determined attackers with time
and expertise.
13What is program obfuscation?
- A collection of tactics that transform a program
into a new program that - Functions the same as the original.
- Is materially more difficult for a human to
understand its inner workings. - Is materially more difficult for a decompiler to
output correct, understandable, high level source
code.
Not to be confused with a program obfuscation
solution
14How an Obfuscator Works
- Binary in, Binary out (no source code required)
- Uses static analysis and other techniques to
perform obfuscating transforms - Outputs mapping information.
- How to translate obfuscation transform back to
original
15How an Obfuscator Works
Input Programs
Output Programs
Obfuscator
External Dependencies
Map Data
External Configuration
16Example C Source Code
17Example C Source Code
18Example Decompiled
19Example Decompiled with Control Flow Obfuscation
20Obfuscating Transforms
- An Obfuscating Transform Can
- Be lossy or irreversible
- Change program size
- Impact program performance
- Examples of Obfuscating Transforms
- Identifier Renaming
- Metadata Removal
- Control Flow Obfuscation
- String Encryption
21Identifier Renaming
- Programmers use descriptive identifier names to
create self documenting code. - The goal is to replace meaningful names with
non-meaningful names. - Increases time and effort required to understand
decompiler output. - Irreversible. The original names cannot be
recovered from the output program alone. - Going back to original names can be done with a
map file.
22What Can be Renamed?
- Classes, Interfaces, Methods, Fields, Method
Parameters, Generic Type Parameters, etc. - All names used only internally can be renamed.
- If the program is a library
- All external names can be renamed if all clients
are obfuscated in sync. - External names must be preserved if clients are
not obfuscated. - Most commercial obfuscators support both library
scenarios with minimal configuration.
23Constraints on Renaming
- New names must follow the rules of the runtime in
order for the program to remain valid. - Implicit naming relationships must be preserved
- Virtual method overrides
- Interface contracts
- Renaming must be done consistently across
interdependent components - E.g. Method definitions and method call sites
24Approaches to Renaming
- 11 algorithms
- One unique new name for each unique original name
- Easy to implement in an obfuscator
- Easier to attack. Once a names intent is known,
use global search and replace on decompiled
output.
GetPayroll() becomes AX() GetPayroll(int
key) becomes AX(int AY) MakeDeposit(float
amt) becomes AZ(float AI) SendPayment(string
key) becomes AV(string AY)
25Approaches to Renaming
- 1 to Many algorithms
- One new name for many original names, subject to
platform scoping rules. - Generate new names optimally. Use as few unique
names as possible within any given scope - More difficult to implement in an obfuscator.
Requires deep analysis. - More difficult to attack. Global search and
replace is ineffective. - Size reduction (fewer names to store) is a nice
side effect.
26Approaches to Renaming
- Overload Induction
- A 1Many algorithm for method renaming.
- Rename as many methods as possible to the same
name, inducing method overloading. - Original method overload relationships are lost
and hidden in the noise.
GetPayroll() becomes a() GetPayroll(int
key) becomes a(int a) MakeDeposit(float
amt) becomes a(float a) SendPayment(string
key) becomes a(string a)
27When to Rename
- First line of defense against decompilation it
is best to rename as much as possible. - If the application is self contained (no
unobfuscated external clients), rename
everything. - If the application is obfuscated in sync with all
clients, rename everything. - If the application has unobfuscated clients,
rename only internal names. - Items referenced dynamically may not be
renameable. - E.g. A class that is dynamically loaded by name,
based on a user input string.
28Renaming Side Effects
- Smaller programs
- Performance neutral
- Adds complexity to debugging and troubleshooting.
- If not proactively addressed, renaming can create
problems when debugging, troubleshooting, and
updating.
29Metadata Removal
- Not all metadata is required to execute an
application - Properties, Events, Method Parameter names
- Some Custom Attributes / Annotations
- Often used at design / development time by IDEs
and other tools - This information provides hints to decompilers
and attackers. - An obfuscator can strip it out.
- Irreversible. The stripped metadata cannot be
recovered from the output program alone.
30Metadata Removal
- When to Remove Metadata
- If the program is not a library meant to be used
by other developers, it is usually safe to strip
metadata like properties, events, and method
parameter names. - Some metadata is used at runtime by framework
code (e.g. in .Net, data bound controls use
properties.). - An obfuscator should figure this out or allow the
user to specify that certain metadata not be
removed. - Side Effects
- Decreases size of the application
- Performance neutral
31Control Flow Obfuscation
- High level source is compiled into a sequence of
instructions that closely mirrors source. - The goal is to transform the original instruction
sequence into a logically equivalent sequence
that does not mirror the source. - One that will not decompile back to the original
source. - Increases time and effort required to understand
decompiler output. - Nice side effect sometimes breaks decompilers
expecting vanilla code. - Semi-reversible. The original logic must be
preserved, so the original instruction sequence
may be re-discovered.
32Approaches to Control Flow Obfuscation
- Decompilers look for clues to reproduce high
level statements. - Simple Rules
- Loops are backward jumps
- If statements are forward jumps
- Block Re-Ordering
- Move blocks of instructions and introduce extra
jumps - Destroys clues used by decompilers
- goto considered beneficial
-
33Block Re-Ordering Illustration
x
Original
Re-Ordered
for
goto
for
if xlt0
goto
yy-1
yy1
yy-1
goto
x
yy1
if xlt100
goto
if xlt0
if xlt100
34Approaches to Control Flow Obfuscation
- Splitting blocks of instructions and introducing
spurious control flow. - Classic Optimizations can be obfuscatory
- Loop Unrolling
- Caching local variables on the stack
35Optimization as Obfuscation (Example)
Source code int temp a a b b
temp Compiles to something like push a pop
temp push b pop a push temp pop b
Which can be optimized to push a push b pop
a pop b And commonly decompiles to a b b
a
36When to Use Control Flow Obfuscation (Caution)
- When you want to hide program logic from human
readers and decompilers. - Increase the time, effort, and expertise required
to understand program logic. - Can increase application size.
- Depends on the algorithm used.
- Can decrease performance.
- If performance is a concern, measure impact and
do not apply to performance sensitive methods.
37String Encryption
- String literals are compiled into the application
in the clear. - A common attack is to disassemble or decompile
the program, then search for a known sensitive
string. - Allows attacker to quickly locate sensitive code.
- The goal of string encryption is to slow this
attack down. - At runtime, the strings must be decrypted on
demand, so this transform is reversible.
38Approaches to String Encryption
- Encrypt selected strings at obfuscation time and
embed in application. - Add a decryption method call immediately after
every string load instruction. - Replace the encrypted string on the stack with
the clear string. - Typically use a fast but weak encryption.
- Since the decryption must occur at runtime, there
is little use for strong encryption.
39When to use String Encryption
- When you want to deter casual attacks. A
determined attacker can recover the strings. - Can increase application size.
- Apply selectively to size sensitive programs.
- Can impact performance.
- Adds the overhead of a method call in front of
every encrypted string load. - If performance is a concern, measure impact and
do not apply to performance sensitive methods.
40Other Obfuscating Transforms
- Preventative Transforms (breaking known
decompilers) - Inserting invalid metadata that the runtime can
ignore - Exploiting bugs in decompilers and disassemblers
- No guarantees here
- Runtime compatibility issues
- Bugs in decompilers get fixed
- Transforming Program Structure
- Riskier transforms, benefits unclear.
- Obfuscation tools usually dont implement
41Other Transforms (While the Hood is Up)
- Pruning
- Benefit of static analysis that obfuscators
perform - Determine and remove unused code
- This can offset size and performance increases
introduced by other transforms. - Linking and Packaging
- Merging code
- E.g. for .NET, merge multiple input assemblies
into one output assembly. - More size reduction
- Can simplify deployment
42Other Transforms
- Application Watermarking
- Embedding and hiding data inside an application
- Obfuscation hinders attacks, watermarking detects
attacks - Track applications
- E.g. discover who leaked a program onto a P2P
network by watermarking each copy with a serial
number - Obfuscators can hide a watermark inside any
number of internal data structures - A good watermark is
- Resilient. Difficult to remove without changing
or breaking the application. - Stealthy. It should not be immediately obvious
that an application contains a watermark.
43Obfuscation Best Practices
- Integrate obfuscation into the lifecycle as early
as possible - Development
- Debugging
- Automated builds
- Testing
- Support
- Updating
44Developing Obfuscated Applications
- Reflection and dynamic invocation considerations
- Declarative obfuscation
- Developers know the code best.
- Developers are not always the ones doing the
obfuscation. - Developers annotate their code to give hints to
the obfuscator. - E.g. do not rename this method
- An obfuscator can strip out attributes after
processing. - Obfuscator IDE integration for local builds
- Developers can use the obfuscator on their code
to gauge the impact.
45Debugging Obfuscated Applications
- Symbols are obfuscated because of renaming.
- Control flow obfuscation can change line number
information. - An obfuscator should be able to transform
debugging information along with the output
programs. - E.g. PDB files for .Net that contain line number
information. - Also provide a way to get an original name back
from an obfuscated name and context. - Use a mapping file produced by the obfuscator
- Ideally integrate into the IDE and debugger
itself
46Building Obfuscated Applications
- Automated Builds
- An obfuscator should easily integrate into
builds. - Command line interface
- Ant, Nant, MSBuild, etc.
- Code signing considerations
- Obfuscation must be performed on a binary before
it is signed because obfuscation changes the code - Verification
- Consider putting a check in the automated build
- Is the code obfuscated?
47Testing Obfuscated Applications
- Obfuscation changes code and therefore can
introduce bugs. - Configuration errors
- Errors in obfuscating transform algorithms
- Is the output application valid?
- Does the output application work the same as the
unobfuscated version? - Behavior
- Performance and size requirements
- Was a problem introduced by the obfuscator?
- Regression testing is key
- Test before and after obfuscation.
48Supporting Obfuscated Applications
- Information from the field might be obfuscated
- Log information
- Crash dumps
- Stack trace information
- Output map file is key to decoding
- Utilities to translate obfuscated symbols back to
original symbols
49Updating Obfuscated Applications
- Applications may consist of multiple obfuscated
components that are serviced independently - Applications may depend on shared obfuscated
components that are serviced independently - Obfuscated applications with a plug-in
architecture can be dynamically updated with new
features - Obfuscation (renaming) can complicate these
scenarios - Incompatible identifier names will break
referencing components
50Incremental Obfuscation
- How to safely update components of obfuscated
applications independently? - Two approaches
- Dont let the obfuscator change names of visible
symbols. - Simplifies updating at the cost of less effective
obfuscation - Always re-obfuscate updated components using the
same obfuscated names. - Incremental Obfuscation
- Import the original name mapping into the
obfuscator and let it use the same names. - Map file becomes an artifact that must be tracked
throughout the components lifecycle.
51Summary
- Obfuscation is a strategy and a process
- Like anything, it has strengths and weaknesses
that need to be assessed in relation to
requirements. - Once assessed, you can make your decisions about
obfuscation. - A good obfuscator should not only provide strong
obfuscating transforms, it should also provide
support for the process throughout the software
development lifecycle.