Bof2 Writing Executable Shellcode
Bof2 Writing Executable Shellcode
NET
Security
Research
Buffer
Overflow
Part
2:
Writing
Executable
Shellcode
Written
By
:
Affix
root@root-the.net
What
is
a
Shellcode?
In
computer
security,
a
shellcode
is
a
small
piece
of
code
used
as
the
payload
in
the
exploitation
of
a
software
vulnerability.
It
is
called
"shellcode"
because
it
typically
starts
a
command
shell
from
which
the
attacker
can
control
the
compromised
machine.
Shellcode
is
commonly
written
in
machine
code,
but
any
piece
of
code
that
performs
a
similar
task
can
be
called
shellcode.
Because
the
function
of
a
payload
is
not
limited
to
merely
spawning
a
shell,
some
have
suggested
that
the
name
shellcode
is
insufficient.
However,
attempts
at
replacing
the
term
have
not
gained
wide
acceptance.
Knowledge
• How
processor
Registers
Work
• Basic
Assembley
Language
• The
Difference
between
32bit
at
64bit
registers
Recommended
Reading
• Buffer
Overflow
Part
1
:
Smashing
the
Stack
2
Right
I’m
ready
lets
go!
Shellcode
Application
In
order
for
us
to
proceed
we
will
need
to
write
a
small
basic
application
that
we
will
use
to
turn
into
shellcode.
We
do
this
by
writing
the
application
in
C
first
then
stripping
out
the
parts
we
do
not
need.
For
example
function
names
etc…
So
here
is
our
basic
application.
#include <stdlib.h>
void main()
{
exit(0);
}
Hey
as
I
said
it
doesn’t
need
to
be
advanced
or
anything.
It
just
needs
to
work.
This
is
going
to
be
an
exit
shellcode.
I
know
it
is
useless
to
some
people
but
others
may
like
it.
So
now
we
need
to
statically
compile
it
with
GCC.
[Affix@localhost bof2]$ gcc -static exit.c -o exit
The
reason
we
use
the
static
switch
is
so
the
libraries
are
directly
linked
to
the
application.
You
can
do
a
test
run
of
this
application
if
you
wish
but
its
kind
of
useless
it
will
just
exit.
Disassembly!
Now
we
need
to
disassemble
our
functions
to
get
how
Assembly
code.
Open
up
exit
in
gdb
[Affix@localhost bof2]$ gdb exit
3
Ok
now
we
will
disassemble
our
main
function
(gdb) disas main
Dump of assembler code for function main:
0x080482bc <+0>: push %ebp
0x080482bd <+1>: mov %esp,%ebp
0x080482bf <+3>: and $0xfffffff0,%esp
0x080482c2 <+6>: sub $0x10,%esp
0x080482c5 <+9>: movl $0x0,(%esp)
0x080482cc <+16>: call 0x8048e40 <exit>
End of assembler dump.
All
of
the
above
isn’t
needed,
The
highlighted
a
line
above
is
what
we
really
need
to
pay
attention
to.
This
is
calling
the
exit
routine.
So
now
lets
disassemble
_exit
(gdb) disas _exit
Dump of assembler code for function _exit:
0x08053360 <+0>: mov 0x4(%esp),%ebx
0x08053364 <+4>: mov $0xfc,%eax
0x08053369 <+9>: call *0x80d25e4
0x0805336f <+15>: mov $0x1,%eax
0x08053374 <+20>: int $0x80
0x08053376 <+22>: hlt
End of assembler dump.
Ok
this
is
the
_exit
function,
Again
we
do
not
need
all
of
this
code.
Notice
that
I
have
highlighted
2
lines.
These
are
the
lines
we
wish
to
look
at
in
a
little
more
detail.
Lets
start
with
the
Green.
0x08053364 <+4>: mov $0xfc,%eax
we
see
this
is
moving
$0xfc
into
the
eax
register.
$0xfc
in
hex
is
252
this
calls
the
exit_group
system
call.
If
we
look
at
exit_group
in
man
we
come
up
with
this.
DESCRIPTION
This system call is equivalent to exit(2) except that it
terminates not only the present thread, but all threads in the
current thread group.
This
is
simply
the
exit
system
call.
Lets
check
its
man
page
DESCRIPTION
The function _exit() terminates the calling process
"immediately". Any open file descriptors belonging to the
process are closed; any children of the process are inherited
by process 1, init, and the process’s parent is sent a SIGCHLD
signal.
4
The
following
code
is
what
we
don’t
need
so
we
can
simply
discard
this.
0x08053364 <+4>: mov $0xfc,%eax
0x08053369 <+9>: call *0x80d25e4
_start :
mov $20, %ebx
mov $1, %eax
int $0x80
Fairly
simple.
If
you
do
not
understand
assembly
language
I
recommend
researching
a
little
to
find
out
what
all
the
above
means.
Now
we
have
compiled
out
ELF-‐executable.
Feel
Free
to
test
it.
But
again
it
will
just
exit.
So
how
do
we
get
this
as
ShellCode
we
are
used
to.
Well
we
need
to
get
it
in
MachineCode.
This
is
done
using
the
Object
Dump
utility.
it
should
be
installed
by
default
on
most
Unix
/
Linux
based
Systems.
[root@affix bof2]# objdump -d ExitCode
0000000000400078 <_start>:
400078: bb 14 00 00 00 mov $0x14,%ebx
40007d: b8 01 00 00 00 mov $0x1,%eax
400082: cd 80 int $0x80
Well
now
we
see
some
HEX
Code.
These
are
Known
as
OpCodes.
The
first
Byte
we
see
(bb
on
the
first
line)
is
our
instruction
code.
Followed
by
4
bytes.
These
4
bytes
are
the
values
to
pass
to
the
instruction.
5
To
define
the
ShellCode
in
an
application
simply
we
set
it
as
a
character
array.
Remember
these
are
HEX
Values
so
we
need
to
use
\x
#include <stdio.h>
char ShellCode[] = "\xbb\x14\x00\x00\x00"
"\xb8\x01\x00\x00\x00"
"\xcd\x80"
int main()
{
return 0;
}
You
can
compile
this
if
you
wish
but
it
will
return
nothing.
FAQ
Q
–
Will
this
work
on
64bit
systems?
A
–
The
process
is
basically
the
same
However
the
example
assembled
code
and
opcodes
will
only
function
on
32
bit
systems.
6