二進(jìn)制安全之堆溢出(系列)—— house of spirit
本文是二進(jìn)制安全之堆溢出系列的第四章節(jié),主要介紹house of spirit。
原理
目的:通過任意地址free達(dá)到篡改任意地址的目的
條件
在目標(biāo)地址周圍能夠偽造一個(gè)堆塊
能夠?qū)卧斓亩褖K進(jìn)行一次free
free之后能夠重新申請(qǐng)得到這個(gè)堆塊并篡改目標(biāo)地址內(nèi)容
流程
從任意地方偽造一個(gè)堆塊
將堆塊釋放到bin鏈
將偽造的堆塊malloc取出
達(dá)到通過堆實(shí)現(xiàn)任意地址寫入的效果
Demo
#include<stdio.h>
#include<malloc.h>
#include<unistd.h>
#include<string.h>
int main(){
? ? malloc(0);
? ? int size = 0x40;
? ? long p = 0;
? ? char s[10];
? ? *((&p)+1) = size+1+0x10;
? ? sleep(0);
? ? *((&p)+3+size/8) = 0x71;? ? ? ? //更改一個(gè)chunk的size位,避免前向合并,因?yàn)槭莊astbin,故不用再構(gòu)造第三個(gè)堆塊
? ? free((&p)+2);? ? ? ? ? ? ? ? ? ? ? ? ? ? //free掉第一個(gè)堆塊的數(shù)據(jù)空間
? ? sleep(0);
? ? void *q = malloc(size);
? ? printf("%p\n",q);
? ? sleep(0);
? ? strcpy(q,"aaaaaaaa");
? ? sleep(0);
? ? return 0;
}
調(diào)試
初始化p指針(偽造p堆塊)
pwndbg> stack
00:0000│ rsp? 0x7fffffffdbc8 —? 0x4006b4 (main+78) ?— mov? ? eax, dword ptr [rbp - 0x34]
01:0008│? ? ? 0x7fffffffdbd0 ?— 0x1
02:0010│? ? ? 0x7fffffffdbd8 ?— 0x40004007bd
03:0018│? ? ? 0x7fffffffdbe0 ?— 0x0? ? ?==>p
04:0020│ rax? 0x7fffffffdbe8 ?— 0x51 /* 'Q' */
?
pwndbg> x/20gz 0x7fffffffdbe0
0x7fffffffdbe0: 0x0000000000000000? 0x0000000000000051? ? ? ==>偽造的size位
0x7fffffffdbf0: 0x0000000000400770? 0x0000000000400570
偽造下一個(gè)堆塊
pwndbg> x/20gz 0x7fffffffdbe0
0x7fffffffdbe0: 0x0000000000000000? 0x0000000000000051
0x7fffffffdbf0: 0x0000000000400770? 0x0000000000400570
0x7fffffffdc00: 0x00007fffffffdcf0? 0x675fd3aa65176f00
0x7fffffffdc10: 0x0000000000400770? 0x00007ffff7a2d830
0x7fffffffdc20: 0x0000000000000000? 0x00007fffffffdcf8
0x7fffffffdc30: 0x0000000100000000? 0x0000000000000071? ? ? ==>偽造的下一個(gè)堆塊的size
free 第一個(gè)堆塊的數(shù)據(jù)空間
0x50: 0x7fffffffdbe0 ?— 0x0
相當(dāng)于把棧上偽造的堆塊,釋放到了bin鏈里面
將以上 free 的堆塊malloc出來
0x60: 0x0 此時(shí)bins中的chunk被分配給了 q
之前偽造的p堆塊
pwndbg> x/20gz 0x7fffffffdbe0
0x7fffffffdbe0: 0x0000000000000000? 0x0000000000000051? ? ? ==>偽造的size位
0x7fffffffdbf0: 0x0000000000400770? 0x0000000000400570
此時(shí)的 q 堆塊
pwndbg> x/20gz 0x7fffffffdbe0
0x7fffffffdbe0: 0x0000000000000000? 0x00007fffffffdbf0
0x7fffffffdbf0: 0x0000000000000000? 0x0000000000400570? ==>fastbin的第一個(gè)堆塊,fd指向0
為什么size位原本是0x51,現(xiàn)在變成0x00007fffffffdbf0了呢
從匯編代碼來看,malloc之后,這個(gè)位置被重新賦值了
0x400700 <main+154>? ? call? ?malloc@plt <0x400540>
0x400705 <main+159>? ? mov? ? qword ptr [rbp - 0x28], rax ==> 重新賦值
? 0x400709 <main+163>? ? mov? ? rax, qword ptr [rbp - 0x28]
?
RBP? 0x7fffffffdc10
RAX? 0x7fffffffdbf0 ?— 0x0
即如下過程
02:0010│? ? ? ? ? 0x7fffffffdbe0 ?— 0x0
03:0018│? ? ? ? ? 0x7fffffffdbe8 —? 0x7fffffffdbf0 ?— 0x0
04:0020│ rax rdx? 0x7fffffffdbf0 ?— 0x0
05:0028│? ? ? ? ? 0x7fffffffdbf8 —? 0x400570 (_start) ?— xor? ? ebp, ebp
06:0030│? ? ? ? ? 0x7fffffffdc00 —? 0x7fffffffdcf0 ?— 0x1
07:0038│? ? ? ? ? 0x7fffffffdc08 ?— 0x400ae2129b1e7e00
向 q 中寫入 aaaaaaaa
pwndbg> x/20gz 0x7fffffffdbe0
0x7fffffffdbe0:0x00000000000000000x00007fffffffdbf0
0x7fffffffdbf0:0x61616161616161610x0000000000400500