某安全竞赛题二

第二题

程序运行

 

开启端口12543

ida打开程序,在函数initFunctions中会将之后要使用的系统函数以及字符串的地址保存在一个表中。

 

如下图

 

之后会调用函数parrot如下图,在该函数中会调用unk_603820处的函数,通过之前的initFunction函数可发现该处对应函数callFuntion。

 

在callfunction函数中,首先会调用mmap函数分配一段可执行内存,之后会将加密过的服务器通信函数拷贝到该断内存中,然后解密这段内存,最后运行,而该题的溢出点也发生在该被加密的函数中。

 

调用mmap函数分配内存,该处分配的内存为0x7ffff7ff6000

 

之后将加密之后的函数字符串拷贝到该内存中(此处使用函数memcpy函数进行拷贝,源地址为0x400eb8,目标地址为0x7ffff7ff6000)

 

拷贝前后

 

之后调用函数dectyptFunction函数进行解密

 

解密之后

 

通过gdb的反编译很容易发现此处是一个函数,开头通用的堆栈操作

 

发送一段超长字符,程序崩溃

 

通过ida发现,改程序中可能造成溢出的函数只有memory,同时因为溢出漏洞的函数被加密,调试的时候不便直接对该处下断点(必须等到内存解密),因此我们对函数memory的函数表下硬件读断点(因为该处肯定会被加密函数使用到,因此断下之后肯定位于被解密的函数中)。

 

运行发包之后断在函数0x7ffff7ff6129中,此处读取了memcpy的地址,同时在0x7ffff7ff615a出发生了溢出

 

查看此时的堆栈,以及寄存器rbx,即可发现该处确实是memcpy

 

此时的堆栈,返回地址0x7fffffffe308处的数据已经被覆盖

 

查看覆盖偏移,为280

 

重新构造发送的数据包。

 

此时eip已被控制。

 

该题的总思路就是服务器会将用于和用通信的函数加密,只在程序运行的时候动态解密,但是该函数中对传入的数值长度没有做校验导致溢出,稍微麻烦的就是处理加密函数。

posted @ 2015-06-02 17:42  goabout2  阅读(148)  评论(0编辑  收藏  举报