再谈关于缓冲器溢出

article/2025/9/16 17:39:21

废话少说(说一句废话,这是入门级的)

C/C++的代码:

 

// buffer overflow code by cto@renshenguo.com   
#include <windows.h>
#include <stdio.h>
void fnHack()   //the host never expect to run this
{   printf("Your computer has been hacked!\n"); //example for hack action
exit(0);    //exit process
}
int main(int argc, char* argv[])
{	int var[4] = {NULL};
var[5] = (int)fnHack;
printf("The host is running in normal way.\n");
return 0;
}

 

直接编译:

 

--------------------Configuration: BufferOverflow - Win32 Debug--------------------
Build : warning : failed to (or don't know how to) build 'F:\CODES\VISUAL C++\BufferOverflow\Debug\BufferOverflow.pch'
Compiling...
BufferOverflow.cpp
f:\codes\visual c++\bufferoverflow\bufferoverflow.cpp(16) : fatal error C1010: unexpected end of file while looking for precompiled header directive
Error executing cl.exe.
BufferOverflow.exe - 1 error(s), 1 warning(s)

 

Oops!这种情况多数是预编译头引起的:

 


然后选择如下图,确定

 

重新编译:

 

Deleting intermediate files and output files for project 'BufferOverflow - Win32 Debug'.
--------------------Configuration: BufferOverflow - Win32 Debug--------------------
Compiling...
BufferOverflow.cpp
Linking...
BufferOverflow.exe - 0 error(s), 0 warning(s)


然后我们试着运行一下:

 

 

我们没有去调用fnHack函数,但是它却执行力,究竟是怎么回事?

我们先看看这些代码编译以后的反汇编是什么样一副尊容:

@ILT+0(_main):
00401005   jmp         main (00401070)
@ILT+5(?fnHack@@YAXXZ):
0040100A   jmp         fnHack (00401020)
1:    // buffer overflow code by cto@renshenguo.com
2:    #include <windows.h>
3:    #include <stdio.h>
4:
5:    void fnHack()   //the host never expect to run this
6:    {   printf("Your computer has been hacked!\n"); //example for hack action
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,40h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-40h]
0040102C   mov         ecx,10h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
00401038   push        offset string "Your computer has been hacked!\n" (0042001c)
0040103D   call        printf (004012b0)
00401042   add         esp,4
7:        exit(0);    //exit process
00401045   push        0
00401047   call        exit (00401120)
8:    }
0040104C   pop         edi
0040104D   pop         esi
0040104E   pop         ebx
0040104F   add         esp,40h
00401052   cmp         ebp,esp
00401054   call        __chkesp (00401330)
00401059   mov         esp,ebp
0040105B   pop         ebp
0040105C   ret
9:
10:   int main(int argc, char* argv[])
11:   {   int var[4] = {NULL};
00401070   push        ebp
00401071   mov         ebp,esp
00401073   sub         esp,50h
00401076   push        ebx
00401077   push        esi
00401078   push        edi
00401079   lea         edi,[ebp-50h]
0040107C   mov         ecx,14h
00401081   mov         eax,0CCCCCCCCh
00401086   rep stos    dword ptr [edi]
00401088   mov         dword ptr [ebp-10h],0
0040108F   xor         eax,eax
00401091   mov         dword ptr [ebp-0Ch],eax
00401094   mov         dword ptr [ebp-8],eax
00401097   mov         dword ptr [ebp-4],eax
12:       var[5] = (int)fnHack;
0040109A   mov         dword ptr [ebp+4],offset @ILT+5(fnHack) (0040100a)
13:       printf("The host is running in normal way.\n");
004010A1   push        offset string "The host is running in normal wa"... (00420044)
004010A6   call        printf (004012b0)
004010AB   add         esp,4
14:       return 0;
004010AE   xor         eax,eax
15:   }
004010B0   pop         edi
004010B1   pop         esi
004010B2   pop         ebx
004010B3   add         esp,50h
004010B6   cmp         ebp,esp
004010B8   call        __chkesp (00401330)
004010BD   mov         esp,ebp
004010BF   pop         ebp
004010C0   ret
__chkesp:
00401330   jne         __chkesp+3 (00401333)
00401332   ret
00401333   push        ebp
00401334   mov         ebp,esp
00401336   sub         esp,0
00401339   push        eax
0040133A   push        edx
0040133B   push        ebx
0040133C   push        esi
0040133D   push        edi
0040133E   push        offset string "The value of ESP was not properl"... (004200a0)
00401343   push        offset string "" (0042009c)
00401348   push        2Ah
0040134A   push        offset string "i386\\chkesp.c" (0042008c)
0040134F   push        1
00401351   call        _CrtDbgReport (004046b0)
00401356   add         esp,14h
00401359   cmp         eax,1
0040135C   jne         __chkesp+2Fh (0040135f)
0040135E   int         3
0040135F   pop         edi
00401360   pop         esi
00401361   pop         ebx
00401362   pop         edx
00401363   pop         eax
00401364   mov         esp,ebp
00401366   pop         ebp
00401367   ret


