Unpacking For Dummies Compressed
Unpacking For Dummies Compressed
Paul Jung
@_ _thanat0s_ _
Rémi Chipaux,
@futex90
X86 aware anyone ??
Are you ready ?
●
○ http://upload.trollprod.org/Unpacking_Workshop_VmWare.zip
Packing
Why packers
●
●
●
Why un-packing
●
○
●
○
Why un-packing
●
○
What kind of tools people use to pack
●
●
●
●
Concepts Needed
Mandatory to no leave the room in 10 minutes
Things to Know
●
●
●
●
●
Entry Point & File Mapping
_IMAGE_SECTION_HEADER
File.exe
DOS Header
PE Header
.idata
.data
.text
MZ
PE
Sections
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
union {
DWORD PhysicalAddress;
DWORD VirtualSize;
} Misc;
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
Entry Point
_IMAGE_OPTIONAL_HEADER
File.exe
DOS Header
PE Header
.idata
.data
.text
MZ
PE
Entry Point
typedef struct _IMAGE_OPTIONAL_HEADER {
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
DWORD BaseOfData;
DWORD ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
. . .
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
0x00000000
0x00400000
MZ
DOS Header
PE
PE Header
File Mapping
0x00401000
.text
EIP
0x00402000
0x00405000
.idata
Import table
0x00400000
MZ
0x00000000
DOS Header
PE
PE Header
0x00401000
File Mapping
.text
mype.exe
0x00402000
.data
0x00405000
.idata
0x00410000
VIRTUAL MEMORY
MZ
DOS Header
PE
PE Header
0x00411000
mydll.dll
.text
0x00412000
.data
PEB (Process Environment Block)
●
●
○
○
PEB (Process Environment Block)
Traversing module list
LoaderData
3 Chained lists;
InLoadOrderModuleList; DLL & PE at Start
InMemoryOrderModuleList; DLL & PE, current state
InInitialisationOrderModuleList; DLL loaded current state
Traversing module list
LoaderData
Traversing module list
LoaderData
push 30h
pop ecx
mov esi, fs:[ecx] ; PEB (FS:[0x30])
mov esi, [esi+0Ch] ; ESI = LoaderData
mov esi, [esi+1Ch] ; ESI = Flink InInitialisationOrderModuleList
mov ebp, [esi+8] ; EBP = Base addresse de ntdll
mov ds:ntdllbase, ebp
Traversing module list
LoaderData
● ntdll
● kernel32
Traversing module list
LoaderData
Function
EAT DLL PE Stub
Offset
Packer families
How does it work
Mainly three kinds of techniques
● PE
○
■
RWX
●
●
●
■
●
●
●
Mainly three kinds of techniques
PE PE
●
○
■
■
■
■
■
RunPE
SPENDED Executable B
ATE_SU
P r oc ess, CRE
Creat e
-> PEB
t : EBX
e ad Contex
GetThr
Packer A
Malware B
RunPE
Malware B
RunPE
• Artefact
• No parents
Mainly three kinds of techniques
PE PE
●
○
■
■
■
Malware analysis
Injection Simple
Executable B
AllocEx
Virtual
Packer A emory
r o c e s s M
WriteP
d
e s u m eThrea
Malware B R
Malware analysis
Injection simple
• Running executable is « Legit ». Executable B
●
○
●
○
●
○
●
○
RunPE
Classical
RUNPE
In
.NET code
Where are the packed data ? .NET PE
●
○
○
○
●
○
○
■
Packer detection
How to know if it’s packed
Identifying that your sample is packed
A bunch of clues:
● High section entropy (Above 6.5).. Maybe usual on ressources.
● Unusual small code segments.
● No clear strings in the whole PE.
● Few Import ( not relevant in .net )
● Unusual segment names.
○ Home made scripts
■ https://github.com/Th4nat0s/Chall_Tools
Identify that your sample is packed
● A bunch of clues
○ None or very few winnt API calls present in the IAT
$rabin2 -i mymalware.exe
[Imports]
ordinal=001 plt=0x00000000 bind=NONE type=FUNC name=kernel32.dll_GetModuleHandleA
ordinal=002 plt=0x00000000 bind=NONE type=FUNC name=kernel32.dll_GetProcAddress
ordinal=003 plt=0x00000000 bind=NONE type=FUNC name=kernel32.dll_ExitProcess
ordinal=004 plt=0x00000000 bind=NONE type=FUNC name=kernel32.dll_LoadLibraryA
ordinal=001 plt=0x00000000 bind=NONE type=FUNC name=user32.dll_MessageBoxA
ordinal=001 plt=0x00000000 bind=NONE type=FUNC name=advapi32.dll_RegCloseKey
ordinal=001 plt=0x00000000 bind=NONE type=FUNC name=oleaut32.dll_SysFreeString
ordinal=001 plt=0x00000000 bind=NONE type=FUNC name=gdi32.dll_CreateFontA
ordinal=001 plt=0x00000000 bind=NONE type=FUNC name=shell32.dll_ShellExecuteA
ordinal=001 plt=0x00000000 bind=NONE type=FUNC name=version.dll_GetFileVersionInfoA
ordinal=001 plt=0x00000000 bind=NONE type=FUNC name=mscoree.dll__CorExeMain
11 Imports
Identify that your sample is packed
A bunch of clues
● High section entropy
● Unusual small code segments
● Unusual segment names
○ Home made scripts
■ https://github.com/Th4nat0s/Chall_Tools
$peentro.py badfile.exe
Section Entropy Size MD5 Remark
.text 4.40891301623 4096 3c25c7a8d445ed1528ba543d6ef35b81
.rdata 2.51973214733 4096 774e8378a9026e53a894eb2043a9cc69
.data 0.599092931135 4096 5c22f870e9c25a2e9331ea30ea55b0ee
.CODE 7.85331928916 86016 dfcbb76bec31c0be1091107edb6ce5d8 Unusal Segment,High Entropy
.rsrc 1.12323628339 4096 adfd501e3b4857ad481c68a07e2425f8
.reloc 0.8026442707 4096 5e07aef133521c73130ec441ed9fa82a
Identify the packer
Known tools/packers are easy to identify
● Unix command file works «only» for Upx
● Some packers (Upx, Vmprotect) cannot pack .NET PE
● Yara rules or the old PEid
○ https://github.com/Yara-Rules/rules/blob/master/Packers/packer.yar
○ https://www.aldeid.com/wiki/PEiD
● RDG packer detector
○ http://www.rdgsoft.net (Mute the browser !!!)
● DIE (DetectItEasy)
○ https://github.com/horsicq/Detect-It-Easy | http://ntinfo.biz/
● Exeinfo
○ http://exeinfo.atwebpages.com/
Identifier Tools Usage
● DIE
$./diec /home/thanat0s/sample0.exe
PE+(64): compiler: Microsoft Visual C/C++(2008)[-]
PE+(64): linker: Microsoft Linker(9.0)[EXE64,console]
$./diec /home/thanat0s/sample1.exe
PE: protector: ENIGMA(3.70 build 2015.6.14 20:50:1)[-]
PE: compiler: MinGW(-)[-]
PE: linker: GNU Linker(2.25)[EXE32,admin]
$./diec /home/thanat0s/sample2.exe
PE: packer: UPX(0.39)[NRV,best]
PE: linker: Polink(2.50*)[EXE32]
$./diec /home/thanat0s/sample3.exe
PE: protector: Confuser(1.X)[-]
PE: library: .NET(v2.0.50727)[-]
PE: linker: Microsoft Linker(8.0)[EXE32]
Identifier Tools Usage
● File
○ file badfile.exe
● Yara
○ yara (peid|packer).yar badfile.exe
● Some homemade (& dirty) tools
○ peentro.py badfile.exe
$peentro.py badfile.exe
Section Entropy Size MD5 Remark
.text 4.40891301623 4096 3c25c7a8d445ed1528ba543d6ef35b81
.rdata 2.51973214733 4096 774e8378a9026e53a894eb2043a9cc69
.data 0.599092931135 4096 5c22f870e9c25a2e9331ea30ea55b0ee
.CODE 7.85331928916 86016 dfcbb76bec31c0be1091107edb6ce5d8 Unusal Segment,High Entropy
.rsrc 1.12323628339 4096 adfd501e3b4857ad481c68a07e2425f8
.reloc 0.8026442707 4096 5e07aef133521c73130ec441ed9fa82a
SNAPSHOT YOUR VM !!
Packed or not packed ?
Packing triage…. http://upload.trollprod.org/samples.zip
Packed ? Why ? Packed ? Why ?
Sample A Sample K
Sample B Sample L
Sample C Sample M
Sample D Sample N
Sample E Sample O
Sample F Sample P
Sample G Sample Z
Sample H
Sample I
Sample J Password is : infected
Packing triage…….
Packed ? Why ? Packed ? Why ?
Sample A No but a lot of small B64 strings. Sample K Yes, Entropy, weirds segs.
Sample B Yes, Diec -> Upx Sample L ...don’t know… weird seg.
Sample C Yes, Diec -> Confuser Sample M Yes, Entropy
Sample D Yes No strings.. Ugly in DnSpy. Sample N Yes, ~Entropy, weirds segs.
Sample E Yes, Entropy, dual code segs. Sample O Yes, Entropy ++
Sample F Yes, Entropy Sample P it’ Notepad :)
Sample G Yes, Entropy, weirds segs. Sample Z Yes, Diec -> Enigma
Sample H No strings...but imports...
Sample I Yes, Entropy in data
Sample J Yes, Huge B64 Strings , Ugly in DnSpy
.NET Packer UnPacking
Unpacking .NET samples
● NEVER open a .NET sample in x86dbg… (it hurts, badly...)
● Detect .NET type with «file» or «die»
● .NET methods and variables are more than often obfuscated
Unpacking .NET samples
Unobfuscation with DE4DOT
https://github.com/0xd4d/de4dot
Unpacking .NET samples
Look for “New modules”
https://github.com/CodeCracker-Tools/MegaDumper
● The pain point is, your VM could run slowly (it’s an endless loop) use
multiple CPUs.
“Find the new RWX segment” and dump :)
● Break on new RWX segment creation
○ Convert it to RW and wait the exception.
But dumping is not that simple…
Rebuilding
● IAT
● IEP
Simply “Break” and dump :)
● Find the unciphered protected PE in a memory segment
○ Break on
■ WriteProcessMemory
■ VirtualAlloc
■ VirtualAllocEx
■ MapViewOfFile
■ UnmapViewOfFile
■ ….. A lot of them
Simply “Break” and dump :)
● Be careful, sometimes the packer use the undocumented API
■ Kernel32.WriteProcessMemory
● call ntdll.NtWriteVirtualMemory
https://undocumented.ntinternals.net/
Let’s unpack a RunPE !
Sample_n.exe
….. Unpack time
BreakPoint on
kernel32!WriteProcessMemory
Going further....
VM Based and Pro packers
Not so easy to extract…
VMProtect http://vmpsoft.com/
TheMida : https://www.oreans.com/themida.php
Paul Jung
@_ _Thanat0s_ _
[email protected]
www.excellium-services.com
Remi Chipaux
www.qintel.com/company