Sophail A Critical Analysis of Sophos Antivirus [Tavis Ormandy]


Sophail: A Critical Analysis of Sophos Antivirus
Tavis Ormandy
taviso@cmpxchg8b.com
developing an understanding of their product internals for
Abstract
the purposes of critical evaluation. Using only reverse
Antivirus vendors often assert they must be
engineering techniques and tools readily available to
protected from scrutiny and criticism, claiming that public
attackers, and with no access to proprietary knowledge, we
understanding of their work would assist bad actors (1).
present a detailed analysis of their product.
However, it is the opinion of the author that Kerckhoffs s
principle1 applies to all security systems, not just
We hope this information will be valuable to those
cryptosystems. Therefore, if close inspection of a security
considering deploying Sophos products.
product weakens it, then the product is flawed.
Version Information
The veil of obscurity removes all incentive to improve,
The results presented below were obtained using
which can result in heavy reliance on antiquated ideas and
Sophos Antivirus 9.5 for Windows, the latest version
principles. This paper describes the results of a thorough
available at the time of writing. Detailed version
examination of Sophos Antivirus internals. We present a
information is available in the Appendix.
technical analysis of claims made by the vendor, and
publish the tools and reference material required to
reproduce our results.
II. COMPONENTS
Furthermore, we examine the product from the perspective
of a vulnerability researcher, exploring the rich attack
surface exposed, and demonstrating weaknesses and
 A range of technologies, including dynamic code analysis,
vulnerabilities.
pattern matching, emulation and heuristics automatically
check for malicious code. (3)
Disclaimer
The views expressed in this paper are mine alone This paper examines some of the core components of the
and not those of my employer. Sophos Antivirus product. We focus on the core scan
engine used in all products, and licensed to third parties for
Keywords use in gateway products.
antivirus, reverse engineering, blacklisting,
enumerating badness, malware, pseudoscience.
III. SIGNATURE MATCHING
 Sophos' Dynamic Code Analysis technology utilizes
I. INTRODUCTION
sophisticated pattern matching techniques and identifies
viruses by rapidly analysing specific code sequences
known to be present within a virus. Virus patterns are
created to ensure that the engine catches not only the
Sophos describe their antivirus product using high-level
original virus but derivatives within the same virus
doublespeak with little technical substance. Furthermore,
family. (4)
their product specifications make repetitive claims about
 detecting threats , without explanation. The product
Static file signatures are the core mechanism Sophos uses
website simply describes how they combine pre-execution
to identify known malicious code.
analysis with runtime behaviour monitoring (2), but fail to
explain how that is achieved, what is analysed, or what
This section presents the result of reverse engineering the
behaviour they consider indicative of  threats .
core signature matching VM, and the Sophos signature file
format.
Sophos have made it difficult to evaluate or understand
their product claims by failing to document the techniques
Key Findings
they used to obtain them. We sought to remedy this by
·ð File signatures are distributed as bytecode for a
simple stack-based VM.
1  It must not be required to be secret, and it must be able to fall into the hands of the
enemy without inconvenience.
Table of Contents:
·ð Pre-image attacks against signatures are trivial,
Flag 00434f54
Length: 00000054
due to heavy dependence on CRC32.
Checksum: 0fcd8607 [GOOD]
·ð Collision resistance is poor, resulting in pool Part Info List:
Flag: 53494c50
pollution attacks, effectively binding their
Dwords: 00000001 (4 bytes)
00# 0005fd2f
efficacy to their secrecy.
$ ./sophtainer --print-section-list < data/vdl01.vdb
Section List:
·ð Signature quality is poor, often trivial or
Flag: 53494c53
Length: 00000001
irrelevant code sections are incorporated into
signatures. Dumping Section 0:
Start: 0000006c [Verified]
·ð The signature format is weak compared to
Compression: 4c5a4f43
Encryption: 00005243
published solutions that exhibit superior
Length: 00000000 [Signature Present]
Flags:
characteristics.
Zlib Compressed
Not Encrypted
·ð Signature definitions are authenticated using a
weak crypto scheme that is trivially defeated,
Section Signature Present:
Algorithm: 01004843 [SPMAA32]
making transport security essential. Sophos do
Sig Length: 00000004
Dumping 4 bytes: 1d 0a a5 e8
not use transport security (5)2.
Comp Flag: 000aa483
Figure 2. Listing the table of contents and section list from a sophtainer file.
·ð As in other Sophos components, use of
inappropriate or weak cryptographic primitives is
The header in Figure 2 describes a single zlib compressed
widespread.
section, with a SPMAA32 signature. SPMAA is the weak,
proprietary, 64bit feistel block cipher often used by Sophos,
Signature File Format
a thorough examination and working implementation is
All Sophos signature files, irrespective of
presented in Section V. Sophos often truncate the 64bit
content, are distributed in a container format called
SPMAA state to 32bits, as is the case with sophtainer
sophtainers. These sophtainers contain subsections called
section signatures, weakening it further.
 partitions 3, which can be extracted as appropriate.
