AirJD 焦点
AirJD

没有录音文件
00:00/00:00
加收藏

Pwning in C++ by Angelboy

发布者 cplusplus
发布于 1458263014752  浏览 7080 关键词 C++, English 
分享到

第1页

Pwning in C++

-basicAngelboy scwuaptx@gmail.com



第2页

Outline

• Virtual function table • Vtable Hijacking

• Vector & String • New & delete • Copy constructor & assignment operator



第3页

Virtual function table

• Virtual function is a key mechanism to support polymorphism in C++

• For each class with virtual functions, depending on the class inheritance hierarchy, the compiler will create one or more associated virtual function table ( table )



第4页

Virtual function table



writable section (heap)

compiler generates the table for all class



read-only section

vtable for Person

typeinfo Person::speak() Person::phd()

vtable for Stu

typeinfo Stu::speak() Person::phd() Stu::pwn()



第5页

Virtual function table



writable section ddaa (heap)

vfptr

a



meh

new a Person and a Stu object



vfptr a b



read-only section

vtable for Person

typeinfo Person::speak() Person::phd()

vtable for Stu

typeinfo Stu::speak() Person::phd() Stu::pwn()



第6页

Virtual function table



ddaa->speak()



writable section ddaa (heap)

vfptr

a



meh



vfptr a b



read-only section

vtable for Person

typeinfo Person::speak() Person::phd()

vtable for Stu

typeinfo Stu::speak() Person::phd() Stu::pwn()



第7页

Virtual function table



vfptr == *ddaa 取 vfptr



writable section ddaa (heap)

vfptr

a



meh



vfptr a b



read-only section

vtable for Person

typeinfo Person::speak() Person::phd()

vtable for Stu

typeinfo Stu::speak() Person::phd() Stu::pwn()



第8页

Virtual function table



writable section ddaa (heap)

vfptr

a



meh

call *vfptr (Person::speak(ddaa))



vfptr a b



read-only section

vtable for Person

typeinfo Person::speak() Person::phd()

vtable for Stu

typeinfo Stu::speak() Person::phd() Stu::pwn()



第9页

Virtual function table



meh->speak()



writable section ddaa (heap)

vfptr

a



meh



vfptr a b



read-only section

vtable for Person

typeinfo Person::speak() Person::phd()

vtable for Stu

typeinfo Stu::speak() Person::phd() Stu::pwn()



第10页

Virtual function table



vfptr == *meh 取 vfptr



writable section ddaa (heap)

vfptr

a



meh



vfptr a b



read-only section

vtable for Person

typeinfo Person::speak() Person::phd()

vtable for Stu

typeinfo Stu::speak() Person::phd() Stu::pwn()



第11页

Virtual function table



call *vfptr (Stu::speak(meh))



writable section ddaa (heap)

vfptr

a



meh



vfptr a b



read-only section

vtable for Person

typeinfo Person::speak() Person::phd()

vtable for Stu

typeinfo Stu::speak() Person::phd() Stu::pwn()



第12页

Virtual function table



meh->pwn()



writable section ddaa (heap)

vfptr

a



meh



vfptr a b



read-only section

vtable for Person

typeinfo Person::speak() Person::phd()

vtable for Stu

typeinfo Stu::speak() Person::phd() Stu::pwn()



第13页

Virtual function table



vfptr == *meh 取 vfptr



writable section ddaa (heap)

vfptr

a



meh



vfptr a b



read-only section

vtable for Person

typeinfo Person::speak() Person::phd()

vtable for Stu

typeinfo Stu::speak() Person::phd() Stu::pwn()



第14页

Virtual function table



call *(vfptr+0x10) (Stu::pwn(meh))



writable section ddaa (heap)

vfptr

a



meh



vfptr a b



read-only section

vtable for Person

typeinfo Person::speak() Person::phd()

vtable for Stu

typeinfo Stu::speak() Person::phd() Stu::pwn()



第15页

Vtable Hijacking

• Need some another vulnerability • Use-after-free, Heap overflow ….

• Force the table and Hijack the vfptr • Because the vfptr is writable



第16页

Virtual function table



writable section ddaa (heap)

vfptr

a



meh



vfptr a b



read-only section

vtable for Person

typeinfo Person::speak() Person::phd()

vtable for Stu

typeinfo Stu::speak() Person::phd() Stu::pwn()



第17页

Virtual function table



heap overflow force a vtabe in ddaa and hijack the vfptr of meh



