CIS 4615 meeting -*- Outline -*- * C++ Catastrophes Based on chapter 8 of the book: 24 Deadly Sins of Software Security by M. Howard, D. LeBlanc, and J. Viega (McGraw-Hill, 2010). ** background ------------------------------------------ DEFAULT METHODS IN C++ class CountedPtr { public: int count; void *ptr; } desugars to: class CountedPtr { public: int count; void *ptr; inline CountedPtr() // default constr. : count(0), ptr(NULL) {} CountedPtr(const CountedPtr& rhs) // copy constr. { count = rhs.count; ptr = rhs.ptr; } CountedPtr& operator= // assignment opr. (const CountedPtr& rhs) { count = rhs.count; ptr = rhs.ptr; } ~CountedPtr() // default destr. { delete ptr; } } ------------------------------------------ Explain what each of these does These would be wrong for maintaining an appropriate invariant! Q: What code should these have? The copy constructor should be disabled by making it private/deleted same for the assignment operator The destructor should check that the count is zero, and should also reinitialize ptr to NULL ** attack overview ------------------------------------------ C++ CODE ATTACKS Attack Steps 1. Find code that passes around 2. Exploit coding error ------------------------------------------ ... function pointers (e.g., for a GUI or in a class's VTable) and can invoke hacker controlled code ... such as a double free, to run attacker-controlled code Q: How does a double free of code hurt in C++? The free runs a "destructor", and after the space is freed, the space is on the heap, and so can be written to by the attacker, so that the second free runs the attacker's code. ** examples of problems that are exploitable *** mismatched calls to delete ------------------------------------------ MISMATCHED CALLS TO DELETE or DELETE[] objects allocated with new should be freed using delete objects allocated with new[] should be freed using delete[] Problem n[]d: char* pChars = new char[128]; // ... delete pChars; Problem nd[]: widget *mw = new widget; //... delete[] mw; ------------------------------------------ Q: What is the difference between new and new[]? The latter allocates an array. Q: What happens in the problem n[]d example? The delete calls looks for the wrong type of header --> crash! Q: What happens in the problem nd[] example? The delete calls looks for the wrong type of header, may call the destructor multiple times on the wrong kind of object *** constructor problems ------------------------------------------ CONSTRUCTOR PROBLEMS uninitialized members could be controlled by attacker How? ------------------------------------------ ... by arranging for the memory to already hold certain values (from previous delete) ** remediation *** don't use arrays, use vectors from the STL ------------------------------------------ USE STL See the STL Tutorial and Reference Guide (Musser et al., 2001) Vectors, instead of arrays: vector arr(10); vector::iterator it; for(it = arr.begin(); it != arr.end(); ++it) { T& obj = (*it); //... } Safer code, Harder to make buffer overflows Pointer Containers Use auto_ptr (or unique_ptr) or the Use the boost pointer container library boost::shared_ptr See www.boost.org/doc/libs/ 1_35_0/libs/ptr_container/ ------------------------------------------ does reference counting *** general remediation steps ------------------------------------------ REMEDIATION STEPS Thoroughly understand C++ Stop using arrays in C++, and For resource classes, no copying, so: get rid of the copy constructor and assignment operator private: Make constructors initialize all data members, with no exceptions! For complex constructions, use Destructors should ------------------------------------------ ... don't use delete[] ... Foo(const Foo& rhs)=0; Foo& operator&(const Foo& rhs)=0; // In the new standard use =delete for the syntax. ... a separate init() method. ... reset the state to a known safe state as in ~Foo() { delete ptr; ptr = NULL; }