Once extracted, Section data begins with a short header
Sophtainers
describing the contents, and a 64bit flag indicating the
Each partition within the sophtainer file begins
section type (along with compression and encryption
with a 32 bit flag describing the content type, the flags I
status). The section flags I have observed to date are listed
have observed are listed in Figure 1.
in Figure 3.
typedef enum {
SOPH_SOPHTAINERFLAG = 'HPOS',
typedef enum {
SOPH_TABLEOFCONTENTSFLAGS = 'COT',
SOPH_SECTION_NAME = 'lh',
SOPH_PARTINFOLISTFLAG = 'SILP',
SOPH_SECTION_IDE = 'edi',
SOPH_SECTIONINFOLISTFLAG = 'SILS',
SOPH_SECTION_TIMESTMP = 'pmtsemit',
SOPH_CRYPTXORFLAG = 'XRRC',
SOPH_SECTION_APPC = 'cppa',
SOPH_CRYPTNONEFLAG = '\0RC',
SOPH_SECTION_VDL1 = '10ldv',
SOPH_COMPRESSIONNONEFLAG = '\0OC',
SOPH_SECTION_VDL2 = '20ldv',
SOPH_COMPRESSIONZLIBFLAG = 'LZOC',
SOPH_SECTION_VDL3 = '30ldv',
SOPH_SECTIONFLAG = 'TCES',
SOPH_SECTION_VDL4 = '40ldv',
SOPH_CHECKSUMNONEFLAG = '\0\0HC',
SOPH_SECTION_SUS0 = '0sus',
SOPH_CHECKSUMSPMAA32FLAG = '\1\0HC',
SOPH_SECTION_XVDL = 'ldvx',
} sflag_t;
} stype_t;
Figure 1. List of partition flags observed in Sophos definition files.
Figure 3. List of section type flags.
The table of contents is mandatory, which describes the
Further technical examination of the sophtainer files, and
location of the  PLIS (Partition List), and the  SILS
tools to parse, extract and create these files accompany this
(Section Info List). Sections may optionally be encrypted
paper.
using the weak XOR cipher; however the 8bit key will be
Parsing IDE Section Data
included in the file itself, making it of questionable value.
The Sophos virus signatures are contained within
A sample table of contents from a Sophos VDB file is the  IDE sections of sophtainer files. Using the sophtainer
presented in Figure 2, which was generated using the utility accompanying this paper, we can extract the contents
sophtainer tool accompanying this paper. to examine them, as demonstrated in Figure 4.
$ ./sophtainer --print-header < data/vdl01.vdb $ ./sophtainer --dump-section 0 < data/vdl01.vdb
Sophtainer Header Dumping Section
Flag: 48504F53 Flag: 54434553
Version: 00000001 Type: 306c6476
[VDL Section, unpacking contents.]
Version: 05
Type: 000d
2 And in fact, it will be difficult for them to do so due to (at the time of writing) their use
[CHUNK 0, TYPE IDE_CHUNK_TYPE_CLASSDICT, 230 BYTES]
of the Akamai CDN, making https non-trivial to deploy. Let s hope they understand SNI.
0003: 4d e4 4c 01 01 42 01 16 4e M.L..B..N
3 Actually the code only refers to them as  PART , which I ve assumed is a truncation of
[ & ]
partition.
0014: 96 27 13 e1 98 0e crc32 27 13 e1 98 0e
Figure 4. Extracting an IDE section, and parsing the first IDE chunk.
001a: ed hlt
The IDE sections are organised into variable width chunks.
This program, a definition called  Attention 629 is a
The first byte of each chunk describes the class and type,
slightly more complex example, containing more literal
followed by a variable width big-endian length. Certain
bytes and some file pointer manipulation.
chunk types are container chunks, and contain a sequence
of sub-chunks immediately after the chunk header. These
The patterns Sophos distribute vary in complexity, the
details are described in the documentation accompanying
simplest examples are of the following form.
this paper, for now we will concentrate on understanding
0000: fc 50 literalib 50
the signature definition chunks.
0002: f4 02 ba bb literalibv 02 ba bb
Deciphering a signature chunk.
0006: fb 20 01 literaliw 20 01
A sample decoded signature chunk for a pattern
0009: fb 90 90 literaliw 90 90
Sophos calls  Turbo 448 can be observed in Figure 14.
000c: ed hlt
The primary components of the signature definition are the
The previous example simply matches six literal
Virus Name, followed by one or more bytecode programs
consecutive bytes (the literalibv opcode matches any
that describe how to identify the file.
one of the specified bytes).
Sophos execute the bytecode program for each input,
Signature Design
deciding if the contents matches or not determines whether
The core theme of the virus definitions
Sophos considers the file malicious.
distributed by Sophos is to find a section of code that
Bytecode programs.
Sophos feels is unique, and then CRC32 it. The rationale
I have written a sample disassembler for the
for relying on such weak protection against signature
bytecode format used by Sophos. The VM is a simple stack
collisions is unclear, but due to the heavy misuse of
based interpreter, with single byte opcodes followed by a
cryptography throughout Sophos products, it is likely due
variable number of operand bytes. The VM has an RPN-
to a misunderstanding of CRC32 characteristics.
like stack for computation, and register that holds the
current file pointer, and six named locations (registers).
Collision resistance
It is self-evident that one of the core goals of an
A table containing some sample opcodes is presented in
anti-virus signature should be to minimise false positives.
Figure 5.
There is a very large body of work published on this topic
that Sophos have ignored, resulting in a very weak
Opcode Description
VDL_OP_CRC32 96 Match crc32 n bytes (ones signature scheme.
complement)
VDL_OP_NEXT FA Increment the file pointer.
VDL_OP_READSW E1 Read word onto stack. In fact, it is not simply easy to find false positives; it is easy
VDL_OP_LOADIWSW DE Load immediate word onto stack.
to generate pre-images for Sophos signatures, making them
VDL_OP_SEEKSW E8 Pop word, seek to absolute offset.
VDL_OP_SEEKIB EB Move file pointer forward n bytes.
vulnerable to a class of attacks known as  pool pollution .
VDL_OP_FADJUSTSW CB Adjust next value on stack.
These attacks are described in more detail in Section X.
VDL_OP_SUBSW D6 Pop two words, subtract, push
result.
VDL_OP_SEEKIW F8 Seek to immediate offset.
Generating pre-images
Figure 5. Sample opcodes for Sophos bytecode VM.
It is well understood that CRC32 is not resistant
The majority of signatures that Sophos distribute begin
to pre-image attacks (6); in fact we can automatically
with a literaliw opcode, which locates a hardcoded 16 bit
generate samples to match most Sophos signatures. A
value, which is then followed by a CRC32 on the
demonstration is presented in Figure 15.
proceeding data. There are more complex signatures, and
some less complex, some sample programs are presented
Signature Quality
below. Sophos claim that their researchers try to match
generic code, so that variations may also match the same
0000: fb eb 7b literaliw eb 70
signature. We tested this claim by disassembling sample
0003: fc 90 literalib 90
signatures for malware samples, and finding what code was
0005: eb 03 seekib 03
used in the signatures.
0007: 96 06 2c b0 28 73 crc32 06 2c b0 28 73
000d: fa next
We see little evidence that Sophos researchers are aware of
000e: fa next
the context of the code they are looking at, often irrelevant,
000f: fb 75 02 literaliw 75 02
trivial, or even dead code is used.
0012: eb 09 seekib 09
TODO: Add some examples patterns and show code from
Design
original samples.
The buffer overflow protection component is
implemented entirely in userspace, and loaded into the
Summary
address space of applications using Appinit_Dlls4.
·ð Sophos signatures are distributed in bytecode
format for a proprietary VM.
Sophos use the Microsoft Detours (6) runtime
·ð The signatures heavily rely on CRC32. instrumentation framework to intercept execution of
various Windows APIs, where they insert runtime integrity
·ð Signatures tend to be of poor quality, often
checks.
matching irrelevant or dead code sequences.
·ð The signatures used by Sophos can be considered
Sophos had intended for these integrity checks to
weak at best.
implement two different mitigation strategies:
Tools to understand, create, and disassemble the bytecode
·ð Prevent exploitation of stack buffer overflows
used by Sophos are presented in the Appendix.
using SEH overwrites.
·ð Detect the use of the return-to-libc exploitation
Signature Attacks
technique.
These strategies are evaluated below.
TODO
SEH Overwrite Protection
·ð Pool pollution attacks.
SEH overwrites were traditionally the simplest
·ð Pre-image disruption attack.
method of exploiting stack buffer overflows on Windows.
·ð Defeating the authentication.
However, adoption of toolchain and runtime mitigations
developed by Microsoft (SafeSEH, SEHOP) has effectively
neutered what had previously been a very trivial
IV. BUFFER OVERFLOW PROTECTION
exploitation technique.
Nevertheless, SafeSEH is only available at build time5, and
 This detection system will catch attacks targeting