writable section ddaa (heap)

&shellcode



meh



0xddaa ddaa



0xdead



0xbeef



read-only section

vtable for Person

typeinfo Person::speak() Person::phd()

vtable for Stu

typeinfo Stu::speak() Person::phd() Stu::pwn()



第18页

Virtual function table



meh->speak()



writable section ddaa (heap)

&shellcode



meh



0xddaa ddaa



0xdead



0xbeef



read-only section

vtable for Person

typeinfo Person::speak() Person::phd()

vtable for Stu

typeinfo Stu::speak() Person::phd() Stu::pwn()



第19页

Virtual function table



vfptr = *meh 取 vfptr



writable section ddaa (heap)

&shellcode



meh



0xddaa ddaa



0xdead



0xbeef



read-only section

vtable for Person

typeinfo Person::speak() Person::phd()

vtable for Stu

typeinfo Stu::speak() Person::phd() Stu::pwn()



第20页

Virtual function table



call *(vfptr) (call shellcode(meh))



writable section ddaa (heap)

&shellcode



meh



0xddaa ddaa



0xdead



0xbeef



read-only section

vtable for Person

typeinfo Person::speak() Person::phd()

vtable for Stu

typeinfo Stu::speak() Person::phd() Stu::pwn()



第21页

Virtual function table



writable section ddaa (heap)

&shellcode



read-only section

vtable for Person



PWN !!meh



0xddaa ddaa



typeinfo Person::speak()



但通常會有 DEP/NX 保護,可0能x要de跳adlibc 中的 oneP-egrasdogne::tphd()



或是其他可利0x⽤b用的ee地f ⽅方



vtable for Stu



typeinfo



Stu::speak()



call *(vfptr) (call shellcode(meh))



Person::phd() Stu::pwn()



第22页

Vector & String

• Vector

• A dynamic array

• 分配在 heap 段

• ⽐比⼀一般 c 中的陣列更有彈性,當空間不夠⼤大時 會重新兩倍⼤大的的⼩小來放置新的 vector ,再把 原本的空間還給系統



第23页

Vector & String

• Vector • member • _M_start : vector 起始位置 • vector::begin() • _M_finish : vector 結尾位置 • vector::end() • _M_end_of_storage :容器最後位置 • if _M_finish == _M_end_of_storage in push_back • It will alloca a new space for the vector • 以這個來判斷空間是否⾜足夠放元素



第24页

Vector & String

• Vector • member function • push_back : 在 vector 最後加⼊入新元素 • pop_back : 移除 vector 最後⼀一個元素 • insert :插⼊入元素到 vector 第 n 個位置 • erase :移除 vector 中第 n 個元素 • ……



第25页

Vector & String

• Vector layout

vector <string> vec

_M_start _M_finish _M_end_of_storage



第26页

Vector & String



• Vector layout

vec.push_back(“meh”)

_M_start _M_finish _M_end_of_storage



address of meh string



第27页

Vector & String



• Vector layout

vec.push_back(“meheap”)

_M_start _M_finish _M_end_of_storage



address of meh string



因為 _M_finish == _ M_end_of_storage

所以會先將藍⾊色那塊 delete 掉

再從新 new ⼀一塊新的 vector 並把舊的值複製過去



第28页

Vector & String



• Vector layout

vec.push_back(“meheap”)

_M_start _M_finish _M_end_of_storage



address of meh string

address of meh string address of meheap string



第29页

Vector & String



• Vector layout

vec.push_back(“meh.py”)

_M_start _M_finish _M_end_of_storage



address of meh string

address of meh string address of meheap string

address of meh string address of meheap string address of meh.py string



第30页

Vector & String



• Vector layout

vec.push_back(“pwn”)

_M_start _M_finish _M_end_of_storage



address of meh string

address of meh string address of meheap string

address of meh string address of meheap string address of meh.py string

address of pwn string



第31页

Vector & String



• Vector layout

vec.pop_back()

_M_start _M_finish _M_end_of_storage

call destructor of pwn string



address of meh string

address of meh string address of meheap string

address of meh string address of meheap string address of meh.py string

address of pwn string



第32页

Vector & String



• Vector layout

vec.pop_back()

_M_start _M_finish _M_end_of_storage



address of meh string

address of meh string address of meheap string

address of meh string address of meheap string address of meh.py string

address of pwn string



第33页

Vector & String

• String

• a dynamic char array • ⽐比起以往的字串陣列更加安全,全部動態配置記憶體空

