2. Who am I
˃ A
so/ware
developer
with
passion
for
func:onal
programming
(F#)
˃ A
so/ware
security
consultant
˃ Collaborate
with
OWASP
Italy
(Co-‐authored
OWASP
Tes:ng
Guide
v2
and
v3)
˃ In
the
spare
:me
write
so/ware
(see
hMp://nebula.tools)
˃ Currently
working
for
Reply
Communica:on
Valley
as
head
of
the
so/ware
development
team
3. Agenda
˃ Introduc:on
to
.NET
˃ Diassemble
a
binary
˃ How
to
debug
.NET
applica:on
˃ Using
Reflec:on
˃ Decompila:on
and
an:-‐decompila:on
tricks
˃ Profile
API
and
extended
Reflec:on
˃ Use
case:
reversing
a
malware
4. .NET CLR
“At
a
high
level,
.NET
is
a
virtual
run:me
environment
that
consists
of
a
virtual
execu:on
engine,
the
Common
Language
Run:me
(CLR),
and
a
set
of
associated
framework
libraries.
Applica:ons
wriMen
for
.NET,
at
compile
:me,
do
not
translate
into
machine
code
but
instead
use
an
intermediary
representa:on
that
the
execu:on
engine
translates
at
run:me
(depending
on
architecture).”
Ref.
Advanced
.NET
Debugging
5. .NET CLR
§ We
can
write
in
any
language
supported
by
the
.NET
Framework
§ We
can
use
any
libraries
wriMen
in
.NET
languages
§ The
MSIL
(Microso/
Intermediate
Language)
is
compiled
to
na:ve
code
through
a
Just
In
Time
Compiler
(JIT
Compiler)
6. .NET Assembly File format
.NET
File
format
˃ Take
advantage
of
the
Op:onal
Header
˃ The
Op:onal
Header
is
not
op:onal
J
˃ Contains
all
the
metadata
of
the
Assembly
(string,
token
id,
etc…)
7. .NET CLR Memory Model
˃ Every
Object
instance
contains
˃ A
pointer
to
a
sync-‐block
˃ A
pointer
to
a
Type
Object
˃ The
instance
fields
˃ For
each
object
there
exist
only
one
Type
Object
˃ Every
methods
in
the
MethodTable
point
to
the
IL
code
or
to
the
JiMed
code
Logical
view
Memory
View
8. .NET Just In Time CompilaEon
1°
:me
execu:on
2°
:me
execu:on
10. A simple (and meaningless) example of C# code
namespace
ConsoleApplica:on
{
class
Program
{
sta:c
void
Main(string[]
args)
{
var
simpleClassInstance
=
new
SimpleClass("Asia");
simpleClassInstance.SayHello();
}
}
}
public
sealed
class
SimpleClass
{
public
String
Name
{
get;
private
set;
}
public
SimpleClass(String
name)
{
this.Name
=
name;
}
public
void
SayHello()
{
Console.WriteLine("Hello:
"
+
this.Name);
}
public
Boolean
IsTwo(Int32
num)
{
if
(num
==
2
&&
num
==
3)
{
this.SayHello();
return
true;
}
return
false;
}
}
11. Dis/assembler tools of the trade
˃ Ildasm
(allow
to
disassemble
binary):
C:Program
Files
(x86)Microso/
SDKsWindowsv8.0AbinNETFX
4.0
Tools
ildasm.exe
˃ Ilasm
(allow
to
assembly
IL
code):
c:WindowsMicroso/
.NETFrameworkv4.0.30319ilasm.exe
˃ How
to
disassemble:
ildasm.exe
ConsoleApplica:on.exe
-‐out=msil.il
˃ How
to
assemble:
ilasm.exe
/EXE
msil.il
12. MSIL
˃ It
is
the
common
bytecode
that
is
compiled
to
na:ve
code
by
the
JIT
˃ It
is
stack
based
No
concept
of
registers,
exists
only
local
variables
˃ It
is
managed
˃ The
CLR
it
is
a
managed
environment,
you
can’t
jump
around
as
you
do
with
na:ve
code
˃ You
can’t
access
memory
unless
you
have
the
right
privileges
14. .NET Debugging
˃ Debugging
.NET
applica:on
is
the
easiest
way
to
understand
how
the
CLR
works
˃ And
also
to
catch
that
“strange”
bug
in
your
code
J
˃ Tools
of
the
trade
˃ Windbg
˃ SOS
extension
15. .NET Debugging
˃ In
order
to
debug
.NET
program
is
necessary
to
load
the
SOS
extension
compa:ble
with
the
version
of
the
loaded
CLR
˃ To
do
this
list
the
loaded
modules
˃ Iden:fy
a
CLR
dll
(like
clrjit.dll)
˃ Use
this
dll
to
load
the
correct
version
of
the
SOS
extension
˃ Use
the
.loadby
command
to
load
the
SOS
extension
˃ Eg.
.loadby
sos.dll
clrjit
(if
the
execu:on
fails,
run
the
command
sxe
ld
clrjit.dll
and
than
g
to
breakpoint
at
CLR
loading)
16. .NET Debugging
˃ Some
usefull
command
during
your
.NET
sessione
debugging
˃ !bpmd
:
set
a
breakpoint
to
a
given
method
˃ !ClrStack:
show
the
current
CLR
stack
˃ !DumpDomain
:
show
all
the
current
available
domains
˃ !DumpAssembly
:
show
details
about
a
specific
assembly
˃ !DumpModule
:
show
details
about
a
specific
module.
The
–mt
op:on
show
also
info
on
the
MethodTable
˃ !DumpMt
:
show
details
about
the
specific
method
table.
The
–md
op:on
show
also
info
on
the
methods
available
˃ !DumpIL
:
show
the
MSIL
code
of
the
specified
method
17. .NET Debugging – Demo
˃ Breakpoint
on
module
load
˃ I
use
the
clrjit.dll
because
is
loaded
at
the
right
:me
(the
CLR
environment
was
loaded)
˃ Command:
sxe
ld
clrjit.dll
˃ Load
the
SOS
extension
by
referencing
the
clrjit
dll
˃ Command:
.loadby
sos
clrjit
18. .NET Debugging – Demo
˃ Dump
the
domains
˃ Command:
!DumpDomain
˃ Iden:fy
the
interesed
module
to
analyze
19. .NET Debugging – Demo
˃ Dump
the
iden:fied
module
with
details
on
the
associated
method
table
˃ Command:
!DumpModule
–mt
<module
id>
˃ Iden:fy
the
address
of
the
MethodTable
20. .NET Debugging – Demo
˃ Dump
the
iden:fied
method
table
with
details
on
the
method
descriptors
˃ Command:
!DumpMT
–md
<method
table>
˃ Iden:fy
the
address
of
the
MethodDescriptor
to
dump
Some
methods
was
alredy
jiMed
and
cached
21. .NET Debugging – Demo
˃ Dump
the
iden:fied
method
descriptor
˃ Command:
!DumpMD
<method
descriptor>
˃ Dump
the
IL
of
the
iden:fied
method
descriptor
˃ Command:
!DumpIL
<method
descriptor>
22. .NET Debugging
˃ If
we
want
to
set
a
breakpoint
on
a
method
in
order
to
be
disassebled
before
to
be
executed,
we
can:
˃ Iden:fy
the
method
that
we
want
to
disassemble
(for
example
LicensedSo/ware.PrimeAlgo.IsPrime)
˃ Execute
the
command:
!bpmd
LicensedSo/ware.exe
LicensedSo/ware.PrimeAlgo.IsPrime
˃ Run
the
program
23. .NET Debugging
˃ As
said
debugging
is
the
most
useful
ac:vity
to
know
exactly
what
happen
in
the
program
˃ If
necessary
you
can
also
analyze
the
transi:on
to
unmanaged
code
˃ Unfortunatly
is
not
very
user
friendly
˃ If
you
don’t
use
WindDbg
every
days
you
will
forget
very
soon
the
name
of
the
commands
:
˃ Fortunatly
we
have
s:ll
one
secret
weapon…
24. .NET ReflecEon
“The
classes
in
the
System.Reflec3on
namespace,
together
with
System.Type,
enable
you
to
obtain
informa3on
about
loaded
assemblies
and
the
types
defined
within
them,
such
as
classes,
interfaces,
and
value
types.
You
can
also
use
reflec3on
to
create
type
instances
at
run
3me,
and
to
invoke
and
access
them.
For
topics
about
specific
aspects
of
reflec3on,
see
Related
Topics
at
the
end
of
this
overview.”
If
you
known
at
least
one
.NET
high
level
language,
you
will
love
reflec:on
J
26. .NET ReflecEon
˃ Let’s
consider
an
example
with
intent
taken
from
a
real
applica:on
Any
idea
on
how
to
“crack”
this
applica:on
in
an
easy
way?
27. .NET ReflecEon
˃ When
you
design
a
license
code
remember
to:
˃ Use
whenever
possible
sealed
class
˃ Don’t
use
interface
or
abstract
class
when
design
your
license
check
code
˃ Use
whenever
possbile
private
or
internal
class
˃ With
this
sugges:ons
you
will
be
able
to
stop
most
of
the
cracking
aDempt
to
your
code
29. Decompiler
˃ When
an
high
level
language
is
compiled
a
lot
of
informa:on
are
stored
in
the
resul:ng
assembly
˃ Name
of
every
func:ons
(even
private
one)
˃ Name
of
every
fields
(even
private
one)
˃ Name
of
parameters
˃ …
˃ Only
the
name
of
the
local
variables
is
lost
31. AnE-‐DecompilaEon tricks
Disassemble
IL_0014:
nop
IL_0015:
ldarg.0
IL_0016:
call
instance
void
ConsoleApplica:on.SimpleClass::SayHello()
IL_001b:
nop
IL_001c:
ldc.i4.1
IL_001d:
stloc.0
IL_001e:
br.s
IL_0024
§ The
if
branch
is
never
taked
and
the
SayHello
instance
method
is
never
invoked.
The
func:on
always
return
false
regardless
of
the
input
value
§ Yes
I
known,
not
a
very
useful
func:on
:P
§ By
conven:on
before
to
call
an
instance
func:on
a
pointer
to
this
must
be
pushed
on
the
stack.
In
this
way
a
pointer
to
this
can
be
read
with
ldarg.0
§ What
happen
if
we
omit
this
details?
32. AnE-‐DecompilaEon tricks
§ Open
the
msil
source
code
file
with
your
prefered
editor
§ Comment
the
loading
of
the
IL_0014:
nop
//
IL_0015:
ldarg.0
IL_0016:
call
instance
void
ConsoleApplica:on.SimpleClass::SayHello()
IL_001b:
nop
IL_001c:
ldc.i4.1
IL_001d:
stloc.0
IL_001e:
br.s
IL_0024
Assemble
this
pointer
(add
the
characters
//
at
the
line
start)
§ Assemble
the
file
with
ilasm
(ilasm.exe
msil.il)
§ Open
youe
prefered
decompiler
and
try
to
decompile
the
IsTwo
rou:ne
Decompile
35. .NET Reflector decompilaEon result
§ A
crash
report
is
generated
when
tryng
to
decompile
the
class
bytecode
(by
the
way
Reflector
is
the
only
not
free
decompiled
considered
in
our
tests)
37. AnE-‐Analysis tricks -‐ SuppressIldasmAQribute
˃ Pro:
˃ Prevents
the
Ildasm.exe
(IL
Disassembler)
from
disassembling
an
assembly.
˃ Cost:
˃ Just
edit
the
binary
and
rename
the
string
SuppressIldasmAMribute
to
Antaniprematuraatribute
to
desable
this
“feature”
˃ Only
works
for
ildasm
L
38. AnE-‐Analysis tricks -‐ Method Name Scrambling
˃ The
CLR
doesn’t
have
a
very
strict
rule
on
the
characters
to
use
for
method
naming
˃ At
least
is
not
strict
as
that
of
the
High
Level
Language
(C#,
VB.NET,
F#)
˃ Even
Ildasm
doen’t
handle
very
well
special
characters
˃ Let’s
try
to
edit
the
name
of
a
method
with
not
printable
characters
40. AnE-‐Analysis tricks -‐ Method Name Scrambling
˃ (Un)Fortunatly
Name
Scrambling
is
preMy
easy
to
overcome
˃ Just
open
you
Assembly
and
rewrite
all
the
unprintable
characters
with
printable
one
˃ Of
course
by
using
Mono.Cecil
J
41. AnE-‐Analysis tricks – Unsupported Method
Signatures
˃ Create
methods
with
the
same
name
and
input
variables
but
different
return
type
˃ This
is
invalid
in
most
of
the
.NET
high
level
languages
˃ But
valid
at
the
CLR
level
42. AnE-‐Analysis tricks – Unsupported Method
Signatures
˃ But
preMy
easy
discover
which
method
is
called,
just
show
the
IL
code
J
43. AnE-‐Analysis tricks
-‐ There
are
also
other
kind
of
obfusca:on
like:
-‐ Code
virtualiza:on
-‐ MSIL
Code
encryp:on
(not
so
usefull
to
be
honest…)
-‐ Control-‐Flow
obfusca:on
-‐ …
44. Profile API & Extended ReflecEon
˃ Allow
to
profile
.NET
applica:on
by
intstrumen:ng
the
CLR
˃ Need
to
be
ini:alizated
with
proper
environment
variables
˃ WriMen
in
unmanaged
code
˃ In
order
to
be
used
it
is
prefered
to
create
an
unmanaged
program
L
˃ Microso/
created
a
new
and
poorly
documented
new
project
in
order
to
use
the
profile
API
from
managed
code
˃ Used
in
automata:on
framework
like
Pex/Mole
and
Fakes
to
generate
high
coverege
tests
45. Create your own .NET profiler in managed code
˃ Download
and
install
the
Pex
project
˃ Create
a
new
.NET
solu:on
and
reference
the
Microso*.ExtendedReflec3on.dll
assembly
˃ Implemente
your
custom
Execu3onMonitor
by
extending
the
interested
base
class
methods
˃ Configure
the
Environment
variables
˃ pay
aMen:on
to
this
step,
it
is
here
that
all
magic
happens
˃ Profit!
46. Profile API & Extended ReflecEon
˃ Ok,
we
can
modify
object
value,
but
what
if
we
want
to
change
the
result
of
a
given
method?
˃ The
profile
that
we
created
it
is
a
bit
limited
on
this
˃ We
need
to
subs3tute
the
method
with
our
own
˃ ExtendedReflecTon
support
this
feature
even
if
it
is
not
documented
˃ In
order
to
subs:tue
a
method
you
have
to:
˃ Create
a
method
with
the
same
namespace
of
the
original
method
˃ Implemented
the
subs:tu:on
method
following
a
specific
naming
conven:on
47. Disadvantages
˃ You
need
to
know
the
niMy
griMy
details
of
the
profile
API
and
be
conscious
to
dirty
your
hands
with
.NET
code
˃ At
the
moment
the
ExtendedReflec:on
is
built
only
for
x86
process
L
˃ Don’t
use
the
profile
API
outside
of
a
sandbox!
If
the
profile
API
are
not
able
to
instrument
the
assembly
the
program
will
be
executed
normally.
48. .NET InstrumentaEon
˃ Extended
Reflec:on
doesn’t
seems
to
be
updated
regularly
(last
Pex
release
is
from
2010)
˃ In
order
to
instrument
methods
it
is
used
method
hooking
(for
example
by
using
Detour
library)
˃ Exist
however
other
solu:ons
for
method
instrumenta:on
49. A real world example
˃ Let’s
try
to
reverse
enginnering
a
.NET
malware
˃ The
available
sandboxes
aren’t
able
to
recognize
dynamic
loaded
.NET
assemblies
˃ Tools
of
the
trade
˃ CFF
Explorer
˃ .NET
Reflector
˃ Ildasm
˃ Visual
Studio
50. Demo RE
˃ Let’s
start
by
verifyng
the
PE
Header
˃ CFF
Explorer
tell
us
2
things
˃ It
is
a
.NET
program
(a
WinForm
applica:on
to
be
precise)
˃ The
Method
table
it
is
a
liMle
“strange”
51. Demo RE
˃ Open
the
malware
with
ilDasm
and
digg
a
liMle
through
the
metadata
and
the
IL
code
˃ It
is
a
tandard
Win
GUI
app
˃ The
Main
func:on
it
is
the
real
entrypoint
˃ Time
to
run
reflector
52. Demo RE
Seems
that
the
result
are
loaded
in
list
of
an
array
of
bytes
and
then
analyzed
in
some
way
Also
that
array
of
bytes
it
is
aliMle
suspicious
Let’s
see
the
other
two
defined
func:ons
53. Demo RE
˃ ShiMyMethod
basically
load
all
the
bytes
of
the
resources
in
a
cumula:ve
array
˃ ShiMyMethod2
simply
load
an
Assembly
given
an
array
of
bytes
˃ Seems
that
in
some
way
the
embedded
resources
are
an
obfuscated
.NET
assembly
54. Demo RE
˃ A/er
the
loading
ther
array
of
bytes
are
xored
with
what
seems
to
be
a
decryp:ng
key
˃ Let’s
open
Visual
Studio
and
try
to
˃ Extract
all
the
resources
˃ Compose
the
final
array
of
bytes
˃ Decrypt
it
and
try
to
load
it
as
an
Assembly
55. Demo RE
˃ The
current
resource
extractor
doesn’t
seems
to
work
very
well
˃ They
just
extract
a
big
blob
of
data,
but
we
need
all
the
chunks
in
separated
file
in
order
to
be
composed
˃ Let’s
write
our
.NET
resource
extractor
that
save
all
the
resources
in
a
serialized
base64
way
on
a
given
directory
;)
56. Demo RE
˃ Extracted
the
resource
we
need
to
simulate
the
methods
of
the
malware
and
see
what
happen
˃ This
is
a
preMy
easy
task
(if
you
are
a
programmer
:P)
˃ You
can
see
the
code
that
compose,
decrypt
the
buffer,
and
load
the
assembly
in
class
ExtractKazyLoader
of
the
Solu:on
˃ Let’s
save
the
loaded
assembly
to
file
and
pass
it
to
VirusTotal
˃ We
find
another
malicious
program
that
seems
to
be
the
Trojan
Downloader
KazyLoader
57. Demo RE
˃ Let’s
decompile
the
KazyLoader
˃ We
know
that
the
loader
is
called
with
the
following
command
this.minfo.Invoke(null,
new
object[]
{
Program.ar,
"cAZjxbbBbFhgunT",
"XHAFNkGllgRQKNw",
buffer
});
˃ Where
˃ The
second
argument
is
the
name
of
the
resources
˃ The
third
argument
is
the
name
of
the
resource
item
˃ The
fourth
argument
is
the
buffer
used
to
decrypt
the
KazyLoader
58. Demo RE
˃ The
loader
is
preMy
easy
to
understand
and
to
replicate
˃ Basically
˃ Load
the
remaining
resource
as
a
Bitmap
˃ Decrypt
the
bytes
of
the
bitmap
with
the
key
used
to
decrypt
the
Loader
(With
3DES
and
with
a
custom
XOR)
˃ Load
the
byte
of
the
reversed
array
and
invoke
the
entry
point
func:on
59. Demo RE
˃ The
complete
code
to
extract
the
Assembly
is
in
the
ExtractKazyRootkit
class
of
the
solu:on
˃ Al
always,
let’s
save
the
resul:ng
assembly
and
pass
it
to
VirusTotal
˃ From
the
result
the
new
generated
code
seems
to
be
the
KazyRootkit
60. Demo RE
˃ We
s:ll
have:
˃ Resources
with
encoded
PE
file
˃ Decryp:on
Key
in
resource
˃ Some
an:
emula:on
check
˃ …
˃ I
think
now
you
got
the
point
J
61. Demo RE
˃ Just
one
last
step:
˃ We
decoded
one
last
file
˃ Upload
it
to
VirusTotal
and…
˃ …
here
is
our
Ransomware
J
62. Demo RE
˃ By
running
the
program
in
a
sandbox
we
see
that
it
encrypts
a
bunch
of
files
and
then
redirect
the
user
to
a
payment
site
to
decrypt
them