Try   HackMD

Pwning in C++

  • ở bài viết này mình sẽ đi qua vấn đề exploit trên binary được compiled bằng source C++ (cpp)
  • và giải thích bằng tiếng mẹ đẻ cho thân thuộc =))))

sai xót ở đâu thì comment hay inbox cho mình sửa nhe

Overview

  • Virtual Function Table
  • Vector & String
  • New & Delete
  • Copy constructor & assignment operator

Virtual Function Table

  • là key mechanism để hỗ trợ polymorphism (tính đa hình) trong C++
  • với mỗi class có virtual function (hàm ảo), tuỳ theo class inheritance (phân cấp) mà compiler sẽ tạo 1 hoặc nhiều virtual function table
  • examble:
#include <iostream>

using namespace std;

class Person {
    public :
        virtual void speak(){;}
        virtual void phd(){;}
    private :
        int a;
};

class Stu : public Person {
    public :
        virtual void speak(){;}
        virtual void pwn(){;}
    private :
        int b;
};

int main(void){
    Person *ddaa = new Person();
    Stu *meh = new Stu();
    ddaa->speak();
    meh->speak();
    meh->pwn();
    return 0;
}
  • sau khi new 2 objects PersonStu

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

vtable của class con Stu sẽ kế thừa phd() từ class cha Person

vfptr viết tắt của Virtual Function ptr(Pointer)

NOTE : vfptr is writeable

  • khi call ddaa->speak()
vfptr == *ddaa //(get vfptr)
call *vfptr
//(Person::speak(ddaa))

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

  • khi call meh->speak()
vfptr == *meh //(get vfptr)
call *vfptr
//(Stu::speak(meh))

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

  • khi call meh->pwn()
vfptr == *meh //(get vfptr)
call *(vfptr+0x10)
//(Stu::pwn(meh))

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Vtable Hijacking

  • cần thoả mãn 1 số vulnerability trên Heap:

UAF, Heap Overflow,

  • Poison vtable and hijack the vfptr
  • example:

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

ow vfptr of vtable in ddaa (target)

hijack vfptr of vtable in meh (point to target)

  • khi call meh->speak()
vfptr == *meh //(get vfptr)
call *vfptr
// call shellcode(meh)

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

===> PWNED

nếu NX enable, thay bằng one_gadget hoặc other available value place

Vector & String

Vector

overview

  • là 1 mảng động (dynamic array)
  • phân bổ trên phân đoạn heap (allocated in heap segment)
  • linh hoạt hơn mảng trong code C

khi không đủ chỗ trống, tạo new vector size gấp đôi và space cũ sẽ trả về hệ thống (system)

remmember

  • member:
    • _M_start : vector start position
      • vector::begin()
    • _M_finish : vector end position
      • vector::end()
    • _M_end_of_strorage : last position of the container
      • if _M_finish == _M_end_of_storage in push_back()
        • alloca new space for vector
        • use for check enough space for element
  • member function
    • .push_back() : add new element into the end of the vector
    • .pop_back() : remove the last element of vector
    • .insert() : insert an element into n's position of the vector
    • .erase() : remove n elements from vector

Vector Layout

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

  • khi .push_back() :

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

_M_finish == _M_end_of_storage

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

-> blue block will be deleted first

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

-> new vector will be create

-> old value will be copied

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

similar (for example)

image

pwn is end function in class

  • khi .pop_back()

image

call destructor of pwn string

String

overview

  • là 1 mảng kí tự động (dynamic char array)
  • an toàn hơn mảng chuỗi (string array)

tất cả bộ nhớ sẽ phân bổ động (dynamically allocated) để giảm khả năng xuất hiện BOF

  • khi input được gọi, bộ nhớ liên tục tái phân bổ (reallocated) cho user đến khi kết thúc

kích thước phù hợp sẽ được return

dễ hiểu là cin >> bao nhiêu sẽ malloc bấy nhiêu