SEHOP is only available on versions of Windows released
security vulnerabilities in both operating system software
since Vista Service Pack One. Therefore, those applications
and applications. . (4)
not built with SafeSEH on Windows XP and Windows
Sophos position their buffer overflow protection as one of
Server 2003 remain exploitable by even low-skilled
the four major components of their product (4), but
attackers.
describe nothing about what it does.
This topic has been explored in detail by Matt Miller,
This section presents an analysis of this Sophos component.
generally recognised as one of the most important
researchers in Windows security, in his paper (7). Matt
Key Findings
describes how a runtime SEH overwrite protection might
·ð Despite misleading claims to the contrary (5), this
be implemented.
component will only operate on versions of
Windows prior to Vista.
Exception Handler Chain Verification
·ð Two weak forms of runtime exploit mitigation
In brief, the core insight introduced in (7) was
are implemented.
that by inserting a canary at the tail of the exception
·ð Sophos use inappropriate and weak cryptographic
handler chain6, the integrity of the list can then be verified
primitives to obscure sensitive implementation at exception dispatch by walking through each link and
details from attackers. checking the list terminus. An attacker cannot easily
·ð Superior solutions written by real experts in maintain this property; therefore the system can verify the
exploit mitigation are available at no cost. chain has not been tampered with before trusting it.
4 The Appinit_Dlls list is processed during initialisation of USER32; therefore
applications that do not load USER32 are unaffected.
5 Furthermore, SafeSEH is generally considered weak, due to well-known attacks if a
single loaded module does not enable it. This may change as adoption increases.
6 The chain is effectively a linked list of function pointers.
A good quality implementation of this mitigation A Simple demonstration bypassing this weak protection is
(including source code) is available from (8). The also provided.
pseudocode implementation from (7), intended to be called
Summary
during exception dispatch, is quoted in Figure 6.
·ð The SEH overwrite protection in Sophos is very
CurrentRecord = fs:[0];
weak.
ChainCorrupt = TRUE;
·ð The implementation only verifies that the first
while (CurrentRecord != 0xffffffff) {
if (IsInvalidAddress(CurrentRecord->Next))
two exception records do not point within the
break;
current thread stack.
if (CurrentRecord->Next == ValidationFrame) {
ChainCorrupt = FALSE; ·ð Even low-skilled attackers can trivially bypass
break;
this mitigation with minimal effort.
}
·ð Sophos misunderstood published information on
CurrentRecord = CurrentRecord->Next;
}
this topic, resulting in a broken implementation
if (ChainCorrupt == TRUE)
of what is essentially a solved problem.
ReportExploitationAttempt();
else ·ð The obvious attack against Sophos SEH
CallOriginalKiUserExceptionDispatcher();
protection is return-to-libc, however this is
Figure 6. The pseudocode for Matt Miller s runtime exception handler chain
discussed in the next section.
integrity verification, which effectively binds the difficulty of SEH overwrite
exploitation to the implementation of ASLR on the host.
Ret2libc Detection
Sophos Implementation
Ret2libc (return-to-libc) is an exploitation
While clearly inspired by (7), the implementation
technique originally developed by Solar Designer to
in Sophos demonstrates a fundamental misunderstanding of
demonstrate weaknesses in early stack buffer overflow
the attacks that Matt was working to prevent. At best it can
mitigation techniques. While fundamentally the same
be considered a weak obfuscation that prevents the most
principle, the attack has been generalised over time and is
trivial existing exploits from functioning.
now sometimes referred to as ROP, Return Oriented
Programming.7
Simple adjustments to an existing exploit can be made to
bypass the checks that Sophos perform.
In brief, during classical stack buffer overflow scenarios, an
attacker modifies the return address to point back into the
Pseudocode for the implementation found in Sophos is
buffer they control. Early exploit mitigations focussed on
presented in Figure 7, based on reverse engineering the
these attacks, meaning the stack might be randomised or
hooks found in sophos_detoured.dll.
non-executable, resulting in the attacker being unable to
CurrentRecord = Tib->ExceptionList;
return into the same buffer he is using to modify the stack
frame. Solar Designer defeated this by setting up the
for (i = 0; i < 2; i++) {
if (IsBadReadPtr(CurrentRecord, Size)) {
parameters for a call into a library routine, and then
break;
}
returning into a static location  the c library.
if (CurrentRecord->Handler >= Tib->StackLimit
&& CurrentRecord->Handler <= Tib->StackBase) {
SuspendCurrentThread();
Ret2libc is still an important exploitation technique, and is
}
if (CurrentRecord->Next == -1) {
often part of the attacker s solution to the NX/DEP puzzle.
break;
}
A strong ASLR implementation is generally considered the
CurrentRecord = CurrentRecord->Next;
}
best protection against ret2libc; if attackers cannot predict
CallOriginalExceptionDispatch(); where the code sequences they want are located, they
Figure 7. Reverse engineered pseudocode for Sophos SEH Overwrite
cannot return into them8. However, it is a reasonable
protection.
observation that ASLR is not strong on all Windows
This code simply verifies that the handler for the first two
platforms or with all applications, and Sophos have
exception records do not point within the current thread
attempted to implement a solution to this in their Buffer
stack. The intention was clearly to prevent pointing the
Overflow Protection product. We reverse engineer and
exception handler back into the buffer that the attacker
evaluate their ideas in this section.
controls, however this is such a ludicrously weak
mechanism that bypassing it is trivial.
Code suitable for reproducing these findings on machines
7 The author prefers the original ret2libc term, and will use it throughout this paper.
using Sophos products accompanies this paper.
8 There are well understood generic attacks against ASLR that are not explained here for
brevity. Briefly, you must leak an address, find something static, or increase your chances
of getting lucky.
Protected Functions believe that there are hidden  landmines distributed
The Sophos solution appears to be called throughout the Windows API, forcing them to work harder.
 Protected Functions 9. In summary, Sophos create a list of
Of course, the hardcoded 64bit symmetric key (which
Windows APIs that they believe are most likely to be used
happens to be 0xd6917912f2e43923) is easily recoverable
in a ret2libc exploit, and then intercept them using
using standard reverse engineering techniques, making
Microsoft Detours. When their detour callback is executed,
their obfuscation moot.
they verify the callsite was from within an expected module
before calling the original routine.
However, for extra security, the decrypted contents are then
optionally decrypted with the XOR cipher, using the
This solution is fundamentally broken. It is difficult to
hardcoded, 8bit key, 0x93. This guarantees that any
believe that anyone with even a rudimentary understanding
attacker will simply give up writing their ret2libc payload,
of control flow or the organization of computer programs
as they will be unable to concentrate due to uncontrollable
could have believed it offered any challenge to attackers
laughter.
whatsoever.
Using the spmaautil utility from Figure 16, the
Indeed, it will be a considerably more challenging task to
command demonstrated in Figure 8 will extract the
enumerate all the flaws with this silly idea. Nevertheless, I
decrypted BOPS (Buffer Overflow Protection)
will persevere, and attempt to point out some of the major
Configuration, allowing you to examine the list of
problems below.
 Protected APIs.
Ret2libc generality
$ ./spmaautil --output=results \
Sophos fail to understand that although Solar
--setkey=$((0xd6917912f2e43923)) \
--filename=Config.bops \
Designer demonstrated returning directly to exported
- decrypt
library functions, he did so because it was convenient, not
Figure 8. Decrypting the Sophos BOPS configuration file.
because of any technical limitation. Modern ret2libc attacks
Popular programs are whitelisted.
have made finding collections of useful code sequences
The BOPS configuration file used by Sophos also
(often referred to as gadgets) a science, and various
includes a list of whitelisted programs that these protections
frameworks exist for producing useful payloads out of
are applied to. Examples include quicktimeplayer.exe,
whatever code you have available.
powerpnt.exe, acrord32.exe, outlook.exe, and so on.
Assuming Sophos redesigned their ret2libc protection to
Therefore, an attacker can simply piece together the
actually work; it cannot be used to protect any other
functionality they want from other places, or even simply
software.
indirectly call the routines.
Summary
Attempting to enumerate known bad
Sophos try to enumerate the exports that they ·ð The ret2libc mitigation in Sophos is very weak,
think attackers might want to return into in their exploit and primarily relies on secrets.
payload. Of course, there are typically thousands of these
·ð Sophos protect their secrets using a weak, poorly
exports mapped into the address space of a typical
designed crypto scheme.
Windows application (even ignoring the ret2libc section
·ð Sophos misunderstood the generality of the
above), some of which Sophos cannot possibly know in
ret2libc exploitation technique.
advance.
·ð Very few applications are supported.
The result is that you can simply avoid the routines that
Sample programs and reference material enabling you to
they hook, obtaining the same functionality elsewhere,
reproduce these results accompany this paper.
thereby defeating their protection.
Further information about SPMAA and its use in Sophos
Improper use of cryptographic primitives
products is available in Section V. SPMAA.
Interestingly, Sophos appear to have realised that
an attacker can simply avoid the routines that they
Recommendations
intercept. Their solution to this problem was to obfuscate
The BOPS component of Sophos Antivirus is
the list of APIs with a weak proprietary feistel cipher called
essentially useless. At best you could argue it might require
SPMAA. The intention was presumably to make attackers
an attacker to make trivial modifications to his existing
exploit.
9 This is based on debugging messages observed in the product.
provides zero-day protection to all customers using
Studying BOPS has been revealing, demonstrating a
Sophos [& ] products (12)
fundamental failure by Sophos to understand the most basic
security concepts.
What Sophos refers to as Genotypes are simply
combinations of arbitrary software characteristics. These
Genuine runtime exploit mitigations exist for older
characteristics can be assigned during analysis, or by
Windows systems. The author recommends you evaluate
combinations of signatures called filters (or during pre-
WehnTrust and EMET.
execution analysis).
Key Findings
V. SPMAA
·ð Genes are simply software characteristics that are
applied as tags during analysis or at runtime.
·ð Characteristics can be things like specific API
The hallmark of Sophos products is inappropriate or weak
imports, instructions used, or embedded strings.
use of cryptography, and the algorithm Sophos prefers is a
·ð Combining these characteristics together can be
weak feistel block cipher called SPMAA. SPMAA appears
used to make more signature definitions.
to be a proprietary invention of Sophos, which they use for
authentication and obfuscation of product data.
Design
An American company called  Strategic Patents
Key Findings
(presumably) representing Sophos applied for a patent on
·ð SPMAA is used throughout Sophos products.
this concept in the USA, providing some insight into the
·ð The cipher has not been published or peer
design.
reviewed.
·ð Inherently weak characteristics, possibly a very
 Each gene may describe a different behaviour or
