part 4: secure coding

33
1 Part 4: Secure Coding Many attacks are due to invalidated input to programs and faulty programming Secure Coding: Immensely important Not taught, not well understood Major problem with software development Languages used commonly are unsafe C, C++ are unsafe Java is much safer We will use C to show common programming errors Code examples from “Secure Coding in C and C++” by Robert Seacord.

Upload: hazina

Post on 07-Jan-2016

69 views

Category:

Documents


2 download

DESCRIPTION

Part 4: Secure Coding. Many attacks are due to invalidated input to programs and faulty programming Secure Coding: Immensely important Not taught, not well understood Major problem with software development Languages used commonly are unsafe C, C++ are unsafe Java is much safer - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Part 4: Secure Coding

1

Part 4: Secure Coding

Many attacks are due to invalidated input to programs and faulty programming

Secure Coding: Immensely important Not taught, not well understood Major problem with software development

Languages used commonly are unsafe C, C++ are unsafe Java is much safer

We will use C to show common programming errors

Code examples from “Secure Coding in C and C++” by Robert Seacord.

Page 2: Part 4: Secure Coding

2

Two fundamental attacks

1. Buffer Overflow

- writing past the end of an array or structure

2. Arbitrary Memory Write

- writing to some arbitrary memory location

The data written and the memory location chosen is under the control of the input data

Input data is crafted by the attacker

Page 3: Part 4: Secure Coding

3

gets is BAD

Never use gets, there is no safe way to use gets. Even if you use getc, there could be problems (be careful)

//gets problemvoid main (void) { char password[80]; puts ( “ Enter 8 char password: “); gets(password);}

Page 4: Part 4: Secure Coding

4

Strings are Trouble

Strcpy, strcat are unsafe, in most cases.//string problemsvoid main (int argc, char *argv[] ) { char name[2048]; // which line may overwrite? strcpy (name, argv[1]); strcat (name, “ = “); strcat (name, argv[2]);}

//goodint main (int argc, char *argv[] ) { char *buff = (char *)malloc(strlen(argv[1]+1); if (buf != NULL) { strcpy(buff, argv[1]); printf(“argv[1] =%s\n”, buff); } else { /* could not alloc, recover… */ } return 0;}

Page 5: Part 4: Secure Coding

5

Off by one errors

Spot the errors

//errorint main (int argc, char *argv[] ) { char source[10]; strcpy(source, “0123456789”) char *dest = (char *)malloc(strlen(source)); for (int I = 1; i<=11; i++) { dest[i] = source[i]; } dest[i] = ‘\0’; printf(“dest = %s\n”, dest);}

Page 6: Part 4: Secure Coding

6

More Grief

Counting errors

What happens after execution (difficult)?

//bad, counting errorsint main (int argc, char *argv[] ) { char a[16], b[16], c[32]; strcpy(a, ”0123456789abcdef”); strcpy(b, ”0123456789abcdef”); strcpy(c, a); strcpy(c, b); printf(”c = %s \n”, c);}

Page 7: Part 4: Secure Coding

7

Double Dumb

Not just gets, more trouble

bool IsPasswdOK(void) { char password[12]; gets(password); if (!strcmp(password, “goodpass”)) return(true) else return(false);}

Page 8: Part 4: Secure Coding

8

Safe String Operations

fgets, gets_s : Allows input size specifications

strcpy_s, strcat_s : same

strncpy (dest, source, size-1) : watch out for counting errors

strncat : same

Microsoft STRSAFE library

n = read(fd, buff, n) // safe but complex programming needed

Page 9: Part 4: Secure Coding

9

Overflow “protection”

Compiler checked bounds Often inadequate, slow

Stackgap : introduce random gaps in stack Canaries Libsafe : replaces normal string operations, ensures

overflows do not cross stack frame boundaries

Nothing can match proper input validation

Page 10: Part 4: Secure Coding

10

Attack prone

Looks safe, but is not, wrong use of safe functions Attacker can cause arc injection