汇编语言很头疼,不过其实也不是很难,我们来逐个看看:

10:   int main(int argc, char* argv[])
11:   {   int var[4] = {NULL};
00401070   push        ebp    ;ebp入栈,ebp是基址指针,指向堆栈底部(内存地址较大),关于堆栈机制可以查阅汇编语言
00401071   mov         ebp,esp    ;esp传送到ebp,esp是堆栈指针,指向堆栈顶部(内存地址较小)
00401073   sub         esp,50h     ;esp减少0x50个字节,其实就是堆栈大小增加0x50=80个字节
00401076   push        ebx    ;ebx入栈,很多入栈的操作一般就是两个目的:保护寄存器,参数传递,ebx是存储器指针
00401077   push        esi     ;esi入栈,esi是串操作源指针
00401078   push        edi     ;edi入栈,edi是串操作目的指针
00401079   lea         edi,[ebp-50h]    ;ebp-0x50就是原来栈顶esp-0x50,也就是新分配对战的底部,内存地址较大
0040107C   mov         ecx,14h    ;将0x14传送到ecx(通用寄存器)
00401081   mov         eax,0CCCCCCCCh    ;将0xCCCCCCCC传送到eax通用寄存器,这是VC++变量的默认值,CC的二进制是11001100
00401086   rep stos    dword ptr [edi]        ;填充新分配的堆栈空间
00401088   mov         dword ptr [ebp-10h],0      ;将0传送到ebp-0x10的内存单元(0x10=16也就是int var[4])
0040108F   xor         eax,eax       ;对eax异或,任何数值异或自身最终都使自身清零
00401091   mov         dword ptr [ebp-0Ch],eax ;将0传送到以下几个单元(也就是初始化数组var[4] = {NULL})
00401094   mov         dword ptr [ebp-8],eax
00401097   mov         dword ptr [ebp-4],eax

*var[4]的存储情况如下:


12:       var[5] = (int)fnHack;
0040109A   mov         dword ptr [ebp+4],offset @ILT+5(fnHack) (0040100a)   ;这一条指令很关键,他填充的内存单元超出了var数组的范围(填充ebp就已经非法)
13:       printf("The host is running in normal way.\n");
004010A1   push        offset string "The host is running in normal wa"... (00420044)
004010A6   call        printf (004012b0)      ;printf函数有一个必选参数,后面任意多个参数,函数的调用都是先参数入栈,再call函数
004010AB   add         esp,4      ;esp+4,这条指令是主调函数自己清理堆栈(上面push了一个双字参数,如果用汇编语言,各级多数人用pop指令)
14:       return 0;
004010AE   xor         eax,eax  ;清零,据说效率比mov快,也有说pentium以后一样的:eax是累加器
15:   }

 

函数已经执行完了,似乎没有什么错误,也没有调用call fnHack之类的指令出现,那么继续往下看才能看到问题了