dated design.
characteristic of potentially malicious applications or
·ð Probably designed by a real cryptographer, but
other file. For example, potentially malicious applications
has been misused (and used for too long) by may copy itself to a %SYSTEM% directory. Therefore a
gene may be created to identify this functionality by
Sophos.
matching the sequence of API calls and the strings that
are referenced" (13)
Design
SPMAA is a symmetric cipher, meaning that
Examples
Sophos simply hide the key within the product, and hope
Genes can be understood more easily by referring
attackers do not know how to use a disassembler.
to them as tags. Sophos simply tag executables with new
labels as they analyse or monitor it. When a combination of
In this section we present a working implementation of the
tags have been collected that match a pattern (or genotype),
SPMAA algorithm, and a command line tool to use it,
Sophos detect it as malicious.
along with the encryption keys recovered from Sophos
products.
Sophos list some examples in their patent application,
which I ve reproduced in Figure 9.
A full implementation in C is provided in the Appendix.
Summary
Sophos relies on a weak encryption scheme for
secrecy and authentication throughout the products. While
the cipher itself is not obviously broken, despite the lack of
peer review, it is inherently dated and weak by design.
Sophos misuse cryptographic primitives throughout their
product.
Figure 9 Sophos example Genes
The pre-execution emulation can also apply tags, such as
V. GENES AND GENOTYPES
unusual instructions, operations, or addresses observed.
 Sophos Behavioral Genotype is a powerful technology
VI. PRE-EXECUTION ANALYSIS
that is able to detect malicious behaviour even before
specific signature-based detection has been issued. This
case INSTRUCTION_CLASS_INT:
 Advanced emulation technology along with an online
