secure coding in c/c++

15
McAfee ConfidentialInternal Use Only Secure Coding in C/C++ A technical perspective September 25, 2013 Dan-Claudiu Dragoș Software Development Engineer

Upload: dan-claudiu-drago

Post on 22-Jan-2017

324 views

Category:

Software


9 download

TRANSCRIPT

Page 1: Secure Coding in C/C++

McAfee Confidential—Internal Use Only

Secure Coding in C/C++

A technical perspective

September 25, 2013

Dan-Claudiu Dragoș

Software Development Engineer

Page 2: Secure Coding in C/C++

What will we cover today:

• Software vulnerabilities: who and why?

• String and buffer overflows

• Pointer vulnerabilities

• Dynamic memory management

• Format strings (printf)

• Integer values

• Concurrency

• File I/O

Page 3: Secure Coding in C/C++

McAfee Confidential—Internal Use Only

Software vulnerabilities: who and why?

3

• Script kiddies or illiterate cybercriminals do not find vulnerabilities:

• … they simply use them for profit or fame

• Vulnerabilities are found by security experts

• They may be working for McAfee or for the government of Elbonia

• … this is not a non profit activity!

• These experts can set up environments similar to yours

• They have a deep understanding of the system architecture

• They have access to the same tools as you do

» … including debuggers!

» … or even to the source code!

• They practice the attacks in controlled environments before going live.

Page 4: Secure Coding in C/C++

McAfee Confidential—Internal Use Only

Software vulnerabilities: what to do?

4

• There is no magic recipe!

• The approach should be proactive, not reactive

» … it’s like pipe work when fixing leaks

• There are some good development practices

» … do’s and don’ts

• There is also some external help:

• Modern compilers may reorder parameters on stack or apply

optimizations

• Modern operating systems may use memory randomization

• Modern CPUs have “execute disable” flags

Page 5: Secure Coding in C/C++

McAfee Confidential—Internal Use Only

Software vulnerabilities: Buffers

5

• Unbounded buffer operations are the recipe for disaster

– Never use:

• API functions that populate buffers without taking sizes

• C-String operations without allowing for buffer size!

• Array iterations without checking for bounds

• Unsafe functions marked as such in the documentation

– Do not rely on your own canary values, let the compiler do its job!

– During development:

• Build the source code with a debug library with strict bounds checking

• Use static analysis software (Coverity)

• Run the software through a dynamic analyser (Purify)

Page 6: Secure Coding in C/C++

McAfee Confidential—Internal Use Only

Software vulnerabilities: Buffers

6

• Design patterns to keep in mind:

• Allocating memory for the use of (external) API functions is unsafe!

» On Linux the ELF dynamic linking table can be exploited

» Windows approach on using DLLs is safe

GNU libc (unsafe) GNU libc (safer) C++ STL (safest)

Caller allocates Calee allocates Callee allocates

Callee initializes

Caller uses

Caller frees Caller frees Callee frees

Page 7: Secure Coding in C/C++

McAfee Confidential—Internal Use Only

Software vulnerabilities: Pointers

7

• Function pointers are dangerous!

– An attacker may modify the memory and use such pointer as a trampoline

to their own shell code

• C++ polymorphic approach is much safer

• Always initialize and set the pointers to NULL after use

– NULL pointers may point to valid memory on some architectures

• Linux platforms: running the program through valgrind may help

identify potential issues

– the attacker may very likely do this in search of vulnerabilities!

Page 8: Secure Coding in C/C++

McAfee Confidential—Internal Use Only

Software vulnerabilities: Memory

8

• Never use buffer sizes based only on user input

» …argv[] elements can be empty strings!

» …including argv[0]

• Do not use malloc(0), the behaviour is undefined

• Always check the result of memory allocation (and handle the error)

• Always use the proper call pairs:

• new – delete

• malloc – free

• new[] – delete[]

• placement new – explicit destructor call

Page 9: Secure Coding in C/C++

McAfee Confidential—Internal Use Only

Software vulnerabilities: Format strings

9

• Variadic functions such as printf are dangerous

• the C standard does not provide a reliable way to determine the call

argument count

• these functions must rely on the caller to provide the proper format, the

right number of arguments and the proper argument types

• If the format string contains unparsed user input, this is an exploit

invitation:

» the attacker can trigger reading arbitrary data from the stack

» the %n format specifier causes data to be written!

» specially crafted format strings can cause data to be written to

arbitrary memory locations!

• Localization code is a prime target for these attacks

Page 10: Secure Coding in C/C++

McAfee Confidential—Internal Use Only

Software vulnerabilities: Integers

10

xkcd clipart released under Creative Commons license

Page 11: Secure Coding in C/C++

McAfee Confidential—Internal Use Only

Software vulnerabilities: Integers

11

• C language defines multiple integer types and default conversions

• Integer values are prone to overflow

• Don’t:

• design your code with a certain architecture in mind

• forget that the safe storage of the multiplication result requires twice

the size of the largest argument

• mix signed and unsigned types

• forget about LSB/MSB or the negative numbers

• Do:

• check for bounds on any integer value received from the user

• test the code thoroughly on all relevant architectures

Page 12: Secure Coding in C/C++

McAfee Confidential—Internal Use Only

Software vulnerabilities: Concurrency

12

• The concurrency issues do not usually result in privilege escalation

» …they are mostly used for denial of service

• An attacker may only want to get your system to an undefined state

» …but this is also a job for the QA!

• Always be on the look for:

• scalability issues

• race conditions

• deadlocks

• starvation and live locks

Page 13: Secure Coding in C/C++

McAfee Confidential—Internal Use Only

Software vulnerabilities: File I/O

13

• Referring files by names is unsafe by design

• on Linux the race window between stat() and open() cannot be

(cleanly) avoided

• an attacker may replace the file in this race window

• The prime target for these attacks are the setuid() programs

• Mitigation strategies:

• use canonical names / paths, do not trust the user input

• perform all the operations with the lowest required privileges / drop

super user privileges when they are no longer required

• check that the file operation is not performed on a symlinked file

• the admin must ensure that no hard links are possible between user

files and system files

Page 14: Secure Coding in C/C++

McAfee Confidential—Internal Use Only

Software vulnerabilities:

14

• Questions?

Page 15: Secure Coding in C/C++