remmember

  • member:
    • size : length of string
    • capacity : capacity of string space
    • reference count : refcnt
      • strings is incremented whenever other elements refer to it
      • if other elements are no longer referenced -> reduced
        • reference < 0 : space will be deleted
    • value : store the string content
  • member function:
    • length() : string size
    • capacity() : current string space capacity
    • c_str() : get C string equivalent

String Layout

  • examble:

image

a

b

d

  • thu được công thức cho capacity là:
    • cấp số nhân 2 lớn hơn và gần size nhất

cho đến khi input kết thúc

  • khi .push_back() :

image

1 push_back = 1 reference

-> refcnt = 1

r

2 push_back = 2 reference

-> refcnt = 2

  • khi .pop_back() :

p

1 pop_back will decrease refcnt

call str destructor nhưng không xoá space

q

next pop_back will let refcnt = 0

call str destructor nhưng không xoá space

y

vẫn call destructor nhưng lần này vì refcnt < 0 nên sẽ xoá space

New & Delete

  • mặc định trong C++, newdelete vẫn dựa vào malloc()free() để handle memory management
  • nhưng newdelete có thể bị overloaded

-> do memory management by itself

  • sự khác nhau lớn nhất là newdelete là sẽ call constructor/destructor, trong khi malloc()free() chỉ thực hiện cấu hình bộ nhớ đơn giản
  • NOTE: cố gắng không mix malloc/free với new/delete

không thì 1 số tình huống unpredictable sẽ xảy ra

New

  • operator new
    • tương tự như malloc()
    • đơn giản là cấu hình không gian bộ nhớ

    nhưng nếu cấu hình fail -> an exception will be entered trong khi malloc() return NULL

    • a bit like a wrapper above malloc()
  • constructor

Delete

  • destructor
  • operator delete
    • tương tự như free()
    • giải phóng không gian bộ nhớ
    • a bit like a wrapper on free()

compare

  • memory function matching:
Configuration function Dismiss fuction
new delete
new [] delete []
operator new operator delete
operator new [] operator delete []
malloc free

Copy & Assignment

  • BUG examble:
#include <iostream>
#include <string>
#include <vector>
#include <string.h>

using namespace std;

class Stu{
    public : 
        Stu():name(NULL),id(0){}
        Stu(string str, int stuid){
            name = new char[str.length()+1];
            strcpy(name,str.c_str());
            id = stuid;
        }
        void putinfo(){
            cout << id << ":" << name << endl;
        }

        ~Stu(){
            delete [] name;
        }
    private :
        int id;
        char *name;
};

int main(void) {
    vector<Stu> stulist ;
    Stu student = Stu("orange",1337);
    stulist.push_back(student);
    stulist[0].putinfo();
    return 0;
}

image

Copy constructor

  • C++ dùng copy constructor khi copying objects
    • khi member của 1 class có indicator, cần phải implement it yourself
  • nếu không được defined, default copy constructor sẽ được dùng
    • shadow copy

Assignment operator

  • khi C++ thực hiện toán tử "=", object sẽ sử dụng assignment operator function (hàm toán tử gán)
    • khi member của 1 class có indicator, cần phải implement it yourself
  • nếu không được defined, default copy constructor sẽ được dùng
    • shadow copy

shadow copy

  • chỉ copy ptr
  • content remain the same as the original one

image

deep copy

  • allocate mới
  • content pointed to by pointer will also be copied

image

analyse BUG

  • call constructor
Stu student = Stu("orange",1337);
/*
Stu(string str, int stuid){
    name = new char[str.length()+1];
    strcpy(name,str.c_str());
    id = stuid;
}
*/

image

  • khi .push_back() :
stulist.push_back(student);

image

  • khi hết chức năng class -> call destructor
    ~Stu(){
        delete [] name;

image

  • và chính vector cũng sẽ call destructor chính nó

content nó return

===> DOUBLE FREE

ref

của Angleboy luôn chất lượng

video about operator

Rule of Three

Rule of Five