# 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
- Vtable Hijacking ([ref in C](https://hackmd.io/@trhoanglan04/bof_advanced_level#fake-vtable))
- 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:
```cpp
#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 **Person** và **Stu**

> vtable của class con Stu sẽ kế thừa **phd()** từ class cha Person
> **vfptr** viết tắt của **V**irtual **F**unction **ptr**(Pointer)
> **NOTE** : **vfptr** is writeable
- khi call `ddaa->speak()`
```c
vfptr == *ddaa //(get vfptr)
call *vfptr
//(Person::speak(ddaa))
```

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

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

### Vtable Hijacking
- cần thoả mãn 1 số vulnerability trên Heap:
> UAF, Heap Overflow, ...
- Poison vtable and hijack the **vfptr**
- example:

> ow **vfptr** of vtable in ddaa (target)
> hijack **vfptr** of vtable in meh (point to target)
- khi call `meh->speak()`
```c
vfptr == *meh //(get vfptr)
call *vfptr
// call shellcode(meh)
```

===> ==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

- khi `.push_back()` :

> `_M_finish == _M_end_of_storage`

> -> blue block will be deleted first

> -> new vector will be create
> ---> old value will be copied

>similar (for example)

> pwn is end function in class
- khi `.pop_back()`

> 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:




- 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()` :

> 1 push_back = 1 reference
> ---> **refcnt** = 1

> 2 push_back = 2 reference
> ---> **refcnt** = 2
- khi `.pop_back()` :

> 1 pop_back will decrease **refcnt**
> call str destructor nhưng không xoá space

> next pop_back will let **refcnt** = 0
> call str destructor nhưng không xoá space

> 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++, `new` và `delete` vẫn dựa vào **malloc()** và **free()** để handle memory management
- nhưng `new` và `delete` có thể bị overloaded
> ---> do memory management by itself
- sự khác nhau lớn nhất là `new` và `delete` là sẽ call constructor/destructor, trong khi **malloc()** và **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:
```c
#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;
}
```

#### 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

### deep copy
- allocate mới
- content pointed to by pointer will also be copied

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

- khi `.push_back()` :
```c
stulist.push_back(student);
```

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

- và chính vector cũng sẽ call destructor chính nó
> content nó return
===> **DOUBLE FREE**
# ref
- https://fr.slideshare.net/slideshow/pwning-in-c-basic/58370781
> của Angleboy luôn chất lượng
- https://www.youtube.com/watch?v=BnMnozsSPmw
> video about operator
- https://www.youtube.com/watch?v=PXcRe-W2w7s&t=1036s
> Rule of Three
- https://www.youtube.com/watch?v=E4MWxaUy3zo
> Rule of Five