堆溢出 pawnable.kr Unlink

    xiaoxiao2021-03-25  146

    题目地址:http://pwnable.kr/play.php

    按题目提示连接  ssh unlink@pwnable.kr -p2222 (pw: guest)

    ls    发现和之前的题目一样: 三个文件分别是 flag,unlink,unlink.c

    先查看unlink.c  源码如下:

    #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct tagOBJ{ struct tagOBJ* fd; struct tagOBJ* bk; char buf[8]; }OBJ; void shell(){ system("/bin/sh"); } void unlink(OBJ* P){ OBJ* BK; OBJ* FD; BK=P->bk; FD=P->fd; FD->bk=BK; BK->fd=FD; } int main(int argc, char* argv[]){ malloc(1024); OBJ* A = (OBJ*)malloc(sizeof(OBJ)); OBJ* B = (OBJ*)malloc(sizeof(OBJ)); OBJ* C = (OBJ*)malloc(sizeof(OBJ)); // double linked list: A <-> B <-> C A->fd = B; B->bk = A; B->fd = C; C->bk = B; printf("here is stack address leak: %p\n", &A); printf("here is heap address leak: %p\n", A); printf("now that you have leaks, get shell!\n"); // heap overflow! gets(A->buf); // exploit this unlink! unlink(B); return 0; }

    很明显是模拟的 Unlink 堆溢出漏洞,和题目一致,不知道这个可以先去看看这篇文章 :http://www.evil0x.com/posts/24617.html

    在 gets(A->buf)   处有堆溢出,我们可以通过这个来改写A,B,C的堆空间内容。

    重点当然是在unlink上 , unlink(B)做的其实就是将 B 从双向链表中取出来。

    在这个双向链表中,fd指向前一个节点,bk指向后一个节点。

    unlink() 所作的就是:   

    (B->fd)->bk=B->bk

    (B->bk)->fd=B->fd

    因为 OBJ 结构体的第一个成员就是fd  所以上式  ==   *(*B+4) = *(B+4) 

                                                                                            **(B+4) = *B             

     利用2式  我们可以通过重写B在堆中的 fd 与 bk 可以实现任意内存写入 

    在典型的 Unlink 漏洞中是通过重写GOT中  free() 函数的地址为 我们的 shellcode 地址,但是这种方法应该早就被修复了(上面那篇文章中提到了)。

    所以我们就只能是修改别的函数的返回值地址 , 下面 

     

    objdump -S unlink

    看一下汇编

    main() 函数如下 :

    0804852f <main>: 804852f: 8d 4c 24 04 lea 0x4(%esp),
    转载请注明原文地址: https://ju.6miu.com/read-6222.html

    最新回复(0)