004010B0   pop         edi           ;把以前入栈的寄存器全部出栈,其实就是恢复寄存器的值
004010B1   pop         esi
004010B2   pop         ebx
004010B3   add         esp,50h  ;栈顶加0x50就是释放函数增加的堆栈
004010B6   cmp         ebp,esp ;比较栈底和栈顶,影响标志位,ebp和esp的值不变(可以判断堆栈是否空了或者非法,防程序员不小心搞崩了堆栈)
004010B8   call        __chkesp (00401330)
004010BD   mov         esp,ebp ;恢复栈顶
004010BF   pop         ebp           ;恢复栈底(基址指针)
004010C0   ret

我们看看__chkesp这个函数是怎么回事:

__chkesp:
00401330   jne         __chkesp+3 (00401333)      ;不相等则跳转,即如果add  esp,50h后堆栈还有,则转到ret以后
00401332   ret
00401333   push        ebp            ;可以看出这里也是一个函数,至于怎么清零堆栈甚至抛出崩溃,我们不管,我们的代码肯定是相等的
00401334   mov         ebp,esp
00401336   sub         esp,0
00401339   push        eax
0040133A   push        edx
0040133B   push        ebx
0040133C   push        esi
0040133D   push        edi
0040133E   push        offset string "The value of ESP was not properl"... (004200a0)
00401343   push        offset string "" (0042009c)
00401348   push        2Ah
0040134A   push        offset string "i386\\chkesp.c" (0042008c)
0040134F   push        1
00401351   call        _CrtDbgReport (004046b0)
00401356   add         esp,14h
00401359   cmp         eax,1
0040135C   jne         __chkesp+2Fh (0040135f)
0040135E   int         3
0040135F   pop         edi
00401360   pop         esi
00401361   pop         ebx
00401362   pop         edx
00401363   pop         eax
00401364   mov         esp,ebp
00401366   pop         ebp
00401367   ret

回到main函数的后面看看

004010BD   mov         esp,ebp ;恢复栈顶
004010BF   pop         ebp           ;恢复栈底(基址指针),注意这一行,他会从堆栈顶部弹出到ebo寄存器
004010C0   ret       ;这里微软很XX,其实编译后是retn,相当于一条pop eip指令,也就是说ebp的值将被填充为@ILT+5(fnhack),即 jmp fnHack (00401020)

当然,CPU只是个机器,他会机械地跳转到fnHack去执行....

以更好的方法是编译release程序,然后用OllyIce去跟踪,你就发现EIP(指令指针的值)在执行retn后变成了0040100A!!!

不会?杆单了,看图:

当然如果你的是什么创天中文VC++之类的话,那只能自己去对号入座了(应该是设置活动配置之类的)

选择release,确定,rebuild all就可以了!

OllyIce的我就不说了,那个很多人都会,因为很多人都是从跟某些人学黑客开始接触编程的(这也是我近期才发现的)

那么,别人原来的程序又没有fnHack,这些东西有什么意义?

 

不错,但是源代码还是可以注入的,关于注入我现在先不谈了,另外缓冲区溢出还可能是字符串,比如网站

如果用专门编写的程序向存在溢出的网站POST带有汇编指令的请求,那么服务器的CPU将机械的执行那些指令

包括 net user hacker 123456 /add,写到这里,you know that!只要把跳转指令指向shellexecute这个API即可

(什么?不同机器不同?不错不同的机器API的地址可能不同,但是相同的系统必定相同,如同时XP SP3的话,因为32位都是内存映射的,每个进程有4G的独立空间)

 

另外一个应用是,把他指向内置的授权函数!

一些所谓的破解版下载下来仍然需要注册,其实如果它真的是破解版,只要随便输入一堆注册码,或者直接点注册就成功了就是这个原因

不过这仍然是比较初步的破解,比较牛插的是直接用jmp跳过检查,连提示注册都没有

 

水平问题,我不知道我写的是否够确切,各位看的是否够明白.

我知道有部分人会不屑于顾,因为他们是那些OOXX的人.这也是我后来才知道的(IT行业,很多半桶水的在搞软件,搞出来就想卖钱,太多了.但是也有一些高手确实很高手,我发现了,我真的发现了!!!)