if (!Emulator->EmulatorFlags & EMULATOR_32BIT)) {
MSDOSInterruptHandler(State, OperandByte);
decompressor for scanning multi-layer attachments is
break;
}
utilized to detect polymorphic viruses. The robust engine
AddGeneType(Emulator, 0, GENE_TYPE_INTOP, OperandByte);
supports multiple scanning modes to optimize AddGeneType(Emulator, 0, GENE_TYPE_INTVA,
Emulator->RegsEIP 
performance. DecodedInstruction->SourceBytes);
// Test for Windows System Call
if (OperandByte == 0x2E) {
SysNum = Emulator->RegsEAX; // Syscall Number
Sophos promote their pre-execution analysis as a generic
Params = Emulator->RegsEDX; // Parameter Stack
// This doesn't make any sense, these numbers
solution to obfuscated or packed malicious code. In reality,
// change for every SP.
//
the supported operations are very specific and of limited // 0xBD could be
// NtOpenPrivateNamespace (Windows Vista)
value. // NtRaiseException (Windows 2003)
// NtReleaseSemaphore (Windows XP)
// NtSetDefaultUILanguage (Windows 2000)
// NtTestAlert (Windows NT)
Key Findings
//
// 0xBE could be
·ð Sophos include a very simplistic x86 emulation
// NtOpenObjectAuditAlarm (Windows Vista)
// NtRaiseHardError (Windows 2003)
engine that records memory references and // NtRemoveIOCompletion (Windows XP)
// NtSetEAFile (Windows 2000)
execution characteristics. // NtSetUnloadDriver (Windows NT)
if (SysNum != 0xBD && SysNum != 0xBE)
goto next;
·ð The emulation is a poor representation of x86,
EmulateExceptionDispatch(0xC0000014, Value);
and only executed for around 500 cycles. Figure 10 Pseudocode for software interrupts.
·ð Detecting the Sophos emulator is trivial, but
This code demonstrates a fundamental misunderstanding of
spinning for 500 cycles on entry is sufficient to
basic NT concepts, the intent of the author was to emulate
subvert emulation.
an exception dispatch on code calling
·ð Minimal OS stubs are present, but demonstrate a
NtRaiseException() directly. However, Sophos
lack of understanding of basic concepts.
failed to realise that System Call numbers vary across
·ð Sophos includes automated unpacking of many
windows versions. The original programmer copied the
archive and executable packer types, but are far
system call numbers from the SSDT of a Windows Server
too specific to be useful.
2003 SP1 kernel, not realising that these did not apply to
·ð A Javascript interpreter is used to emulate PDF
any other windows release (15). This entirely nonsense,
and HTML, exposing considerable attack surface.
non-functioning code10 has remained undisturbed for many
years.
Native Code Emulation
Executable code is simulated in a simplistic x86
Numerous similar mistakes and misunderstandings plague
emulator for a few hundred cycles during analysis. The
the Sophos codebase.
emulator records memory references and allows self-
modifying code to execute before the static file signatures
Javascript Emulation
are applied. The emulator also records characteristics that
Applying the same logic to dynamic HTML and
are used in gene matching.
PDF input, Sophos have built an ecmascript interpreter into
their product, based on SEE (Simple Ecmascript Engine) a
Evidently the key intention of the emulation is to allow
freely available BSD licensed interpreter. The interpreter is
trivial decryption loops to run before applying static file
used to emulate javascript payloads, record characteristics
signatures. Many naïve programmers use trivial XOR
and allow simple decryption loops to run.
decryption loops or similar simple tricks to obfuscate
program code or data. Sophos also uses these tricks to
SEE is unmaintained and abandoned, and has received little
obfuscate their product data.
attention from security researchers, who focus on more
widely used implementations such as SpiderMonkey,
Design
Tamarin and V8.
The emulator supports a small subset of x86
features; there is no concept of CPL or x87 support, for
As a result, SEE suffers from a number of documented
example. A minimal stub exists to service software
problems handling pathological expression, including
interrupts for MS-DOS and Windows executables.
broken locale handling, for example Figure 11
Bizarrely, the interrupt handler has been broken since its
demonstrates a code pattern that SEE fails to handle.
original implementation, due to Sophos misunderstanding
(new String()).localeCompare(Math.abs(-1));
of Windows NT internals.
Figure 11. Known problems in SEE locale handling.
Pseudocode representing the handler for software interrupt
2Eh (Windows NT System Call) is displayed in Figure 10.
10
With the exception of executables specifically written for a small number
of unsupported Windows 2003 Server releases.
requiring dozens of versions to be tested before an
Executable Packers
executable that could be unpacked was found.
Executable packers are self-extracting
compressed executables, widely used for software
The difficulty in producing a supported input for the
distribution. However, packers are a simple way for
purposes of testing demonstrates the effective obsolescence
unskilled users to transform one program into an equivalent
of this code13. Even an unskilled, naïve adversary simply
but different program, thus defeating blacklisting schemes
trying to perform a simple transformation would not have
with very low skill requirements.
any trouble subverting the automated unpacking process.
For this reason, Antivirus vendors often tout their
Summary
automated unpacking as a competitive advantage. In
·ð Automated unpacking is a considerable attack
theory, the more packers that a vendor recognises and
surface.
unpacks, the less opportunity for unskilled users to bypass
·ð Only old and outdated versions of packers are
their blacklists (of course even a moderately skilled
supported.
attacker could simply write an equivalent program).
·ð Many of the packers supported are irrelevant on
Interesting coverage of unpacking support in various
modern systems.
Antivirus programs is available in (15).
Archives and Containers
Executable Packers Supported
Sophos supports a large number of largely
The native packers11 I have observed support for
esoteric archive and container formats, used for extracting
in Sophos Antivirus are listed in Figure 12.
and identifying the relevant contents of archive files. While
there is a large volume of these extractors, they vary
Packer Year Summary
considerably in quality.
DIET 1992 Dr. Teddy s  DIET program for
files.
PKLITE 1996 PKZIP for executable files.
Many of the decoders are simply bizarre nonsense. For
LZEXE 1989 Fabrice Ballard s12 executable
example, the ELF decoder specifically excludes Siemens
packer.
TriCore executables (used in industrial microcontrollers).
UPX 2001 The Ultimate Packer for
eXecutables.
PETITE 1999 Ian Luck s executable packer.
ELF defines dozens of esoteric architectures like the Fujitsu
ASPACK 1999 Alexey Solodovnikov s Packer.
FR20 or the Matsushita MN10200, all of which are
FSG 2002 Fast Small Good , particularly
perfectly valid.
popular in Poland.
PECompact 2001 PE Compact
// This makes no sense.
if (ElfMachine != EM_TRICORE){
Figure 12 Packers Supported by Sophos Antivirus
// Matches ET_NONE, ET_REL, ET_EXEC and ET_DYN
if ((ElfType - 1) <= 2)
return CLASS_ELF_STORAGE.Name;
Unpacker Quality
return NULL;
}
With the exception of PECompact support which
Figure 13. Pseudocode for a bizarre architecture exclusion in the ELF
appears to have been licensed from the vendor, the
decoder.
unpacking routines appear to be original code developed by
The most likely explanation is that a customer complained
Sophos. The decoders generally only handle default options
that one of their embedded executables for a
and codecs, and cannot tolerate even minor stub
Siemens/Infineon TriCore device was triggering a CRC32
modifications.
collision with one of the static file signatures Sophos
distribute. Rather than fix the problem properly, Sophos
The majority of the packers supported are old and outdated
simply excluded the entire architecture, no longer
and of questionable utility, many do not support modern
recognising them as executable.
executables and are largely irrelevant.
Unpacker Generality
Summary
The routines implemented by Sophos often
·ð Emulation is trivial for attackers to detect, and
support one very old specific version of the packer. It took
provides little value for such a large attack
considerable effort to locate supported builds from
surface.
shareware archives in order to test the functionality, often
11
Sophos define additional unpackers using VDL, however these are a
negligible increase in attack surface.
12
Fabrice Bellard is now famous as the author of QEMU. 13 See Appendix for list of packer builds that were found to function.
·ð Unpackers and decompressor are high-volume
VIII. CONCLUSION
and low quality, providing little value and are
often outdated or irrelevant.
·ð Sophos have poor understanding of NT internals Sophos demonstrate considerable naivety in many topics
and executable file formats, ostensibly one of key to the efficacy of their product. Their widespread use
of XOR encryption for secrecy, and their poor
their core focus areas.
understanding of rudimentary exploitation concepts like
·ð Sophos perform little testing to verify their
return-to-libc reinforce this.
scanning process works as intended, often
shipping broken nonsense code.
The promise of antivirus is that users will be less dependent
·ð Pre-execution analysis represents a considerable
on making good trust decisions. While certainly desirable,
attack surface, including a full software machine
Sophos appear ill equipped to keep this promise with their
emulator, a javascript interpreter, and hundreds of
current technology.
decompression codecs and unpackers.
The pseudo-scientific terminology used by Sophos to
promote their software masks elementary pattern matching
VII. ATTACK SURFACE ENUMERATION
techniques. While their attempt at implementing runtime
exploit mitigation should be applauded, their failure to
understand the subject area resulted in a substandard
There is little intersection between the work of antivirus
product far exceeded by existing published solutions.
vendors and that of security researchers. Security
researchers operate on the assumption that users make good
trust decisions, and then try to find ways of subverting that.
IX. REFERENCES
Antivirus vendors, however, work on the assumption that
users are either unwilling or unable to make trust decisions.
TODO
Sadly, the antivirus vendors are correct. Many users,
perhaps the majority, are incapable of making good trust
1. McMillan, Robert. Security Vendors Slam Defcon
decisions. This is not entirely unreasonable; the process can
Virus Contest. PCWorld Business Center. [Online] 26
be complex, technical and confusing.
April 2008. [Cited: 13 April 2011.]
http://www.pcworld.com/businesscenter/article/145148/sec
While there is general agreement that the solution to this
urity_vendors_slam_defcon_virus_contest.html.
problem is to offload those decisions to someone (or
something) that is capable, we generally diverge on how to
2. SophosLabs. Sophos HIPS. Sophos. [Online]
approach to this.
http://www.sophos.com/security/sophoslabs/sophos-
hips/detection-layers.html.
Antivirus Products
The promise of antivirus software is that users
3. AV comparatives. [Online] http://www.av-
will be less dependent on making trust decisions.
comparatives.org/seiten/ergebnisse/methodology.pdf.
Evaluating antivirus software requires understanding of
how close to fulfilling this promise the vendor comes, and
4. Sophos. Sophos SAVI Interface Factsheet. [Online]
how much attack surface you must trade to achieve it.
http://www.sophos.com/sophos/docs/eng/factshts/Sophos-
SAVI-dsus.pdf.
In the case of Sophos, some of the major components that
contribute to the attack surface includes:
5.  . Sophos Reviewers Guide. [Online]
http://www.sophos.com/sophos/docs/eng/factshts/Sophos-
·ð An x86 software emulator executed on untrusted
SAV-ReviewersGuide-uk.pdf.
input.
·ð An unmaintained and poorly studied Ecmascript
6.  . IDE downloads. [Online]
interpreter.
http://www.sophos.com/downloads/ide/.
·ð Large numbers of archive unpackingand
7. Tinnes, Julien. Challenge Securitech (french). [Online]
decompression routines.
http://www.cr0.org/misc/jt-securitech-06-11.pdf.
·ð Packed executable processing.
·ð Weak authentication scheme on configuration
data.
8. Sophos. Sophos HIPS: Layers of Detection. [Online]
http://www.sophos.com/security/sophoslabs/sophos-
hips/detection-layers.html.
9.  . System Requirements. Sophos Anti Virus Product
Website. [Online] http://www.sophos.com/products/small-
business/sophos-anti-virus/system-requirements.html.
10. Microsoft. Microsoft Detours. [Online]
http://www.microsoftstore.com/store/msstore/en_US/pd/pr
oductID.216531800/search.true.
11. Preventing the Exploitation of SEH Overwrites .
Miller, Matt. 5, s.l. : Uninformed, 2006.
12. Miller, Matt. WehnTrust. [Online]
http://wehntrust.codeplex.com/.
13. Sophos. Sophos Behavioral Genotype Protection.
[Online]
http://www.sophos.com/support/knowledgebase/article/173
15.html.
14. Stragic Patents P.C. US Patent Provisional
application No. 60/825,557.
15. Metasploit Project. [Online]
http://dev.metasploit.com/users/opcode/syscalls.html.
16. PolyPack: An Automated Online Packing Service for
Optimal Antivirus Evasion. Jon Oberheide, Michael
Bailey, Farnam Jahanian.
17. Sophos. Sophos Endpoint Security and Control Help.
X. MISCELLANEOUS FIGURES
[CHUNK 2799, TYPE IDE_CHUNK_TYPE_SIGNATURE (1), CLASS IDE_CHUNK_CLASS_SMALL (4), 37 BYTES]
4ceb: 41 23 0a 43 09 54 75 72 62 6f 2d 34 34 38 42 01 A..C.Turbo.448B.
4cfb: 01 49 12 45 10 fb e8 00 96 1e 43 66 1b 24 96 20 .I.E......Cf....
4d0b: bc 81 b7 d4 ed .....
[CHUNK 2800, TYPE IDE_CHUNK_TYPE_SIGFLAGS (10), CLASS IDE_CHUNK_CLASS_EMPTY (0), 1 BYTES]
4ced: 0a .
[CHUNK 2801, TYPE IDE_CHUNK_TYPE_PSTRINGA (3), CLASS IDE_CHUNK_CLASS_SMALL (4), 11 BYTES]
4cee: 43 09 54 75 72 62 6f 2d 34 34 38 C.Turbo.448
[CHUNK 2802, TYPE IDE_CHUNK_TYPE_SUBCHUNKCOUNT (2), CLASS IDE_CHUNK_CLASS_SMALL (4), 3 BYTES]
4cf9: 42 01 01 B..
[CHUNK 2803, TYPE IDE_CHUNK_TYPE_BYTECODEHEADER (9), CLASS IDE_CHUNK_CLASS_SMALL (4), 20 BYTES]
4cfc: 49 12 45 10 fb e8 00 96 1e 43 66 1b 24 96 20 bc I.E......Cf.....
4d0c: 81 b7 d4 ed ....
[CHUNK 2804, TYPE IDE_CHUNK_TYPE_BYTECODE (5), CLASS IDE_CHUNK_CLASS_SMALL (4), 18 BYTES]
4cfe: 45 10 fb e8 00 96 1e 43 66 1b 24 96 20 bc 81 b7 E......Cf.......
4d0e: d4 ed ..
0000: fb e8 00 literaliw e8 00 ; match literal 16bit immediate
0003: 96 1e 43 66 1b 24 crc32 1e 43 66 1b 24 ; match crc32 n bytes (ones complement)
; generating 30 byte pre-image for crc 0x43661b24...
0000: 97 97 61 d9 38 9c 97 97 ..a.8...
0008: 97 97 97 97 97 97 97 97 ........
0010: 97 97 97 97 97 97 97 97 ........
0018: 97 97 97 97 97 97 ......
0009: 96 20 bc 81 b7 d4 crc32 20 bc 81 b7 d4 ; match crc32 n bytes (ones complement)
; generating 32 byte pre-image for crc 0xbc81b7d4...
0000: 4b 24 44 b0 c4 c4 c4 c4 K.D.....
0008: c4 c4 c4 c4 c4 c4 c4 c4 ........
0010: c4 c4 c4 c4 c4 c4 c4 c4 ........
0018: c4 c4 c4 c4 c4 c4 c4 c4 ........
000f: ed hlt ; end of program
Figure 14. Sample decoded virus signature.
[CHUNK 401, TYPE IDE_CHUNK_TYPE_SIGNATURE (1), CLASS IDE_CHUNK_CLASS_SMALL (4), 37 BYTES]
0ba3: 41 23 0a 43 09 41 49 44 53 2d 38 30 36 34 42 01 A..C.AIDS.8064B.
0bb3: 01 49 12 45 10 fb 9a 00 96 1e aa af bf aa 96 20 .I.E............
0bc3: 6c 69 f5 7c ed li...
[CHUNK 402, TYPE IDE_CHUNK_TYPE_SIGFLAGS (10), CLASS IDE_CHUNK_CLASS_EMPTY (0), 1 BYTES]
0ba5: 0a .
[CHUNK 403, TYPE IDE_CHUNK_TYPE_PASCALSTRING (3), CLASS IDE_CHUNK_CLASS_SMALL (4), 11 BYTES]
0ba6: 43 09 41 49 44 53 2d 38 30 36 34 C.AIDS.8064
[CHUNK 404, TYPE IDE_CHUNK_TYPE_SUBCHUNKCOUNT (2), CLASS IDE_CHUNK_CLASS_SMALL (4), 3 BYTES]
0bb1: 42 01 01 B..
[CHUNK 405, TYPE IDE_CHUNK_TYPE_BYTECODEHEADER (9), CLASS IDE_CHUNK_CLASS_SMALL (4), 20 BYTES]
0bb4: 49 12 45 10 fb 9a 00 96 1e aa af bf aa 96 20 6c I.E............l
0bc4: 69 f5 7c ed i...
[CHUNK 406, TYPE IDE_CHUNK_TYPE_BYTECODE (5), CLASS IDE_CHUNK_CLASS_SMALL (4), 18 BYTES]
0bb6: 45 10 fb 9a 00 96 1e aa af bf aa 96 20 6c 69 f5 E............li.
0bc6: 7c ed ..
0000: fb 9a 00 literaliw 9a 00 ; match literal 16bit immediate
0003: 96 1e aa af bf aa crc32 1e aa af bf aa ; match crc32 n bytes (ones complement)
; generating 30 byte pre-image for crc 0xaaafbfaa...
0000: 36 36 44 ea f8 ec 36 36 66D...66
0008: 36 36 36 36 36 36 36 36 66666666
0010: 36 36 36 36 36 36 36 36 66666666
0018: 36 36 36 36 36 36 666666
0009: 96 20 6c 69 f5 7c crc32 20 6c 69 f5 7c ; match crc32 n bytes (ones complement)
; generating 32 byte pre-image for crc 0x6c69f57c...
0000: bc 32 28 c1 4e 4e 4e 4e .2..NNNN
0008: 4e 4e 4e 4e 4e 4e 4e 4e NNNNNNNN
0010: 4e 4e 4e 4e 4e 4e 4e 4e NNNNNNNN
0018: 4e 4e 4e 4e 4e 4e 4e 4e NNNNNNNN
000f: ed hlt ; end of program
$ printf "\x9a\x0066D\xea\xf8\xec666666666666666666666666\xbc\x32\x28\xc1NNNNNNNNNNNNNNNNNNNNNNNNNNNN" > VIRUSLOL.EXE
$ sav32cli.exe VIRUSLOL.EXE
Sophos Anti-Virus
Version 1.01.1 [Win32/Intel]
Virus data version 4.61G, January 2011
Includes detection for 2225186 viruses, trojans and worms
Copyright (c) 1989-2011 Sophos Plc. All rights reserved.
System time 13:51:58, System date 17 April 2011
Quick Scanning
>>> Virus 'AIDS-8064' found in file VIRUSLOL.EXE
1 file swept in 5 seconds.
1 virus was discovered.
1 file out of 1 was infected.
Please send infected samples to Sophos for analysis.
For advice consult www.sophos.com, email support@sophos.com
or telephone +44 1235 559933
Ending Sophos Anti-Virus.
Figure 15. Producing random pre-images for Sophos signatures.
XI. APPENDIX
#include
#include
#include
#include "spmaa.h"
// This is an implementation of the proprietary SPA crypto algorithm used
// in Sophos products.
const static guint spmaa_index_vector[] = {
5, 1, 6, 4, 7, 2, 1, 3,
6, 3, 0, 7, 0, 4, 2, 5,
4, 6, 7, 1, 2, 7, 5, 0,
3, 5, 4, 2, 1, 0, 3, 6,
};
const static guint8 spa_lookup_a[] = {
0xB2, 0xC8, 0x3E, 0xA8, 0x14, 0xD4, 0x54, 0x40,
0x79, 0xEE, 0x24, 0xD3, 0x6F, 0x37, 0xC4, 0xE7,
0x4F, 0x42, 0x82, 0xE9, 0xC5, 0x1D, 0x50, 0xB4,
0x25, 0x97, 0x5D, 0x0E, 0xB5, 0xA5, 0x8F, 0x5E,
0x95, 0x34, 0xAE, 0xBD, 0xFD, 0x5C, 0xAD, 0x5F,
0x0C, 0xEA, 0x7A, 0xA7, 0x48, 0xEC, 0x6B, 0x08,
0x45, 0x26, 0xCF, 0x1E, 0x9B, 0x7C, 0x8A, 0x18,
0x98, 0x71, 0x65, 0x5B, 0xA2, 0x83, 0x3C, 0x91,
0x88, 0x73, 0xC2, 0x7D, 0xC6, 0xCA, 0x78, 0xFA,
0x6A, 0xF3, 0x9F, 0xF1, 0xD2, 0x19, 0x6E, 0x28,
0x9C, 0x86, 0x30, 0x1A, 0x41, 0xCD, 0x35, 0xE2,
0xCE, 0x7F, 0x68, 0x02, 0x29, 0x1F, 0x7B, 0xDB,
0x57, 0x75, 0xF0, 0x6D, 0x12, 0x4B, 0x4E, 0xD6,
0x09, 0x8B, 0x66, 0x31, 0x5A, 0xD7, 0x32, 0xF9,
0xC9, 0x77, 0xBF, 0xB8, 0x11, 0x8D, 0xD1, 0x16,
0x4C, 0xCB, 0xA1, 0x69, 0x3D, 0xAA, 0x0D, 0xD8,
0x39, 0x6C, 0x94, 0xF6, 0xE4, 0x80, 0x61, 0xCC,
0x93, 0xC7, 0x84, 0xEB, 0xE3, 0x99, 0xAF, 0x47,
0x1C, 0x63, 0x4D, 0xBE, 0x74, 0xB7, 0x8C, 0x96,
0xD0, 0x06, 0x56, 0xE8, 0x1B, 0x55, 0x3F, 0xFB,
0x2F, 0x64, 0xFC, 0x52, 0x17, 0x36, 0x49, 0xED,
0x67, 0x62, 0xE6, 0x43, 0x33, 0xA3, 0xDD, 0xBB,
0x03, 0xDC, 0xD9, 0xB6, 0xF4, 0xDF, 0xAC, 0xC1,
0x0A, 0x23, 0x87, 0x13, 0xFF, 0xEF, 0x22, 0x2E,
0x85, 0xD5, 0xDE, 0xF8, 0xE1, 0x0F, 0x01, 0xAB,
0x53, 0xF7, 0xE0, 0xB9, 0xC3, 0xDA, 0x9D, 0x9A,
0x38, 0x58, 0xA9, 0xF2, 0x10, 0xB3, 0x90, 0x76,
0x70, 0xBC, 0x2C, 0x60, 0x00, 0x92, 0xB1, 0x2A,
0xE5, 0x21, 0xA4, 0xFE, 0x2B, 0x7E, 0xA6, 0x3A,
0x0B, 0x72, 0xBA, 0x51, 0x44, 0xB0, 0xA0, 0x59,
0x27, 0x05, 0x89, 0x07, 0x9E, 0x20, 0x81, 0x3B,
0x8E, 0x46, 0xF5, 0x4A, 0x2D, 0x15, 0x04, 0xC0,
};
const static guint spa_lookup_b[] = {
0x31, 0x7A, 0x09, 0xC1, 0x12, 0xEC, 0xA8, 0x6B,
0x0D, 0xCD, 0x43, 0x6E, 0x23, 0xDF, 0xF9, 0xF5,
0xF6, 0x0E, 0xF4, 0x60, 0x82, 0x77, 0xC5, 0x59,
0xF0, 0x3C, 0xB2, 0xBC, 0x26, 0x4F, 0x11, 0xEB,
0xFF, 0x9C, 0x80, 0x47, 0xC8, 0xAB, 0x90, 0xAC,
0xD0, 0x45, 0x3F, 0x1B, 0x57, 0x50, 0x56, 0x6F,
0x69, 0xE0, 0x30, 0xC3, 0x99, 0x44, 0xA5, 0x1D,
0x5C, 0x81, 0xFE, 0x17, 0x28, 0x0A, 0x8E, 0x62,
0x18, 0x35, 0x2C, 0x7E, 0x25, 0xD7, 0xE1, 0xA1,
0xD4, 0x3B, 0x1A, 0x5F, 0x75, 0x5E, 0x74, 0xC4,
0xE8, 0x9A, 0xAF, 0x5B, 0x10, 0x97, 0x40, 0x7B,
0xBE, 0xFD, 0x08, 0x01, 0x96, 0xB7, 0x65, 0x37,
0x88, 0xED, 0x7D, 0xD9, 0x58, 0x94, 0x4E, 0xEF,
0xCC, 0x48, 0x3E, 0x15, 0x61, 0x38, 0x20, 0xA9,
0xA7, 0x68, 0xB9, 0x8F, 0x24, 0xA2, 0xB5, 0x27,
0x78, 0xDC, 0x13, 0xEE, 0x36, 0x4D, 0x5D, 0x2A,
0x32, 0x8A, 0x6C, 0xCE, 0xE4, 0xF2, 0xBA, 0x41,
0x49, 0xD1, 0xB8, 0x0B, 0xB6, 0x21, 0xF8, 0x04,
0x9B, 0xB0, 0x05, 0x34, 0xF1, 0xC6, 0x55, 0x89,
0xC0, 0x70, 0xD8, 0x8C, 0xBF, 0x9E, 0x0C, 0x64,
0xC7, 0xE6, 0xE9, 0x1C, 0x02, 0xBD, 0x51, 0xB3,
0x92, 0xCA, 0x3D, 0x00, 0xA4, 0x5A, 0xE7, 0xCF,
0x8D, 0x7C, 0x4C, 0x9F, 0x83, 0x3A, 0xE2, 0xC2,
0xE5, 0x73, 0xDD, 0xAD, 0x95, 0x76, 0x19, 0x9D,
0x7F, 0x66, 0x71, 0xAA, 0xA6, 0x07, 0x2B, 0x2D,
0x63, 0x84, 0xD3, 0xCB, 0xAE, 0x42, 0x14, 0x06,
0x72, 0x2F, 0x6D, 0x22, 0xEA, 0xD6, 0x54, 0x1F,
0x79, 0xFA, 0x16, 0xFB, 0x98, 0xB1, 0x0F, 0xFC,
0xB4, 0xA3, 0x8B, 0xF3, 0xD5, 0xC9, 0xBB, 0x03,
0x1E, 0xDE, 0xD2, 0x4A, 0x46, 0x91, 0x52, 0x67,
0x85, 0x29, 0x87, 0x33, 0x93, 0x53, 0x86, 0x39,
0xE3, 0x6A, 0x4B, 0xDB, 0xF7, 0xA0, 0x2E, 0xDA,
};
const static guint spa_lookup_c[] = {
0x38, 0x4B, 0xA6, 0x87, 0x19, 0x73, 0x68, 0x51,
0x3E, 0xC7, 0xAD, 0x1B, 0xC2, 0x25, 0x45, 0x94,
0xE2, 0x6A, 0xF5, 0xBE, 0x09, 0x83, 0x97, 0x84,
0x95, 0x91, 0x3D, 0xAA, 0x79, 0xF4, 0x8F, 0x9A,
0xA1, 0x7D, 0x52, 0x18, 0xC9, 0x60, 0xB8, 0xEF,
0xA4, 0x40, 0x62, 0xB4, 0xF2, 0xE4, 0xF9, 0xD0,
0x00, 0x49, 0xC0, 0xA7, 0xFF, 0x85, 0xEE, 0xE9,
0x88, 0xFD, 0x32, 0x71, 0x21, 0x31, 0x78, 0x33,
0xAB, 0xE3, 0xB5, 0x56, 0x5B, 0xF6, 0x36, 0x9C,
0x2B, 0xDC, 0x63, 0xE5, 0x93, 0x5F, 0x70, 0xD7,
0xC6, 0xEC, 0x7C, 0x59, 0xF1, 0xB0, 0x4E, 0x2E,
0x0B, 0x6E, 0x3B, 0xEB, 0x1E, 0xB1, 0x86, 0xA3,
0x82, 0xD9, 0x7B, 0x3A, 0x80, 0xDA, 0xD3, 0x37,
0x64, 0x6B, 0xC4, 0x6F, 0x2D, 0x10, 0x98, 0x92,
0x29, 0x4C, 0xB3, 0xDB, 0xE7, 0x46, 0x6C, 0x7E,
0xBB, 0xF7, 0xA2, 0x8B, 0xD2, 0x13, 0x1A, 0x58,
0x89, 0x6D, 0x26, 0xF8, 0xC1, 0xE6, 0x55, 0x7F,
0xC3, 0x17, 0x5C, 0x2C, 0x5A, 0xAE, 0x0C, 0xFA,
0xE8, 0x22, 0x0A, 0x77, 0x99, 0x8C, 0xA0, 0x90,
0x2A, 0x08, 0xBC, 0xED, 0x9E, 0x65, 0xDF, 0x53,
0x4D, 0x5D, 0x16, 0x04, 0x7A, 0xBF, 0x48, 0x12,
0x61, 0x43, 0xDD, 0xD4, 0xD1, 0x1C, 0x9D, 0x9F,
0xC5, 0xB9, 0x75, 0xD8, 0x05, 0x72, 0xAC, 0xAF,
0xF0, 0x27, 0x28, 0xA8, 0x1F, 0x57, 0x01, 0xD6,
0xFB, 0x42, 0xDE, 0xCD, 0x41, 0x0E, 0x4A, 0xD5,
0xF3, 0xBA, 0xB2, 0xCA, 0xB7, 0x8D, 0xFC, 0x50,
0x5E, 0x03, 0xCC, 0x54, 0x02, 0xA9, 0x34, 0x81,
0x67, 0x66, 0xCE, 0xEA, 0x69, 0x20, 0x30, 0xCF,
0x2F, 0x23, 0x76, 0x8E, 0xE0, 0x06, 0x15, 0x47,
0x74, 0x1D, 0x35, 0x24, 0xA5, 0x3F, 0xFE, 0x39,
0xC8, 0xE1, 0x44, 0x3C, 0xB6, 0x0D, 0xCB, 0x4F,
0x11, 0x07, 0x14, 0x8A, 0x96, 0xBD, 0x0F, 0x9B,
};
const static guint spa_lookup_d[] = {
0x90, 0x1A, 0xA3, 0x4F, 0x40, 0xA8, 0x1C, 0x9F,
0xC8, 0xB1, 0x9E, 0xE3, 0x60, 0x85, 0x19, 0xE2,
0xFD, 0xD7, 0x0A, 0xC9, 0xD3, 0x86, 0x00, 0x78,
0x06, 0x12, 0x8F, 0xBA, 0x2E, 0x53, 0x1D, 0x07,
0x2D, 0x16, 0xF5, 0xF2, 0xD1, 0xE0, 0xF8, 0x4C,
0x26, 0x57, 0xB9, 0xD8, 0xC3, 0x3D, 0x7A, 0xB5,
0xDB, 0x24, 0x0F, 0x63, 0x2C, 0xC0, 0x82, 0x51,
0x37, 0x99, 0xA9, 0x65, 0x47, 0xAB, 0xDA, 0x39,
0xE5, 0xA5, 0x58, 0x98, 0x4B, 0x9B, 0xBD, 0xAC,
0xEB, 0x5F, 0x3B, 0x03, 0x9A, 0xE6, 0x28, 0x43,
0xD9, 0xCC, 0xFA, 0xA0, 0x30, 0xB2, 0xB6, 0xA4,
0x84, 0x80, 0x72, 0xD6, 0xAE, 0x3A, 0xA7, 0x33,
0x0C, 0x05, 0xEF, 0xE9, 0x89, 0xA1, 0x79, 0x18,
0x62, 0x96, 0x6F, 0x50, 0xCE, 0x92, 0x7C, 0x2B,
0x5D, 0x8A, 0xF1, 0xFC, 0x97, 0xF7, 0x02, 0xAF,
0xFE, 0x54, 0x46, 0x93, 0x3F, 0xB0, 0x81, 0x68,
0x5B, 0x11, 0xC7, 0x1B, 0xBC, 0x8C, 0xC4, 0x5C,
0x8B, 0x34, 0xB7, 0x2A, 0x91, 0x7F, 0x41, 0x9D,
0xCF, 0x31, 0x7D, 0x67, 0xE1, 0x76, 0xE4, 0x22,
0xC2, 0x61, 0x6C, 0xA2, 0x95, 0xEA, 0x1F, 0x14,
0x3E, 0x32, 0x7E, 0xDE, 0x56, 0xB4, 0x52, 0x0E,
0x1E, 0x59, 0x29, 0x6A, 0x73, 0x9C, 0xDC, 0x69,
0xBF, 0x7B, 0x0D, 0x8E, 0x13, 0xFF, 0xDF, 0xC6,
0x23, 0x6B, 0xED, 0xD4, 0xF0, 0xF6, 0x64, 0x20,
0x38, 0xFB, 0x44, 0x09, 0x66, 0xCB, 0xDD, 0x74,
0x71, 0x5A, 0x10, 0xB8, 0x4A, 0x83, 0x75, 0xAD,
0x45, 0x77, 0x01, 0x4E, 0xB3, 0x8D, 0x6D, 0x21,
0x70, 0xF4, 0xBE, 0xC5, 0x88, 0xF9, 0x49, 0xE7,
0x27, 0xEE, 0x48, 0x04, 0x15, 0xD0, 0xD5, 0xEC,
0x0B, 0xCD, 0x55, 0xCA, 0x87, 0x5E, 0xA6, 0x08,
0x2F, 0x35, 0x4D, 0x36, 0xE8, 0xBB, 0xAA, 0x17,
0x42, 0xC1, 0x6E, 0x3C, 0x25, 0xF3, 0xD2, 0x94,
};
void spmaa_init(spmaa_t * state, gconstpointer key)
{
memset(state, 0, sizeof(spmaa_t));
// g_debug("initializing spmaa state @%p with key %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx",
// state,
// ((guint8 *)(key))[0],
// ((guint8 *)(key))[1],
// ((guint8 *)(key))[2],
// ((guint8 *)(key))[3],
// ((guint8 *)(key))[4],
// ((guint8 *)(key))[5],
// ((guint8 *)(key))[6],
// ((guint8 *)(key))[7]);
// Setup key.
spa_setk(&state->internal, key);
return;
}
void spa_setk(struct spa * state, const guchar * key)
{
for (guint i = 0; i < 8; i++) {
state->key[i + 0] = key[spmaa_index_vector[4 * i + 0]];
state->key[i + 8] = key[spmaa_index_vector[4 * i + 1]];
state->key[i + 16] = key[spmaa_index_vector[4 * i + 2]];
state->key[i + 24] = key[spmaa_index_vector[4 * i + 3]];
}
return;
}
void spmaa_buffer(spmaa_t *state, gconstpointer data, gushort length)
{
const guint8 * buffer = data;
for (guint i = 0; i < length; i++) {
// Prepare next byte.
state->internal.cryptbuffer[state->bytesavail] ^= buffer[i];
if (state->bytesavail++ == 7) {
// Reset Counter.
state->bytesavail = 0;
// Encrypt.
spa_crypt(&state->internal, 0);
}
}
return;
}
guint32 spmaa_finalise32(spmaa_t * state)
{
if (state->bytesavail) {
spa_crypt(&state->internal, 0);
}
return state->internal.cryptbuffer[4] << 0
| state->internal.cryptbuffer[5] << 8
| state->internal.cryptbuffer[6] << 16
| state->internal.cryptbuffer[7] << 24;
}
void spa_crypt(struct spa * state, gboolean mode)
{
guint8 T[8];
guint32 A, B, C, D, E, F, G, H, I, J, K;
guint32 i, j;
// Reset state.
A = B = C = D = E = F = G = H = I = J = K = 0;
// Initialize.
T[3] = state->cryptbuffer[0];
T[2] = state->cryptbuffer[1];
T[1] = state->cryptbuffer[2];
T[0] = state->cryptbuffer[3];
T[4] = state->cryptbuffer[4];
T[5] = state->cryptbuffer[5];
T[6] = state->cryptbuffer[6];
T[7] = state->cryptbuffer[7];
for (i = 0; i < 8; i++) {
// Next byte.
A = B = C = E = 0;
j = mode ? (7 - i) : i;
A = (spa_lookup_a[state->key[j + 8] ^ T[5]] & 0xF0) | (spa_lookup_c[state->key[j + 0] ^ T[4]] & 0x0F);
B = (spa_lookup_b[state->key[j + 16] ^ T[6]] & 0xF0) | (spa_lookup_a[state->key[j + 8] ^ T[5]] & 0x0F);
C = (spa_lookup_d[state->key[j + 24] ^ T[7]] & 0xF0) | (spa_lookup_b[state->key[j + 16] ^ T[6]] & 0x0F);
E = (spa_lookup_c[state->key[j + 0] ^ T[4]] & 0xF0) | (spa_lookup_d[state->key[j + 24] ^ T[7]] & 0x0F);
D = (spa_lookup_d[state->key[j + 24] ^ T[7]] & 0x0F);
F = T[4];
G = T[5];
H = T[6];
I = T[7];
D = T[3];
J = C ^ D;
T[4] = J;
J = T[2];
K = E ^ J;
T[5] = K;
T[6] = T[1] ^ A;
K = B;
D = T[0] << 0 | T[1] << 8 | T[2] << 16 | T[3] << 24;
D = D ^ K;
T[7] = D;
T[3] = F;
T[2] = G;
T[1] = H;
T[0] = I;
}
state->cryptbuffer[0] = T[4];
state->cryptbuffer[1] = T[5];
state->cryptbuffer[2] = T[6];
state->cryptbuffer[3] = D;
state->cryptbuffer[4] = F;
state->cryptbuffer[5] = G;
state->cryptbuffer[6] = H;
state->cryptbuffer[7] = I;
}
void spa_cbcdec(spmaa_t *state, gpointer block)
{
guint8 *ciphertext = block;
guint i;
if (ciphertext) {
for (i = 0; i < 8; i++) {
state->internal.cryptbuffer[i] = ciphertext[i];
}
spa_crypt(&state->internal, 1);
for (i = 0; i < 8; i++) {
state->internal.cryptbuffer[i] ^= state->internal.prevblock[i];
state->internal.prevblock[i] = ciphertext[i];
ciphertext[i] = state->internal.cryptbuffer[i];
}
return;
}
// Reset CBC State.
memset(state->internal.prevblock, 0, sizeof(state->internal.prevblock));
return;
}
Figure 16. SPMAA implementation in C


Wyszukiwarka

Podobne podstrony:
Sequencing and Analysis of Neanderthal Genomic
Static Analysis of Binary Code to Isolate Malicious Behaviors
[2006] Analysis of a Novel Transverse Flux Generator in direct driven wind turbine
1801?sign Analysis of Fixed Pitch Straight Bladed Vertical Axis Wind Turbines
Foresight analysis of wind power in Turkey
Analysis of Post Detonation Products of Different Explosive Charges
Rowe B Analysis of the First Key
Analysis of residual styrene monomer and other VOC in expand
Comparative study based on exergy analysis of solar air heater collector using thermal energy storag
Butterworth Finite element analysis of Structural Steelwork Beam to Column Bolted Connections
Analysis of ADN, Its Precursor and Possible By Products Using Ion Chromatography
Analysis of volatile organic compounds using gas
Quantitative dilatometric analysis of intercritical annealing in a low silicon TRIP steel
Molecular analysis of C glabrata
Berkovich Group Analysis of ODEs of order n bigger than 2 (1997) [sharethefiles com]
Evaluation of HS SPME for the analysis of volatile carbonyl

więcej podobnych podstron