// call wrong functionvoid good_f(char* str) { … }void main ( );{ static char buf [10] static void (*fptr)(char *str); fptr = &good_fl strnpy(buf, argv[1], strlen(argv[1]) fptr(argv[2]);

}Attacker can overwrite fptr and provide args to fptr

Page 11: Part 4: Secure Coding

11

Memory Layout

generic Unix Win32

code code

code

data

heap

stack

Global data

BSS segment

heap

stack

Reserved

stack

Reserved Reserved Reserved

heap

Reserved

stack

heap

Reserved

heap

stack

constant varsstatic vars

un-init-vars

Page 12: Part 4: Secure Coding

12

Where do these go?

// memory layoutstatic int initial = 1; // global datastatic int non-init; // BSS segment

void main(int argc, char* argv[]) // stack{ int i = 1, j; //stack static int x = 2 // global data static int y; // BSS segment int *buf = malloc (30); // buff on stack, contents on heap

}

Page 13: Part 4: Secure Coding

13

Arbitrary Memory Write

Via Overflow

// bad memory writevoid foo (int* arg, int len);{ char buff [50] ; int val = 25; int *ptr; = 30; memcpy(buff, arg, len); *ptr = val; …}

Page 14: Part 4: Secure Coding

14

Function Pointer

Use of function pointer may be harmful

// attackable function callsgood-f(char *str) { printf(str) }; // watch outvoid main(int argc, char* argv[]){ void (*fptr) (const char *str); fptr = &good_f; *fptr(“hi ”); //attackable Good_f(“there\n”); //non-attackable}

Page 15: Part 4: Secure Coding

15

Dangling Pointer

Free list structure is complex, and damage can be done by: Using free memory Double free

Prestored pointers are a source of errors

p = malloc(50);….Some code……free(p)……Some code……*p is used here

Page 16: Part 4: Secure Coding

16

Free Memory Error

Check the return value of malloc, else you may get…

//referencing free memoryint *mat(int *a, *b, n){ int *c = malloc(n * sizeof(int)); // no check? int i; for (i=0; i<n; i++) c += a[i] + b[i]; return c;}

//two errors, subtlefor (p=head; p != NULL; p = p->next) { // error 1 q = p-> next; free(p) ; // error 2}

Page 17: Part 4: Secure Coding

17

Double Free

More common that you think

// freeing same memory twicex = malloc (size);//work on itfree(x);y = malloc(size);//work on it;free(x); // often a cut and paste error

Page 18: Part 4: Secure Coding

18

The Unlink Attack

Overflow in allocated memory may make unlinking dangerous

Buffer overflow in HEAP – unlink attackint main(int arrgc, char *argv[]);{ char first, second, third; first = malloc (222); second = malloc (12); third = malloc (12); strcpy(first, argv[1]); // may mess up mem alloc free(first); free(second); free(third);}

Page 19: Part 4: Secure Coding

19

Mitigations

Make pointer null after freefree(p); p = NULL;

Use consistent strategy Do it in constructors and destructors Do it at beginning and end of each module Pair malloc and free Keep you own free list (fixed size items)

Canaries Guard pages Randomization of malloc strategy

Page 20: Part 4: Secure Coding

20

Integers are rather complex

C/C++ has many integer types Unsigned, short, long, long long

Integers have ranks Integer promotions are not well understood, conversions are also

used and can cause errors (truncation, overflow) Mixing unsigned ans signed integers are a problem, assigning

negative numbers to unsigned integers is common (attack)

Page 21: Part 4: Secure Coding

21

Size Matters

Obvious error

INTEGER Securityint main (int argc, char **argv); { unsigned short int total; total = strlen(argv[1])+strlen(argv[2]); char *buf = malloc (total); strcpy (buf, argv[1]); strcpy (buf, argv2));}

Page 22: Part 4: Secure Coding

22

Automatic promotions and casting

May not work, and then may

//integer promotionschar c1, c2, c3 result;c1 = 100;c2 = 90;c3 = -120;result = c1+c2+c3;// will work correctly (BAD)

Page 23: Part 4: Secure Coding

23