http://chatgpt.dhexx.cn/article/tLO8WvW9.shtml

相关文章

Go内存溢出与内存泄露

https://www.cnblogs.com/sunsky303/p/11077030.html 一、内存泄露与内存溢出的区别 内存溢出(out of memory&#xff0c;简称OOM) 内存溢出是指程序在申请内存时&#xff0c;没有足够的内存空间供其使用&#xff0c;简单点说就是你要求分配的内存超出了系统能给你的&#…

(原创)攻击方式学习之(3) - 缓冲区溢出(Buffer Overflow)

堆栈溢出 堆栈溢出通常是所有的缓冲区溢出中最容易进行利用的。了解堆栈溢出之前&#xff0c;先了解以下几个概念&#xff1a; 缓冲区 简单说来是一块连续的计算机内存区域&#xff0c;可以保存相同数据类型的多个实例。堆栈 堆 栈是一个在计算机科学中经常使用的抽象数据类型。…

攻击方式学习之(3) - 缓冲区溢出(Buffer Overflow) [zt]

堆栈溢出 堆栈溢出通常是所有的缓冲区溢出中最容易进行利用的。了解堆栈溢出之前&#xff0c;先了解以下几个概念&#xff1a; 缓冲区 简单说来是一块连续的计算机内存区域&#xff0c;可以保存相同数据类型的多个实例。 堆栈 堆 栈是一个在计算机科学中经常使用的抽象数据类型…

linux 远程溢出,Linux Kernel蓝牙CAPI报文远程溢出漏洞

Linux Kernel是开放源码操作系统Linux所使用的内核。 Linux Kernel对入站CAPI消息没有执行正确的处理&#xff0c;远程攻击者可能利用此漏洞在服务器上执行任意指令。 Linux Kernel代码的net/bluetooth/cmtp/capi.c文件中没有正确地处理入站的CAPI消息。如果用户发送了特制的CA…

linux远程溢出,linux-ftpd-ssl 远程溢出漏洞

linux-ftpd-ssl 远程溢出漏洞 2005-11-15 eNet&Ciweek 详细描述&#xff1a; linux-ftpd-ssl是一款支持加密的FTP server。 linux-ftpd-ssl软件包中存在远程溢出漏洞&#xff0c;恶意服务器可能利用此漏洞在主机上执行任意指令。 恶意服务器生成的超长响应命令可能会覆盖栈…

html溢出攻击,溢出(漏洞)攻击的实现及防御

前言 媒体上关于系统漏洞的话题一直不断&#xff0c;在我所接触的用一些朋友和用户中虽然也知道打系统补丁很重要&#xff0c;但却又一直不以为然总以为网络上的危险离自己很远&#xff0c;大部份人都认为进行一次远程攻击很困难甚至认为只要安装了防病毒软件就一切大吉&#x…

缓冲区溢出(Buffer Overflow)

堆栈溢出 堆栈溢出通常是所有的缓冲区溢出中最容易进行利用的。了解堆栈溢出之前&#xff0c;先了解以下几个概念&#xff1a; 缓冲区 简单说来是一块连续的计算机内存区域&#xff0c;可以保存相同数据类型的多个实例。堆栈 堆 栈是一个在计算机科学中经常使用的抽象数据类型…

永恒之蓝漏洞复现(Windows server 2008系列缓冲区溢出漏洞)

漏洞信息 漏洞名称&#xff1a;Windows server 2008系列缓冲区溢出漏洞 CVEID&#xff1a;2017-0144 漏洞类型&#xff1a;输入验证错误 威胁类型&#xff1a;远程 发布时间&#xff1a;2017-03-14 危害等级&#xff1a;高危 漏洞简介 Microsoft服务器消息块1.0&#xff08;…

攻击方式学习之(3) - 缓冲区溢出(Buffer Overflow)

堆栈溢出 堆栈溢出通常是所有的缓冲区溢出中最容易进行利用的。了解堆栈溢出之前&#xff0c;先了解以下几个概念&#xff1a; 缓冲区 简单说来是一块连续的计算机内存区域&#xff0c;可以保存相同数据类型的多个实例。堆栈 堆 栈是一个在计算机科学中经常使用的抽象数据类型…