間,減少⼀一般 buffer overflow 的發⽣生

• 在給定 input 時,會不斷重新分配空間給 user 直到結束 後,就會回傳適當的⼤大⼩小給 user

• 有許多種實作⽅方式,這邊介紹最常⾒見的⼀一種

• g++



第34页

Vector & String

• String • member • size :字串的⻑⾧長度 • Capacity : 該 string 空間的容量 • reference count : 引⽤用計數 • 只要有其他元素引⽤用該字串就會增加 • 如果其他元素不引⽤用了,也會減少 • 當 reference == 0 時就會,將空間 delete 掉 • value : 存放字串內容



第35页

Vector & String

• String • member function • length() : string ⼤大⼩小 • capacity() : ⺫⽬目前 string 空間容量 • c_str() : Get C string equivalent • ……



第36页

Vector & String

• String layout

string str cin >> str

str



第37页

Vector & String



• String layout

string str cin >> str input : aa

str



size = 2 capacity = 2

refcnt = 0 aa



第38页

Vector & String



• String layout

string str cin >> str input : aaa

str



size = 2 capacity = 2 refcnt = -1

aa

size = 3 capacity = 4

refcnt = 0 aaa



第39页

Vector & String



• String layout

string str cin >> str input : aaaaa

str



size = 2 capacity = 2 refcnt = -1

aa

size = 4 capacity = 4 refcnt = -1

aaaa

size = 5 capacity = 8

refcnt = 0 aaaaa



第40页

Vector & String



• String layout

string str cin >> str input : a*125

str



size = 125 capacity = 128

refcnt = 0 a*125



依此類推 capacity 會 不斷以⼆二的指數倍增⻑⾧長

直到 input 結束



size = 2 capacity = 2 refcnt = -1

aa

size = 4 capacity = 4 refcnt = -1

aaaa

size = 8 capacity = 8 refcnt = -1

aaaaaaaa

...



第41页

Vector & String



• String layout

vector<string> vec vec.push_back(str)

str

_M_start _M_finish _M_end_of_storage



size = 125 capacity = 128

refcnt = 1 a*125

str



size = 2 capacity = 2 refcnt = -1

aa

size = 4 capacity = 4 refcnt = -1

aaaa

size = 8 capacity = 8 refcnt = -1

aaaaaaaa

...



第42页

Vector & String



• String layout

vector<string> vec vec.push_back(str) vec.push_back(str)

str

_M_start _M_finish _M_end_of_storage



size = 125 capacity = 128

refcnt = 2 a*125

str

str str



size = 2 capacity = 2 refcnt = -1

aa

size = 4 capacity = 4 refcnt = -1

aaaa

size = 8 capacity = 8 refcnt = -1

aaaaaaaa

...



第43页

Vector & String



• String layout

vec.pop_back()

這邊會 call str destuctor 但不會 delete 空間

str

_M_start _M_finish _M_end_of_storage



size = 125 capacity = 128

refcnt = 1 a*125

str

str str



size = 2 capacity = 2 refcnt = -1

aa

size = 4 capacity = 4 refcnt = -1

aaaa

size = 8 capacity = 8 refcnt = -1

aaaaaaaa

...



第44页

Vector & String



• String layout

vec.pop_back()

這邊會 call str destuctor 但不會 delete 空間

str

_M_start _M_finish _M_end_of_storage



size = 125 capacity = 128

refcnt = 0 a*125

str

str str



size = 2 capacity = 2 refcnt = -1

aa

size = 4 capacity = 4 refcnt = -1

aaaa

size = 8 capacity = 8 refcnt = -1

aaaaaaaa

...



第45页

Vector & String



• String layout

end of scope

這邊會 call str destuctor 因 refcnt < 0 會做 delete

_M_start _M_finish _M_end_of_storage



size = 125 capacity = 128

refcnt = -1 a*125

str

str str



size = 2 capacity = 2 refcnt = -1

aa

size = 4 capacity = 4 refcnt = -1

aaaa

size = 8 capacity = 8 refcnt = -1

aaaaaaaa

...



第46页

New & Delete

• 在 c++ 預設的情況下 ,new/delete 的最底層實作依舊是靠 malloc/free 去處理記憶體管理

• 在 c++ 中,記憶體配置池稱為 free store ,但預設情況 下 free store 位置是在 heap

