<<

Integer safety crash course

Read this chapter, it's from a great book you should buy: http://taossa.com/index.php/the-vault/chapter-6-c-language-issues/

● 1111111111111111111 ● int a = -1; 1111111111111 ● Most significant ● Least significant bit

Two's Complement

● 1111111111111111111111111 ● int a = -1, b; 1111111 ● ● Most significant bit b = -a; printf(“%d\n”,a); ● Least significant bit ● ● ~negate → b = ~a + 1; 00000000000000000000000 printf(“%d\n”,b); 000000000

● add 1 → 00000000000000000000000 000000001

Declaring variables

● int ; ● Signed or unsigned? ● char c; ● Signed or unsigned? ● long c; ● Signed or unsigned? ● short c; ● Signed or unsigned? ● #define X 4 ● Signed or unsigned?

http://www.cdecl.org/

Declaring variables

I. int c; I. Signed or unsigned? II.char c; II.Often signed- III.long c; depends IV.short c; III. Signed V. #define X 4 IV. Signed V. Signed

http://www.cdecl.org/

Signedness in a security context

● Bounds checking ● void dumpcash(unsigned ● Bounds checking int amt) { … } ● Bounds checking if (amt < acct_bal) dumpcash(amt); ● #define SIZE 64 if (index < SIZE) buffer[index] = data;

Signedness Concept → implicit funk

● int a = ● If a = -1? read_int(sockfd); ● if (a < sizeof(buf) ) {

}

Signedness Concept 1 → implicit conversion (coercion)

● signed vs unsigned ● int a; ● Converted to ● a < sizeof(buf) unsigned arithmetic ● == false ● Unsigned takes ● 0xffffffff < sizeof(buf) precedence

Signedness Concept 2 → extension

● a = 10000000 ● char a = 0x80; ● b = ● unsigned int b = a; 1111111111111111111 ● printf(“%u\n”,b); 1111110000000

● This slide might remind you of a lab exercise advisory you might be stuck on

Signedness Concept 3 → integer promotion

● Well covered in ● unsigned short a, b; taossas ● a = ● Learned this from strtoul(argv[1],0,0); fellow RPI student ● b = Roy Wellington in strtoul(argv[2],0,0); 2008; Roy read the C spec ● if(a*b < 0){ printf(“Roy is the ● Default is int man\n”); conversion }

Considerations for the future

● Signedness bugs are here to stay ● 64-bit won't make them go away

Esoteric signedness fun

● ● 10000000000000000 int a = -2147483648; 000000000000000 printf(“%d %d\n”, -a, ● Most significant bit ~a+1); ● Least significant bit

Guess the next topic

● What are the ● weirdcopy(char *buf, boundary conditions char *, unsigned for len? int len){ do { buf[len] = *data++; } while(--len); }

Thanks to A^2 for pointing out an error

Underflow

● Aside: everything but 0 is ● while(--len){ true in C do_stuff ● } ● len = 0;

● len → len = -1

● len = -2

● …

● len = 1

● len = 0

A common pattern for underflows

● This bad code is ● strlen(buf) can be 0 everywhere

● malloc 0 still allocates ● buf[strlen(buf)-1] = 0; memory ● These are ● sz = 0 exploitable buf = malloc(sz); for(i = 0; i < sz-1; i++) buf[i] = read_char(fd);

Overflow on addition

● int x = 0xdeadbeef; ● x + 0xbadc0ded = ?

http://www.youtube.com/watch?v=y4GDcvweo14

Addition under the covers

● int x = 0xdeadbeef; ● x + 0xbadc0ded = ? ● 11011110101011011011111011101111 10111010110111000000110111101101 ● ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 110011001100010011100110011011100

Multiplication too!

● uint sz = read_int(); ● Numeric overflow by multiplication, ● Buf = malloc(sizeof(int) * ● Can be used to sz); trigger buffer underflows and overflows depending on signedness.

Overflow thoughts

● Numeric overflows ● + other archs have become more can detect overflows, difficult to exploit compilers dont because of 64-bit ● :-(

Don't forget about truncation

● Look for lots of these in 64 bit code; anywhere you have variable integer sizes

● uint64_t sz = read_bytes(sizeof(uint64_t)); ● uint32_t limit = sz; ● if(limit < MAX) { … }

2 – Format strings

● printf(buf) ● sprintf,snprintf,syslog,asprintf,v*rintf, custom debug functions, ... ● Newer gcc versions warn about unspecified format strings

Deep thoughts on fmt strings

● Easy to find ● Direct parameter access not available on windows ● Latest VC++ disables %n entirely

3 – off by ones

● char buf[256]; int i; ● for(i = sizeof(buf); i >= 0; i—) ● for(i = 0; I <= sizeof(buf); i++) ● for(i = 0; sizeof(buf) > i; i++) ● char *buf = malloc(256); buf[256] = 0;

NUL termination

● “The strncpy() is similar, except that at most n are copied. Warning: If there is no null among the first of src, the string placed in dest will not be null terminated.” “The functions snprintf() and vsnprintf() write at most size bytes (including the trailing null byte ('\0')) to str.”

float != double

● Float 8 bit exponent 23 bit mantissa About 7 digits precision ● Double 11 bit exponent 53 bit mantissa About 16 decimal digits precision

Floating point woes

#include #include double GetTime(); int main(int argc, char* argv[]) { float a = GetTime(); usleep(5000 * 1000); float b = GetTime(); printf("a = %f\nb = %f\ndt = %f\n", a, b, b-a); return 0; }

Output

● a = 1265603328.000000 ● b = 1265603328.000000 ● dt = 0.000000

Spot the bug int verify(char* in, char* pass) { if(strcmp(in,pass) == 0) return STATUS_PASSWORD_OK; return STATUS_PASSWORD_ERROR; }

buf = new T[x]

● buf = malloc(x*sizeof(T)); for(i=0; i UINT_MAX?

delete x != delete[] x

● delete x call destructor on *x free(x) ● delete[] x ask memory manager for size of for(i=0; i

Double free / use after free

● Member functions are just functions with a hidden parameter “this” ● Calling on an invalid pointer will sometimes succeed ● , especially static / global variables, typically results

Reference counting

● Double free = drop reference counter twice ● We have one object and free it twice ● Refcount is now... ?

Exception handling

● Exception records are usually on the stack ● Corrupt these and throw an exception

Don't trust your compiler #include int main(int argc, char* argv[]) { unsigned int* a; unsigned int i; for(i=0; i<1; i++) printf("*a = %d\n",*a); return 0; }

Here's a harder one #include int main(int argc, char* argv[]) { unsigned int a; unsigned int b = a; unsigned int i; for(i=0; i<1; i++) { if(i > 0xdead) { printf("Initializing a\n"); a = 999; }

printf("a = %3d, b = %3d. ",a, b); if(a == b) printf("Equal\n"); else printf("Not equal\n"); } return 0; } Citations, Good reading

● http://www.ruxcon.org.au/files/2006/unusual_bugs.pdf ● http://taossa.com/index.php/the-vault/chapter-6-c-language-issues/ ● http://cr.yp.to/2004-494.html