From Real Life

Jpeg file comment size includes some other 2 bytes

//JPEG vulnerabilityvoid getcomment(unsigned int len, char *src) { unsigned int size; size = len - 2; char comment = (char *) malloc(size + 1); memcpy (comment, src, size);}read the value of len from JPG file and then get comment.

Page 24: Part 4: Secure Coding

24

Easy Heap Overflow

What does memcpy expect as type of len?

// buffer overflow with –ve numbermain (argc, argv){ int len, char buf [size]; //size is a constant len = atoi(argv[1]); if (len <= size) ( memcpy(buf, argv[2], len); else printf(“too much data”);}

Page 25: Part 4: Secure Coding

25

skip

// truncation errormain(argc, argv){ unsigned short int total; total = strlen(argv[1])+strlen(argv[2]); char *buf = malloc (total) strcpy(buf, argv[1]); strcat(buf, argv[2]);}

Page 26: Part 4: Secure Coding

26

Skip

// truncation problem with conversionbool func(char * name, long cbBuf); unsigned short bufSize = cbBuf; char *buf = (char *) malloc (bufSize); if buf { memcpy ( buf, name, cbBuf); }

Page 27: Part 4: Secure Coding

27

Attackers think -ve

Most programs do not check for –ve values

//negative indexint *table = null;int insert(int pos, int value) { if (!table) table = maloc (400) if (pos > 99) { return -1} table[pos] = value;}

Page 28: Part 4: Secure Coding

28

printf can be harmful

Check for user provided input What does argv[0] actually contain?

//usage exploitvoid usage(char *p) { char str[1024]; snprintf(str, 1024, “Usage: %s <targets>\n”, p); printf(usageStr);}Main(){if argc not > 2 usage(argv[0]);

//easier to attack…printf(argv[1]);

Page 29: Part 4: Secure Coding

29

Printf attacks

//simplestfunc(char *user){ printf(user);}

attack1: %s%s%s%s%s%s………… may crashattack2: %08x, %08x, %08x, …………attack3: use %x a few times and then use %sattack4: \xdc\xf5\x42\x01%08x%08x%08x%08x%s (very tricky)

Page 30: Part 4: Secure Coding

30

skip

//buffer overflowchar buffer[512]; sprintf(buffer, “Wrong command: %s\n”, user);//stretchable bufferchar outbuf[512], buffer[512];sprintf(buffer, “Wrong Command: %.400s”, user);sprintf(outbuf, buffer);

-> input %497\x3c\xd3\xff\xbf\....[shellcode]

Page 31: Part 4: Secure Coding

31

Memory Writes with printf

%n = write # of chars outputted%u wite integer using u spaces

//overwriting memoryint i;printf(“Hello %n\n”, (int*) &i);

also:printf(“\xdc\xf5\x42\x0108x%08x%08x%08x%n”)

//[write specific address]int i;printf("%10u%n", 1, &i); //i=10printf("%100u%n", 1, &i); //i=100

Page 32: Part 4: Secure Coding

32

An incomplete example

unsigned char foo[8]printf(%x16u%n, 1, &foo[0]);printf(%x32u%n, 1, &foo[1]);printf(%x64u%n, 1, &foo[2]);printf(%x128u%n, 1, &foo[3]);printf("%16u%16u%32u%64u%n", 1, &foo[1], 1, &foo[2], 1, &foo[3], 1, &foo[4]);

Page 33: Part 4: Secure Coding

33

Args to Prinf

void foo(int p,int q, char *r, int s, int t){ int a[4] = {1,2,3,4}; print the stack here};main(){ foo(55, 56,"abcdefgh", 57, 58); };

bfabf458: 1 bfabf45c: 2 bfabf460: 3 bfabf464: 4 bfabf468: bfabf488 // base pointerbfabf46c: 8048410 // return addressbfabf470: 37 // 55 - arg 1bfabf474: 38 // 56 - arg 2bfabf478: 8048520 // address for "abc...bfabf47c: 39 // 57 - arg 3bfabf480: 3a // 58 - arg 4