• 不過事實上 new/delete 是可以 overloading 的,也就是⾃自 ⾏行去做記憶體管理,另外最⼤大差別就是new/delete 實際上 會去 call constructor/destructor ⽽而 malloc/free 只做單純的 記憶體配置

• 因此盡量不要讓 malloc/free 與 new/delete 混⽤用,不然可 能會出現⼀一些不可預期的狀況



第47页

New & Delete

• new ⼤大致上流程 • operator new • 與 malloc 類似,單純配置記憶體空間,但配置失敗會進⼊入 exception ⽽而 malloc 則是返回 null ,有點像在 malloc 上⼀一層 wrapper • constructor

• delete ⼤大致上流程 • destructor • operator delete • 與 free 類似,釋放⼀一塊記憶體空間,有點像是在 free 上⼀一層 wrapper



第48页

New & Delete



• 因此 new/delete 及 operator new / operator delete 也應該成對配對

• 記憶體函式配對



配置函式

new new [] operator new operator new[] malloc



解除函式

delete delete [] operator delete operator delete[]

free



第49页

What’s wrong in this code



第50页

What’s wrong in this code



第51页

What’s wrong in this code



第52页

Copy constructor & assignment operator

• shadow copy

• 只做單純 pointer (value) 的複製,複製完後內 容與原本的相同

• deep copy

• 會在配置更多記憶體空間,包含 pointer 所指向 的內容也都⼀一併複製



第53页

Copy constructor & assignment operator



• shadow copy



StuA



name



orange



第54页

Copy constructor & assignment operator



• shadow copy



StuA



name



orange



StuB



name



第55页

Copy constructor & assignment operator



• deep copy



StuA



name



orange



第56页

Copy constructor & assignment operator



• deep copy



StuA



name



orange



StuB



name



orange



第57页

Copy constructor & assignment operator

• Copy constructor

• c++ 在進⾏行複製 object 會使⽤用 copy constructor

• 通常 class 的 member 有指標時,就需要⾃自⾏行 去實作

• 若未特別定義則會使⽤用 default copy constructor

• 只做 shadow copy



第58页

Copy constructor & assignment operator

• Assignment operator

• c++ 在進⾏行 “=“ 這個 operator 時 object 會使⽤用 assignment operator 這個 function 去 assign object 得直

• 通常 class 的 member 有指標時,就需要⾃自⾏行去實 作

• 若未特別定義則會使⽤用 default assignment operator

• 只做 shadow copy



第59页

Copy constructor & assignment operator

• 何時會使⽤用 copy constructor

• func(Stu stu)

• return stu • vector 等 STL 容器

• ….



第60页

Copy constructor & assignment operator

• 何時會使⽤用 assignment operator

• stuA = stuB • vector 等 STL 容器

• ex : vector.erase()

•…



第61页

Copy constructor & assignment operator

call constructor

id name

vector



第62页

Copy constructor & assignment operator



new char [str.length() + 1]



id = 1337 name



orange



vector



第63页

Copy constructor & assignment operator



push_back(student)



id = 1337 name



orange



id = 1337 name

vector



copy the value to vector using

shadow copy



第64页

Copy constructor & assignment operator



~Stu()

id = 1337 name



orange



id = 1337 name

vector



因 student 的 life time 結束

所以

call destructor



第65页

Copy constructor & assignment operator



delete [] name

id = 1337 name



orange



id = 1337 name



vector



第66页

Copy constructor & assignment operator



~vector()

id = 1337 name



orange



id = 1337 name

vector



因 stulist 的 life time 結束

所以

call destructor



第67页

Copy constructor & assignment operator



~Stu()

id = 1337 name



orange



id = 1337 name

vector



vector 會去 依次去呼叫

內容的

destructor



第68页

Copy constructor & assignment operator



delete [] name

id = 1337 name



orange



id = 1337 name



vector



第69页

Copy constructor & assignment operator



delete [] name

id = 1337 name



orange



double free id = 1337

name



vector



第70页

Copy constructor & assignment operator

• 總結

• 基本上 c++ 在只要做任何複製的動作時通常都 會去使⽤用 copy constructor 或者是 assignment operator

• 所以基本上物件只要有 pointer 都盡量養成習慣 去定義 copy constructor 跟 assignment opeator



第71页

Practice

• HITCON 2015 final ghostparty • https://github.com/scwuaptx/CTF-Practice



支持文件格式:*.pdf
上传最后阶段需要进行在线转换,可能需要1~2分钟,请耐心等待。