复现笔记|篡改栈上指针,泄漏堆地址

实验环境:ubuntu 64位 16.04
实验工具:pwntools,gdb-peda,IDA
实验程序ELF来源:强网杯2018-opm

程序运行界面菜单:


复现笔记|篡改栈上指针,泄漏堆地址_第1张图片
image.png

第一个功能Add a new role有问题。IDA反编译查看。


复现笔记|篡改栈上指针,泄漏堆地址_第2张图片
image.png

分析以上代码,经过分析发现,v6是一个heap指针,且当执行"gets(&v5)"时,有可能会被溢出修改。但因为时"gets()"函数修改,你输入的字符串后加上“\x00”,效果看下图,查看栈空间。


复现笔记|篡改栈上指针,泄漏堆地址_第3张图片
1523671146(1).jpg

溢出篡改v6
复现笔记|篡改栈上指针,泄漏堆地址_第4张图片
1523672191(1).jpg

这就导致了我们要特别关注heap_address为0x00005xxxxxxxxx00之类的地址,比如下图:


复现笔记|篡改栈上指针,泄漏堆地址_第5张图片
1523672779(1).jpg

接下来 我们分析一下它的heap分配情况,根据IDA反编译的结果显示,一个add功能进行了两次heap分配。
v0 = (_QWORD *)operator new(32LL);
and
v7 = (char )malloc(v2);
从内存查看的数据结果来看,operator new()和malloc()申请heap,没差别(应该会有差别的,这里不讨论)。如下图,添加一个name为‘A’
0x70的role。1 punch。

复现笔记|篡改栈上指针,泄漏堆地址_第6张图片
1523674136(1).jpg

接下来进行篡改指针(v6)覆盖heap数据的测试,上提及:
0x555555768c00
0x555555768d00
0x555555768e00
0x555555768f00
之类的heap地址是危险的地址,方便控制的。0x555555768c00已经被系统利用了,我们控制不了。于是我们选择攻击
0x555555768d00。首先0x30个‘B’打在0x555555768d00。

复现笔记|篡改栈上指针,泄漏堆地址_第7张图片
1523677056.jpg

然后创建第三个role的篡改指针(v6),使name3__addr,打在0x555555768d00附近。如下图。原本应该在0x555555768d40的数据被打在了0x555555768d00附近。
复现笔记|篡改栈上指针,泄漏堆地址_第8张图片
1523678199(1).jpg

那么接下来就要想想该怎么进行泄漏了。
在add a new role这个函数下,它有一个输出函数,用于输出role的name和punch数。而它的参数是v6,是可以被控制的。如果我们这时我们想要泄漏出0x555555768d00的数据,则需要将原本v6(此时指向0x555555768d40)让他指向0x555555768cd0。如下图。但是上面提到过"gets()"溢出并没有那么容易控制,想要修个v6指向0x555555768cd0是不可能的,并且程序开启了PIE(基地址随机化)。
复现笔记|篡改栈上指针,泄漏堆地址_第9张图片
1523685095(1).jpg

这里想到了办法是,将0x555555768cd0上的数据保存到一个可控的地址上去,这再添加第二个role,输入name的时候可以做到。然后在添加第三个role的时,输入name的时候溢出,将地址打在
0x555555768d00上。在输入punch的时候将v6指向有
“0x555555768d00”的地址上。
下面演示一遍,:
添加第一个role ,name为"A"0x70,punch为1,这里输入0x70个‘A’是为了第二个role的name_addr在0x555555768d00上。
复现笔记|篡改栈上指针,泄漏堆地址_第10张图片
image.png

添加第二个role,name为"B"0x80 + "a" ,punch为2。这个为了修改v6使原本应该保存在0x555555768cd0 的数据保存在一个可控的地方。
输入完name之后,查看栈的数据。看到v6已经被修改为:0x0000555555760061
复现笔记|篡改栈上指针,泄漏堆地址_第11张图片
1523686827(1).jpg

然后让程序执行几步后查看堆内存,0x555555768cd0,数据没了
复现笔记|篡改栈上指针,泄漏堆地址_第12张图片
1523687013(1).jpg

然后查看0x0000555555760061,数据在这里
复现笔记|篡改栈上指针,泄漏堆地址_第13张图片
1523687134(1).jpg

添加第三个role,name为"C"
0x80,punch为"2"+"C"*0x7f+"a"。
输入name是为了修改v6,让heap地址打在0x555555768d00如下图。
此时的v6
复现笔记|篡改栈上指针,泄漏堆地址_第14张图片
image.png

此时的0x555555768d00:
复现笔记|篡改栈上指针,泄漏堆地址_第15张图片
1523687559(1).jpg

输入punch ,最前面有一个2是为了过atoi()这个函数。
此时的v6,指向了我们前边提到的可控的地址。0x0000555555760061。过几步,v6会作为输出函数的参数。
复现笔记|篡改栈上指针,泄漏堆地址_第16张图片
image.png

成功泄漏:
image.png

使用pwntools,脚本如下。

复现笔记|篡改栈上指针,泄漏堆地址_第17张图片
image.png

你可能感兴趣的:(复现笔记|篡改栈上指针,泄漏堆地址)