缓冲区溢出实例(一)--Windows

一、基本概念 缓冲区溢出:当缓冲区边界限制不严格时,由于变量传入畸形数据或程序运行错误,导致缓冲区被填满从而覆盖了相邻内存区域的数据。可以修改内存数据,造成进程劫持,执行恶意代码,获取服务器控制权限等。 在Windows XP或2k3 server中的SLMail 5.5.0 Mail Server…

linux服务器接收缓冲区拥堵,Linux Kernel IP虚拟服务器栈缓冲区溢出漏洞

发布日期&#xff1a;2013-11-15 更新日期&#xff1a;2013-11-18 受影响系统&#xff1a; Linux kernel < 3.2.13 描述&#xff1a; -------------------------------------------------------------------------------- BUGTRAQ ID: 63744 CVE(CAN) ID: CVE-2013-4588 Li…

20155216 缓冲区溢出漏洞实验

20155216 缓冲区溢出漏洞实验 缓冲区溢出漏洞实验实验简介 缓冲区溢出是指程序试图向缓冲区写入超出预分配固定长度数据的情况。这一漏洞可以被恶意用户利用来改变程序的流控制&#xff0c;甚至执行代码的任意片段。这一漏洞的出现是由于数据缓冲器和返回地址的暂时关闭&#x…

天骄辅助外挂制作,寻求合作

大家好&#xff0c; 进入正题现有我想开发一款游戏外挂&#xff0c;是针对新天娇的 不知您有没有开发外挂的经验呢&#xff1f;由于本人没有外挂开发的经验也暂时找不到相关的资料学习。 现在打算将这个项目外包出去&#xff0c; 要求&#xff1a; 一台机可以同时登录几个帐号 …

解剖一些外挂制作原理(DNF)

外挂现在大体上来讲分为三种&#xff0c;分别是模拟按键&#xff0c;WPE封包和内存挂。比如模拟键盘的&#xff0c;鼠标的&#xff0c;这种就叫做按键模拟&#xff0c;也叫脚本精灵&#xff1b;还有修改数据包的&#xff0c;这种就叫做WPE封包外挂&#xff0c;这种外挂相对而言…

外挂制作之思路总结和基址与偏移量

从今天起开始学习如何做外挂了 &#xff0c; 很久之前了解过一点皮毛。 无非是读写游戏进程中的内存数据。 再读写内存数据之前首先要做的就是找到游戏进程中在内存中的地址。在基地址中&#xff0c;利用CE寻找到某一数据对应的内存地址。计算出偏移量。然后每次都可以通过内存…

高中数学:数列求和的8种常用方法(最全)

高中数学&#xff1a;数列求和的8种常用方法&#xff08;电子版&#xff09;

常用数列求和公式

斐波那契数列 形如数列&#xff1a;1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ... 如果设F(n&#xff09;为该数列的第n项&#xff08;n∈N*&#xff09;&#xff0c;那么这句话可以写成如下形式: F(n)F(n-1)F(n-2) 通项公式: 求和公式: Sn2AnA(n-1) - 1 A(n2) -1 等…

在线等比数列求和计算器

在线等比数列求和计算器 在线等比数列求和计算器 该等比数列求和计算器可以计算指定等比数列各项之和,该等比数列求和计算器可以计算指定等比数列各项之和 https://tooltt.com/dbsl-sum/

蓝桥杯JAVA数列求和

import java.util.Scanner; public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in); int n sc.nextInt(); int a 1,b 1,c 1;for (int i 4; i < n; i) {int temp (a b c)%100000;//为了防止超过最大整数&#xff0c;可以…

C语言例程:数列求和

数列求和 计算 1121231234…12…n 的值。通过该实例&#xff0c;可以学习 if 条件判断语句和 for 循环语句的应用。程序运行结果如图 所示。 #include <stdio.h> int main() { int i,j,n; /* 定义循环变量 i,j&#xff0c;数列项数 n */ long int sum0,temp0; /* 定义…