Memory safety and vulnerabilities: attacks and defenses
1. So$ware
Security
(I):
Buffer-‐overflow
A8acks
Computer
Security
Course.
Dawn
Song
Dawn
Song
1
2. Intro
SERVER
CLIENT
HTTP REQUEST
HTTP RESPONSE
EXPLOIT
Remote
Shell
CLIENT
ATTACKER
Dawn
Song
2
3. Linux
(32-‐bit)
process
memory
layout
Reserved
for
Kernal
user
stack
shared
libraries
run
9me
heap
sta9c
data
segment
text
segment
(program)
unused
-0xC0000000
-0x40000000
-0x08048000
%esp
brk
Loaded
from
exec
-0x00000000
-0xFFFFFFFF
4. Stack
Frame
user
stack
shared
libraries
run
9me
heap
sta9c
data
segment
text
segment
(program)
unused
-0xC0000000
-0x40000000
-0x08048000
-0x00000000
arguments
return
address
stack
frame
pointer
excep9on
handlers
local
variables
callee
saved
registers
To
previous
stack
frame
pointer
To
the
point
at
which
this
funcTon
was
called
5. Stack
Frame
9:int
parse(FILE
*fp)
{
10:
char
buf[5],
*url,
cmd[128];
11:
fread(cmd,
1,
128,
fp);
12:
int
header_ok
=
0;
13:
if
(cmd[0]
==
‘G’)
14:
if
(cmd[1]
==
‘E’)
15:
if
(cmd[2]
==
‘T’)
16:
if
(cmd[3]
==
‘
’)
17:
header_ok
=
1;
18:
if
(!header_ok)
return
-‐1;
19:
url
=
cmd
+
4;
20:
copy_lower(url,
buf);
21:
printf(“Location
is
%sn”,
buf);
22:
return
0;
}
1:void
copy_lower
(char*
in,
char*
out)
{
2:
int
i
=
0;
3:
while
(in[i]!=‘0’
&&
in[i]!=‘n’)
{
4:
out[i]
=
tolower(in[i]);
5:
i++;
6:
}
7:
buf[i]
=
‘0’;
8:}
A
quick
example
to
illustrate
mul9ple
stack
frames
6. Viewing
Stack
Frame
with
GDB
9:int
parse(FILE
*fp)
{
10:
char
buf[5],
*url,
cmd[128];
11:
fread(cmd,
1,
128,
fp);
12:
int
header_ok
=
0;
13:
if
(cmd[0]
==
‘G’)
14:
if
(cmd[1]
==
‘E’)
15:
if
(cmd[2]
==
‘T’)
16:
if
(cmd[3]
==
‘
’)
17:
header_ok
=
1;
18:
if
(!header_ok)
return
-‐1;
19:
url
=
cmd
+
4;
20:
copy_lower(url,
buf);
21:
printf(“Location
is
%sn”,
buf);
22:
return
0;
}
1:void
copy_lower
(char*
in,
char*
out)
{
2:
int
i
=
0;
3:
while
(in[i]!=‘0’
&&
in[i]!=‘n’)
{
4:
out[i]
=
tolower(in[i]);
5:
i++;
6:
}
7:
buf[i]
=
‘0’;
8:}
gcc –g parse.c –o parse
Compile:
./parse
Run:
We
can
debug
using
gdb.
gdb parse
Then
we
can
take
a
look
at
the
stack.
(gdb) break 7
(gdb) run
(gdb) x/64x $esp
Debug:
23:
/**
main
to
load
a
file
and
run
parse
*/
Our
example
modified
to
include
a
main
func9on
parse.c
7. Viewing
Stack
Frame
with
GDB
(gdb) x/64x $esp
Debug:
Our
running
example
modified
to
illustrate
mul9ple
stack
frames
parse.c
8. What
are
buffer
overflows?
args!
ret address!
frame ptr!
!
!
!
local
variables!
!
!
!
!
callee saved
registers!
(Unallocated)
9:int
parse(FILE
*fp)
{
10:
char
buf[5],
*url,
cmd[128];
11:
fread(cmd,
1,
256,
fp);
12:
int
header_ok
=
0;
.
.
.
19:
url
=
cmd
+
4;
20:
copy_lower(url,
buf);
21:
printf(“Location
is
%sn”,
buf);
22:
return
0;
}
1:void
copy_lower
(char*
in,
char*
out)
{
2:
int
i
=
0;
3:
while
(in[i]!=‘0’
&&
in[i]!=‘n’)
{
4:
out[i]
=
tolower(in[i]);
5:
i++;
6:
}
7:
buf[i]
=
‘0’;
8:}
23:
/**
main
to
load
a
file
and
run
parse
*/
parse.c
file
GET
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
(input
file)
args!
ret address!
frame ptr!
local variables!
callee saved
registers!
fp
return
address
stack
frame
ptr
url
header_ok
buf[4]
buf[3,2,1,0]
cmd[128,127,126,125]
.
.
.
cmd[7,6,5,4]
cmd[3,2,1,0]
0xbffff75c
0xbffff758
0xbffff74c
0xbffff748
0xbffff744
0xbffff740
0xbffff73c
.
.
.
0xbffff6c4
0xbffff6c0
0x0804a008!
0x080485a2!
0xbffff778!
0xbffff6c4!
0x00000001!
0xbfef20dc!
0xbf02224c!
0x00000000!
.!
.!
.!
0x41414141!
0x20544547!
!
!
0xbffff760
in
return
address
stack
frame
ptr
i
0xbffff740!
0xbffff6c4!
0x080485a2!
0xbffff758!
0x00000000!
out
0xbffff6b4
0xbffff6b0
0xbffff6ac
0xbffff6a8
0xbffff69c
copy_lower’s
frame
parse’s
frame
9. What
are
buffer
overflows?
fp
return
address
stack
frame
ptr
url
header_ok
buf[4]
buf[3,2,1,0]
cmd[128,127,126,125]
.
.
.
cmd[7,6,5,4]
cmd[3,2,1,0]
0xbffff75c
0xbffff758
0xbffff74c
0xbffff748
0xbffff744
0xbffff740
0xbffff73c
.
.
.
0xbffff6c4
0xbffff6c0
in
return
address
stack
frame
ptr
i
0x0804a008!
0x080485a2!
0xbffff778!
0xbffff6c4!
0x00000001!
0xbfef20dc!
0xbf022261!
0x00000000!
.!
.!
.!
0x41414141!
0x20544547!
!
!
(Unallocated)
0xbffff740!
0xbffff6c4!
0x080485a2!
0xbffff758!
0x00000000!
out
0xbffff6b4
0xbffff6b0
0xbffff6ac
0xbffff6a8
0xbffff69c
9:int
parse(FILE
*fp)
{
10:
char
buf[5],
*url,
cmd[128];
11:
fread(cmd,
1,
256,
fp);
12:
int
header_ok
=
0;
.
.
.
19:
url
=
cmd
+
4;
20:
copy_lower(url,
buf);
21:
printf(“Location
is
%sn”,
buf);
22:
return
0;
}
1:void
copy_lower
(char*
in,
char*
out)
{
2:
int
i
=
0;
3:
while
(in[i]!=‘0’
&&
in[i]!=‘n’)
{
4:
out[i]
=
tolower(in[i]);
5:
i++;
6:
}
7:
buf[i]
=
‘0’;
8:}
23:
/**
main
to
load
a
file
and
run
parse
*/
parse.c
0xbffff760
file
GET
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
(input
file)
10. What
are
buffer
overflows?
fp
return
address
stack
frame
ptr
url
header_ok
buf[4]
buf[3,2,1,0]
cmd[128,127,126,125]
.
.
.
cmd[7,6,5,4]
cmd[3,2,1,0]
0xbffff75c
0xbffff758
0xbffff74c
0xbffff748
0xbffff744
0xbffff740
0xbffff73c
.
.
.
0xbffff6c4
0xbffff6c0
in
return
address
stack
frame
ptr
i
0x0804a008!
0x080485a2!
0xbffff778!
0xbffff6c4!
0x00000001!
0xbfef20dc!
0xbf026161!
0x00000000!
.!
.!
.!
0x41414141!
0x20544547!
!
!
(Unallocated)
0xbffff740!
0xbffff6c4!
0x080485a2!
0xbffff758!
0x00000001!
out
0xbffff6b4
0xbffff6b0
0xbffff6ac
0xbffff6a8
0xbffff69c
9:int
parse(FILE
*fp)
{
10:
char
buf[5],
*url,
cmd[128];
11:
fread(cmd,
1,
256,
fp);
12:
int
header_ok
=
0;
.
.
.
19:
url
=
cmd
+
4;
20:
copy_lower(url,
buf);
21:
printf(“Location
is
%sn”,
buf);
22:
return
0;
}
1:void
copy_lower
(char*
in,
char*
out)
{
2:
int
i
=
0;
3:
while
(in[i]!=‘0’
&&
in[i]!=‘n’)
{
4:
out[i]
=
tolower(in[i]);
5:
i++;
6:
}
7:
buf[i]
=
‘0’;
8:}
23:
/**
main
to
load
a
file
and
run
parse
*/
parse.c
0xbffff760
file
GET
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
(input
file)
11. What
are
buffer
overflows?
fp
return
address
stack
frame
ptr
url
header_ok
buf[4]
buf[3,2,1,0]
cmd[128,127,126,125]
.
.
.
cmd[7,6,5,4]
cmd[3,2,1,0]
0xbffff75c
0xbffff758
0xbffff74c
0xbffff748
0xbffff744
0xbffff740
0xbffff73c
.
.
.
0xbffff6c4
0xbffff6c0
in
return
address
stack
frame
ptr
i
0x0804a008!
0x080485a2!
0xbffff778!
0xbffff6c4!
0x00000001!
0xbfef20dc!
0xbf616161!
0x00000000!
.!
.!
.!
0x41414141!
0x20544547!
!
!
(Unallocated)
0xbffff740!
0xbffff6c4!
0x080485a2!
0xbffff758!
0x00000002!
out
0xbffff6b4
0xbffff6b0
0xbffff6ac
0xbffff6a8
0xbffff69c
9:int
parse(FILE
*fp)
{
10:
char
buf[5],
*url,
cmd[128];
11:
fread(cmd,
1,
256,
fp);
12:
int
header_ok
=
0;
.
.
.
19:
url
=
cmd
+
4;
20:
copy_lower(url,
buf);
21:
printf(“Location
is
%sn”,
buf);
22:
return
0;
}
1:void
copy_lower
(char*
in,
char*
out)
{
2:
int
i
=
0;
3:
while
(in[i]!=‘0’
&&
in[i]!=‘n’)
{
4:
out[i]
=
tolower(in[i]);
5:
i++;
6:
}
7:
buf[i]
=
‘0’;
8:}
23:
/**
main
to
load
a
file
and
run
parse
*/
parse.c
0xbffff760
file
GET
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
(input
file)
12. What
are
buffer
overflows?
fp
return
address
stack
frame
ptr
url
header_ok
buf[4]
buf[3,2,1,0]
cmd[128,127,126,125]
.
.
.
cmd[7,6,5,4]
cmd[3,2,1,0]
0xbffff75c
0xbffff758
0xbffff74c
0xbffff748
0xbffff744
0xbffff740
0xbffff73c
.
.
.
0xbffff6c4
0xbffff6c0
in
return
address
stack
frame
ptr
i
0x0804a008!
0x080485a2!
0xbffff778!
0xbffff6c4!
0x00000001!
0xbfef20dc!
0x61616161!
0x00000000!
.!
.!
.!
0x41414141!
0x20544547!
!
!
(Unallocated)
0xbffff740!
0xbffff6c4!
0x080485a2!
0xbffff758!
0x00000003!
out
0xbffff6b4
0xbffff6b0
0xbffff6ac
0xbffff6a8
0xbffff69c
9:int
parse(FILE
*fp)
{
10:
char
buf[5],
*url,
cmd[128];
11:
fread(cmd,
1,
256,
fp);
12:
int
header_ok
=
0;
.
.
.
19:
url
=
cmd
+
4;
20:
copy_lower(url,
buf);
21:
printf(“Location
is
%sn”,
buf);
22:
return
0;
}
1:void
copy_lower
(char*
in,
char*
out)
{
2:
int
i
=
0;
3:
while
(in[i]!=‘0’
&&
in[i]!=‘n’)
{
4:
out[i]
=
tolower(in[i]);
5:
i++;
6:
}
7:
buf[i]
=
‘0’;
8:}
23:
/**
main
to
load
a
file
and
run
parse
*/
parse.c
0xbffff760
file
GET
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
(input
file)
13. What
are
buffer
overflows?
fp
return
address
stack
frame
ptr
url
header_ok
buf[4]
buf[3,2,1,0]
cmd[128,127,126,125]
.
.
.
cmd[7,6,5,4]
cmd[3,2,1,0]
0xbffff75c
0xbffff758
0xbffff74c
0xbffff748
0xbffff744
0xbffff740
0xbffff73c
.
.
.
0xbffff6c4
0xbffff6c0
in
return
address
stack
frame
ptr
i
0x0804a008!
0x080485a2!
0xbffff778!
0xbffff6c4!
0x00000001!
0xbfef2061!
0x61616161!
0x00000000!
.!
.!
.!
0x41414141!
0x20544547!
!
!
(Unallocated)
0xbffff740!
0xbffff6c4!
0x080485a2!
0xbffff758!
0x00000004!
out
0xbffff6b4
0xbffff6b0
0xbffff6ac
0xbffff6a8
0xbffff69c
9:int
parse(FILE
*fp)
{
10:
char
buf[5],
*url,
cmd[128];
11:
fread(cmd,
1,
256,
fp);
12:
int
header_ok
=
0;
.
.
.
19:
url
=
cmd
+
4;
20:
copy_lower(url,
buf);
21:
printf(“Location
is
%sn”,
buf);
22:
return
0;
}
1:void
copy_lower
(char*
in,
char*
out)
{
2:
int
i
=
0;
3:
while
(in[i]!=‘0’
&&
in[i]!='n')
{
4:
out[i]
=
tolower(in[i]);
5:
i++;
6:
}
7:
buf[i]
=
‘0’;
8:}
23:
/**
main
to
load
a
file
and
run
parse
*/
parse.c
0xbffff760
file
GET
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
(input
file)
14. What
are
buffer
overflows?
fp
return
address
stack
frame
ptr
url
header_ok
buf[4]
buf[3,2,1,0]
cmd[128,127,126,125]
.
.
.
cmd[7,6,5,4]
cmd[3,2,1,0]
0xbffff75c
0xbffff758
0xbffff74c
0xbffff748
0xbffff744
0xbffff740
0xbffff73c
.
.
.
0xbffff6c4
0xbffff6c0
in
return
address
stack
frame
ptr
i
0x0804a008!
0x080485a2!
0xbffff778!
0xbffff6c4!
0x00000001!
0xbfef6161!
0x61616161!
0x00000000!
.!
.!
.!
0x41414141!
0x20544547!
!
!
(Unallocated)
0xbffff740!
0xbffff6c4!
0x080485a2!
0xbffff758!
0x00000005!
out
0xbffff6b4
0xbffff6b0
0xbffff6ac
0xbffff6a8
0xbffff69c
9:int
parse(FILE
*fp)
{
10:
char
buf[5],
*url,
cmd[128];
11:
fread(cmd,
1,
256,
fp);
12:
int
header_ok
=
0;
.
.
.
19:
url
=
cmd
+
4;
20:
copy_lower(url,
buf);
21:
printf(“Location
is
%sn”,
buf);
22:
return
0;
}
1:void
copy_lower
(char*
in,
char*
out)
{
2:
int
i
=
0;
3:
while
(in[i]!=‘0’
&&
in[i]!='n')
{
4:
out[i]
=
tolower(in[i]);
5:
i++;
6:
}
7:
buf[i]
=
‘0’;
8:}
23:
/**
main
to
load
a
file
and
run
parse
*/
parse.c
0xbffff760
file
GET
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
(input
file)
Uh
oh….
15. What
are
buffer
overflows?
fp
return
address
stack
frame
ptr
url
header_ok
buf[4]
buf[3,2,1,0]
cmd[128,127,126,125]
.
.
.
cmd[7,6,5,4]
cmd[3,2,1,0]
0xbffff75c
0xbffff758
0xbffff74c
0xbffff748
0xbffff744
0xbffff740
0xbffff73c
.
.
.
0xbffff6c4
0xbffff6c0
in
return
address
stack
frame
ptr
i
0x0804a008!
0x080485a2!
0xbffff778!
0xbffff6c4!
0x00000001!
0xbf616161!
0x61616161!
0x00000000!
.!
.!
.!
0x41414141!
0x20544547!
!
!
(Unallocated)
0xbffff740!
0xbffff6c4!
0x080485a2!
0xbffff758!
0x00000005!
out
0xbffff6b4
0xbffff6b0
0xbffff6ac
0xbffff6a8
0xbffff69c
9:int
parse(FILE
*fp)
{
10:
char
buf[5],
*url,
cmd[128];
11:
fread(cmd,
1,
256,
fp);
12:
int
header_ok
=
0;
.
.
.
19:
url
=
cmd
+
4;
20:
copy_lower(url,
buf);
21:
printf(“Location
is
%sn”,
buf);
22:
return
0;
}
1:void
copy_lower
(char*
in,
char*
out)
{
2:
int
i
=
0;
3:
while
(in[i]!=‘0’
&&
in[i]!='n')
{
4:
out[i]
=
tolower(in[i]);
5:
i++;
6:
}
7:
buf[i]
=
‘0’;
8:}
23:
/**
main
to
load
a
file
and
run
parse
*/
parse.c
0xbffff760
file
GET
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
(input
file)
Uh
oh….
16. What
are
buffer
overflows?
fp
return
address
stack
frame
ptr
url
header_ok
buf[4]
buf[3,2,1,0]
cmd[128,127,126,125]
.
.
.
cmd[7,6,5,4]
cmd[3,2,1,0]
0xbffff75c
0xbffff758
0xbffff74c
0xbffff748
0xbffff744
0xbffff740
0xbffff73c
.
.
.
0xbffff6c4
0xbffff6c0
in
return
address
stack
frame
ptr
i
0x0804a008!
0x080485a2!
0xbffff778!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x00000000!
.!
.!
.!
0x41414141!
0x20544547!
!
!
(Unallocated)
0xbffff740!
0xbffff6c4!
0x080485a2!
0xbffff758!
0x0000000d!
out
0xbffff6b4
0xbffff6b0
0xbffff6ac
0xbffff6a8
0xbffff69c
parse.c
0xbffff760
file
GET
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
(input
file)
Uh
oh….
9:int
parse(FILE
*fp)
{
10:
char
buf[5],
*url,
cmd[128];
11:
fread(cmd,
1,
256,
fp);
12:
int
header_ok
=
0;
.
.
.
19:
url
=
cmd
+
4;
20:
copy_lower(url,
buf);
21:
printf(“Location
is
%sn”,
buf);
22:
return
0;
}
1:void
copy_lower
(char*
in,
char*
out)
{
2:
int
i
=
0;
3:
while
(in[i]!=‘0’
&&
in[i]!='n')
{
4:
out[i]
=
tolower(in[i]);
5:
i++;
6:
}
7:
buf[i]
=
‘0’;
8:}
23:
/**
main
to
load
a
file
and
run
parse
*/
17. What
are
buffer
overflows?
fp
return
address
stack
frame
ptr
url
header_ok
buf[4]
buf[3,2,1,0]
cmd[128,127,126,125]
.
.
.
cmd[7,6,5,4]
cmd[3,2,1,0]
0xbffff75c
0xbffff758
0xbffff74c
0xbffff748
0xbffff744
0xbffff740
0xbffff73c
.
.
.
0xbffff6c4
0xbffff6c0
in
return
address
stack
frame
ptr
i
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x00000000!
.!
.!
.!
0x41414141!
0x20544547!
!
!
(Unallocated)
0xbffff740!
0xbffff6c4!
0x080485a2!
0xbffff758!
0x00000019!
out
0xbffff6b4
0xbffff6b0
0xbffff6ac
0xbffff6a8
0xbffff69c
parse.c
0xbffff760
file
GET
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
(input
file)
Uh
oh….
9:int
parse(FILE
*fp)
{
10:
char
buf[5],
*url,
cmd[128];
11:
fread(cmd,
1,
256,
fp);
12:
int
header_ok
=
0;
.
.
.
19:
url
=
cmd
+
4;
20:
copy_lower(url,
buf);
21:
printf(“Location
is
%sn”,
buf);
22:
return
0;
}
1:void
copy_lower
(char*
in,
char*
out)
{
2:
int
i
=
0;
3:
while
(in[i]!=‘0’
&&
in[i]!='n')
{
4:
out[i]
=
tolower(in[i]);
5:
i++;
6:
}
7:
buf[i]
=
‘0’;
8:}
23:
/**
main
to
load
a
file
and
run
parse
*/
18. What
are
buffer
overflows?
fp
return
address
stack
frame
ptr
url
header_ok
buf[4]
buf[3,2,1,0]
cmd[128,127,126,125]
.
.
.
cmd[7,6,5,4]
cmd[3,2,1,0]
0xbffff75c
0xbffff758
0xbffff74c
0xbffff748
0xbffff744
0xbffff740
0xbffff73c
.
.
.
0xbffff6c4
0xbffff6c0
in
return
address
stack
frame
ptr
i
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x00000000!
.!
.!
.!
0x41414141!
0x20544547!
!
!
(Unallocated)
0xbffff740!
0xbffff6c4!
0x080485a2!
0xbffff758!
0x00000025!
out
0xbffff6b4
0xbffff6b0
0xbffff6ac
0xbffff6a8
0xbffff69c
parse.c
0xbffff760
file
GET
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
(input
file)
Uh
oh….
9:int
parse(FILE
*fp)
{
10:
char
buf[5],
*url,
cmd[128];
11:
fread(cmd,
1,
256,
fp);
12:
int
header_ok
=
0;
.
.
.
19:
url
=
cmd
+
4;
20:
copy_lower(url,
buf);
21:
printf(“Location
is
%sn”,
buf);
22:
return
0;
}
1:void
copy_lower
(char*
in,
char*
out)
{
2:
int
i
=
0;
3:
while
(in[i]!=‘0’
&&
in[i]!='n')
{
4:
out[i]
=
tolower(in[i]);
5:
i++;
6:
}
7:
buf[i]
=
‘0’;
8:}
23:
/**
main
to
load
a
file
and
run
parse
*/
19. What
are
buffer
overflows?
fp
return
address
stack
frame
ptr
url
header_ok
buf[4]
buf[3,2,1,0]
cmd[128,127,126,125]
.
.
.
cmd[7,6,5,4]
cmd[3,2,1,0]
0xbffff75c
0xbffff758
0xbffff74c
0xbffff748
0xbffff744
0xbffff740
0xbffff73c
.
.
.
0xbffff6c4
0xbffff6c0
in
return
address
stack
frame
ptr
i
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x00000000!
.!
.!
.!
0x41414141!
0x20544547!
0xbffff6c4!
0x00000001!
(Unallocated)
0xbffff740!
0xbffff6c4!
0x080485a2!
0xbffff758!
0x00000025!
out
0xbffff6b4
0xbffff6b0
0xbffff6ac
0xbffff6a8
0xbffff69c
9:int
parse(FILE
*fp)
{
10:
char
buf[5],
*url,
cmd[128];
11:
fread(cmd,
1,
256,
fp);
12:
int
header_ok
=
0;
.
.
.
19:
url
=
cmd
+
4;
20:
copy_lower(url,
buf);
21:
printf(“Location
is
%sn”,
buf);
22:
return
0;
}
1:void
copy_lower
(char*
in,
char*
out)
{
2:
int
i
=
0;
3:
while
(in[i]!=‘0’
&&
in[i]!='n')
{
4:
out[i]
=
tolower(in[i]);
5:
i++;
6:
}
7:
buf[i]
=
‘0’;
8:}
23:
/**
main
to
load
a
file
and
run
parse
*/
parse.c
0xbffff760
file
GET
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
(input
file)
And
when
you
try
to
return
from
parse…
…
SEGFAULT,
since
0x61616161
is
not
a
valid
locaTon
to
return
to.
20. Basic
Stack
Exploit
• OverwriTng
the
return
address
allows
an
a8acker
to
redirect
the
flow
of
program
control
• Instead
of
crashing,
this
can
allow
arbitrary
code
to
be
executed
– Code
segment
called
“shellcode”
• Example:
the
execve
system
call
is
used
to
execute
a
file
– With
the
correct
permissions,
execve(“/bin/sh”)
can
be
used
to
obtain
a
root-‐level
shell.
Dawn
Song
20
21. Shellcode
of
execve
• How
to
develop
shellcode
that
runs
as
execve(“/bin/sh”)?
void
main()
{
char
*name[2];
name[0]
=
"/bin/sh";
name[1]
=
NULL;
execve(name[0],
name,
NULL);
}
0x80002bc
<__execve>:
pushl
%ebp
0x80002bd
<__execve+1>:
movl
%esp,%ebp
0x80002bf
<__execve+3>:
pushl
%ebx
The
procedure
prelude.
0x80002c0
<__execve+4>:
movl
$0xb,%eax
Copy
0xb
(11
decimal)
onto
the
stack.
This
is
the
index
into
the
syscall
table.
11
is
execve.
0x80002c5
<__execve+9>:
movl
0x8(%ebp),%ebx
Copy
the
address
of
"/bin/sh"
into
EBX.
0x80002c8
<__execve+12>:
movl
0xc(%ebp),%ecx
Copy
the
address
of
name[]
into
ECX.
0x80002cb
<__execve+15>:
movl
0x10(%ebp),%edx
Copy
the
address
of
the
null
pointer
into
%edx.
0x80002ce
<__execve+18>:
int
$0x80
Change
into
kernel
mode.
(disassembly
of
execve
call)*
(format
instrucTons
and
data
as
characters)*
*For
more
details,
refer
to
Smashing
the
stack
by
aleph
one
“xebx1fx5e
x89x76x08x31xc0x88x46x46x0cxb0x0b
x89xf3x8dx4ex08x8dx56x0cxcd
x80x31xdbx89xd8x40xcdx80xe8xdcxff
xffxff/bin/sh”
Dawn
Song
21
22. arguments
return
address
stack
frame
pointer
buffer
ShellCode
craZed
return
address
buffer
Basic
Stack
Exploit
To
previous
stack
frame
pointer
To
the
instrucTon
at
which
this
funcTon
was
called
“xebx1fx5ex89x76x08x31xc0x88x46x46x0cxb0x0bx89xf3x8dx4ex08x8dx56x0cxcd
x80x31xdbx89xd8x40xcdx80xe8xdcxffxffxff/bin/sh”
So
suppose
we
overflow
with
a
string
that
looks
like
the
assembly
of:
Shell
Code:
exec(“/bin/sh”)
(exact
shell
code
by
Aleph
One)
When
the
funcTon
exits,
the
user
gets
shell
!!!
Note:
shellcode
runs
in
stack.
arguments
return
address
stack
frame
pointer
buffer
To
previous
stack
frame
pointer
To
the
instrucTon
at
which
this
funcTon
was
called
31. More
on
Stack
Smashing
• Some
complicaTons
on
Shellcode:
– Overflow
should
not
crash
program
before
the
frame’s
funcTon
exits
– Shellcode
may
not
contain
the
‘0’
character
if
copied
using
strcpy
funcTons.
• Sample
remote
stack
smashing
overflows:
– (2007)
Overflow
in
Windows
animated
cursors
(ANI)
– (2005)
Overflow
in
SymanTc
Virus
DetecTon
Dawn
Song
31
32. Many
unsafe
libc
funcTons
strcpy
(char
*dest,
const
char
*src)
strcat
(char
*de
st,
const
char
*src)
gets
(char
*s)
scanf
(
const
char
*format,
…
)
and
many
more.
• “Safe”
libc
versions
strncpy(),
strncat()
are
misleading
– e.g.
strncpy()
may
leave
string
unterminated.
• Windows
C
run
Tme
(CRT):
– strcpy_s
(*dest,
DestSize,
*src):
ensures
proper
terminaTon
33. arguments
return
address
stack
frame
pointer
buffer
ShellCode
craZed
return
address
buffer
To
previous
stack
frame
pointer
To
the
instrucTon
at
which
this
funcTon
was
called
arguments
return
address
stack
frame
pointer
buffer
General
Control
Hijacking:
Return
Address
Overwrite
Step:
Overwrite
return
address
to
point
to
your
code.
Ac9vate
Step:
Return
out
of
frame
and
into
your
code.
Dawn
Song
33
34. arguments
return
address
stack
frame
pointer
local
funcTon
pointer
buffer
ShellCode
craZed
local
func9on
pointer
buffer
To
instrucTons
for
a
funcTon
arguments
return
address
stack
frame
pointer
local
funcTon
pointer
buffer
General
Control
Hijacking:
Local
Fn
Ptr
Overwrite
Step:
Overwrite
local
funcTon
pointer
to
point
to
your
code.
Ac9vate
Step:
Call
that
local
funcTon
variable.
Dawn
Song
34
35. General
Control
Hijacking:
FuncTon
Pointer
in
the
Heap
Overwrite
Step:
Overwrite
entries
in
a
vtable
for
Object
T.
Ac9vate
Step:
Call
any
method
from
Object
T
ptr
data
Object
T
FP1:
FP2:
FP3:
buffer
vtable
method
#1
method
#2
method
#3
ptr
data
Object
T
FP1:
FP2:
FP3:
buffer
vtable
method
#1
method
#2
method
#3
ptr
data
Object
T
craZed
FP1:
craZed
FP2:
craZed
FP3:
buffer
vtable
shellcode
shellcode
shellcode
Dawn
Song
35
36. General
Control
Hijacking:
FuncTon
Pointer
in
the
Heap
Overwrite
Step:
Overwrite
pointer
to
vtable
on
heap
to
point
to
a
cra$ed
vtable.
Ac9vate
Step:
Call
any
method
from
Object
T
ptr
data
buffer
Object
T
FP1:
FP2:
FP3:
vtable
method
#1
method
#2
method
#3
ptr
data
buffer
FP1:
FP2:
FP3:
craZed
FP1:
cra$ed
FP2:
cra$ed
FP3:
cra$ed
ptr
buffer
vtable
method
#1
method
#2
method
#3
shellcode
shellcode
shellcode
(craZed
vtable)
Dawn
Song
36
37. A8ack:
return-‐to-‐libc
(arc
injecTon)
• Control
hijacking
without
execuTng
code
arguments
return
address
stack
frame
pointer
buffer
(stack)
exec()
prinf()
“/bin/shell”
(libc.so)
Dawn
Song
37
38.
General
Control
Hijacking
Control
Flow
Pointer
jump
to
address
longjmp
pointer
funcTon
pointer
in
heap
return
address
frame
pointer
excepTon
Handler
funcTon
pointer
as
local
variable
shellcode,
library
(return
to
libc)
Overwrite
Step:
Find
some
way
to
modify
a
Control
Flow
Pointer
to
point
to
your
shellcode,
library
entry
point,
or
other
code
of
interest.
Ac9vate
Step:
Find
some
way
to
ac9vate
that
modified
Control
Flow
Pointer.
expected
code
Dawn
Song
38
39. Instances
of
Control
Hijacking
Loca9on
in
Memory
Control
Flow
Pointer
How
to
ac9vate
Stack
Return
Address
Return
from
funcTon
Stack
Frame
Pointer
Return
from
funcTon
Stack
FuncTon
Pointers
as
local
variables
Reference
and
call
funcTon
pointer
Stack
ExcepTon
Handler
Trigger
ExcepTon
Heap
FuncTon
pointer
in
heap
(i.e.
method
of
an
object)
Reference
and
call
funcTon
pointer
Anywhere
setjmp
and
longjmp
program
state
buffer
Call
longjmp
Ret
Addr
Frame
Ptr
buf
(stack
frame)
excepTon
handers
local
fn
ptrs
ptr
data
Object
T
FP1:
FP2:
FP3:
vtable
method
#1
method
#2
method
#3
(HEAP)
buf
saved
pointer
…
other
data
longjmp
buf
ptr
data
Object
T
FP1:
FP2:
FP3:
vtable
method
#1
method
#2
method
#3
(HEAP)
buf
Dawn
Song
39
40. arguments
return
address
stack
frame
pointer
authenTcaTon_variable
buffer
Data
Hijacking
Dawn
Song
40
Normal
Situa9on:
User
types
in
a
password
which
is
stored
in
the
buffer,
and
if
the
user
is
successfully
authenTcated,
the
authenTcaTon_variable
is
set.
Modifying
data
in
a
way
not
intended
Example:
AuthenTcaTon
variable
arguments
return
address
stack
frame
pointer
authenTcaTon_variable
buffer
Exploited
Situa9on:
User
types
in
a
password
which
is
long
enough
to
overflow
buffer
and
into
the
authenTcaTon_variable.
The
user
is
now
unintenTonally
authenTcated.
arguments
return
address
stack
frame
pointer
authenTcaTon_variable
buffer
41. So$ware
Security
(II):
Other
types
of
so$ware
vulnerabiliTes
Computer
Security
Course.
Dawn
Song
Dawn
Song
41
42. Common
Coding
Errors
• Input
validaTon
vulnerabiliTes
• Memory
management
vulnerabiliTes
• TOCTTOU
vulnerabiliTes
Dawn
Song
42
43. Input
validaTon
vulnerabiliTes
• Program
requires
certain
assumpTons
on
inputs
to
run
properly
• Without
correct
checking
for
inputs
– Program
gets
exploited
• Example:
– Buffer
overflow
– Format
string
Dawn
Song
43
44. Example
I
Dawn
Song
44
1: unsigned int size;!
2: Data **datalist;!
3:!
4: size = GetUntrustedSizeValue();!
5: datalist = (data **)malloc(size * sizeof(Data *));!
6: for(int i=0; i<size; i++) {!
7: datalist[i] = InitData();!
8: }!
9: datalist[size] = NULL;!
10: ...!
Example
I
45. Example
II
• What's
wrong
with
this
code?
• Hint
–
memcpy()
prototype:
– void *memcpy(void *dest, const void *src, size_t n);
• DefiniTon
of
size_t:
typedef unsigned int size_t;
• Do
you
see
it
now?
Dawn
Song
45
1: char buf[80];!
2: void vulnerable() {!
3: int len = read_int_from_network();!
4: char *p = read_string_from_network();!
5: if (len > sizeof buf) {!
6: error(“length too large, nice try!”);!
7: return;!
8: }!
9: memcpy(buf, p, len);!
10: }!
Example
II
46. Implicit
CasTng
Bug
• A8acker
provides
a
negaTve
value
for
len
– if
wonʼt
noTce
anything
wrong
– Execute
memcpy()
with
negaTve
third
arg
– Third
arg
is
implicitly
cast
to
an
unsigned int,
and
becomes
a
very
large
posiTve
int
– memcpy()
copies
huge
amount
of
memory
into
buf,
yielding
a
buffer
overrun!
• A
signed/unsigned
or
an
implicit
casTng
bug
– Very
nasty
–
hard
to
spot
• C
compiler
doesnʼt
warn
about
type
mismatch
between
signed int
and
unsigned int
– Silently
inserts
an
implicit
cast
Dawn
Song
46
47. Example
III
(Integer
Overflow)
• Whatʼs
wrong
with
this
code?
– No
buffer
overrun
problems
(5
spare
bytes)
– No
sign
problems
(all
ints
are
unsigned)
• But,
len+5
can
overflow
if
len
is
too
large
– If
len = 0xFFFFFFFF,
then
len+5
is
4
– Allocate
4-‐byte
buffer
then
read
a
lot
more
than
4
bytes
into
it:
classic
buffer
overrun!
• Know
programming
language’s
semanTcs
well
to
avoid
pi~alls
Dawn
Song
47
1: size_t len = read_int_from_network();!
2: char *buf;!
3: buf = malloc(len+5);!
4: read(fd, buf, len);!
5: ...!
Example
III
48. Example
IV
• Use-‐a$er-‐free
• Corrupt
memory
h8p://cwe.mitre.org
Dawn
Song
48
1: char* ptr = (char*) malloc(SIZE);!
2: if (err) {!
3: abrt = 1;!
4: free(ptr);!
5: }!
6: ...!
7: if (abrt) {!
8: logError(“operation aborted before commit”, ptr);!
9: }!
Example
IV
49. Example
V
• Double-‐free
error
• Corrupts
memory-‐management
data
structure
h8p://owasp.org
Dawn
Song
49
1: char* ptr = (char*) malloc(SIZE);!
2: if (err) {!
3: abrt = 1;!
4: free(ptr);!
5: }!
6: ...!
7: free(ptr);!
Example
V
50. What
are
so$ware
vulnerabiliTes?
• Flaws
in
so$ware
• Break
certain
assumpTons
important
for
security
– What
assumpTons
broken
in
buffer
overflow?
Dawn
Song
50
51. Why
does
so$ware
have
vulnerabiliTes?
• Programmers
are
humans!
– Humans
make
mistakes!
• Programmers
were
not
security
aware
• Programming
languages
are
not
designed
well
for
security
Dawn
Song
51
52. What
can
you
do?
• Programmers
are
humans!
– Humans
make
mistakes!
– Use
tools!
(next
lecture)
• Programmers
were
not
security
aware
– Learn
about
different
common
classes
of
coding
errors
• Programming
languages
are
not
designed
well
for
security
– Pick
be8er
languages
Dawn
Song
52