栈缓冲区溢出

文章源自【字节脉搏社区】-字节脉搏实验室

作者-Jadore

栈:先进后出

动态调试下的栈:

几个寄存器:

EAX:函数执行完后的返回结果

ECX:计数器

EDX、EBX:计算器

ESP:指向栈顶的指针

EBP:指向栈底的指针

ESI、EDI:源地址,目的地址寄存器

EIP:存储CPU要读取指令的地址

莫里斯蠕虫(Morris worm):

https://baike.baidu.com/item/%E8%8E%AB%E9%87%8C%E6%96%AF%E8%A0%95%E8%99%AB/9035909?fr=aladdin

缓冲区溢出(Buffer Overflow|Buffer Overrun):

由于程序设计时缺乏对缓冲区(Buffer)的边界进行检查而导致在向缓冲区写入超过其本身的数据时而引起的异常,一般会对相邻的内存区域进行覆盖,通常会被利用执行恶意代码获取系统权限。

产生缓冲区溢出的几种可能:

1.数组索引不在合法范围内

通常我们可能比较多地注意到数组的上界不应被超过,而往往却不太会在意数组的下界,来看到这个例子:

#include<stdio.h>

int main()

{

int position=-1;

int value=100;

int array[10];

if(position >= 10)

{

return -1;

}

array[position]=value;

return 0;

}

2. 没有保证足够的存储空间存储复制过来的数据:

strcpy是一个不安全的函数,看这个例子:

#include<stdio.h>

int main()

{

int array[]={1,2,3,4,5,6,7,8,9};

int array2[9];

strcpy(array2,array);

return 0;

}

而莫里斯蠕虫利用的不安全函数为gets,gets函数与strcpy函数一样,并没有检查数组越界的功能,当然除了这两个,还有诸如strcat(),strncpy(),strncat(),甚至输入函数scanf()也并不安全,对应的有更加安全的函数,即在函数名后加上_s,如scanf_s()函数

3. 整数溢出:

整数溢出可分为宽度溢出和算术溢出

宽度溢出:把一个宽度较大的操作数赋给宽度较小的操作数,就有可能发生数据截断或符号位丢失(分别对应以下两个例子):

#include<stdio.h>

int main()

{

int a=1;

float b=3.14;

int c;

c=a+b;

return 0;

}

#include<stdio.h>

int main()

{

signed int value1 = 10;

usigned int value2 = (unsigned int)value1;

}

算术溢出,该程序即使在接受用户输入的时候对a、b的赋值做安全性检查,a+b依旧可能溢出:

#include<stdio.h>

int main()

{

int a;

int b;

int sum=a+b;

return 0;

}

4. 空字符错误:

当’\0’用%c输出时是空格,而用%d输出时是0

#include<stdio.h>

int main()

{

char array[]=”1”;

printf(“%d”,str[1]);

return 0;

}

还有一种遍历数组的情况:

#include<stdio.h>

int main()

{

char str[10]=”0123456789″;

int i;

for(i=0;str[i]!='\0';++i)

{

printf(“str[%d]=%c\n”,i,str[i]);

}

printf(“str[%d]=%d\n”,i,str[i]);

return 0;

}

可以看到,遍历数组时超过了数组边界,并试图读取超出数组边界之外的数据,直到程序读取到一个空字符之后才停止:

还有一种情况会丢失空字符结束符:

char array[]={'0','1','2','3','4','5','6','7','8'};

正确的写法应为:

char array[]={'0','1','2','3','4','5','6','7','8',’\0’};

或者char array[11]={'0','1','2','3','4','5','6','7','8','9’};

这里看看相关的缓冲区溢出漏洞ms08_067:

ms08_067是在执行路径规范化时函数返回地址被覆盖从而导致的任意代码执行的目的,ms08_067的攻击模块已经集成到metasploit中,直接看到exploit函数,首先使用connect函数建立TCP连接,然后进行SMB会话连接,给相关的参数赋值。自动探测时,通过smb_fingerprint函数获取信息

2表示构建恶意路径,先是初始化一些变量,包括填补字符串padder = [*(‘A’..’Z’)],服务器名称server以及前缀prefix、路径path:

target部分,定义赋值了变量Ret、Scratch,变量Ret的值对应SVCHOST.EXE系统文件中的JMP ESI指令地址,该exploit利用ESI寄存器中指向栈空间的地址,覆盖返回地址,因无法直接进行覆盖,因此需要通过JMP ESI指令进行跳转,最终再执行栈中的shellcode:

首先构造含跳转地址的填充字符串jumper,初始化长度为70字节,内容为’A’–’Z’的随机字符串,从第5字节起填充4字节由初始化变量Ret定义的返回地址6,从第51字节起填充8字节的空指令和2字节的跳转指令”\xeb\x62”:

接着,生成恶意路径path(8),由8个部分组成,其中包括编码的Shellcode、触发漏洞的unicode相对路径’\\..\\..’、填补字符串pad、EBP栈基址、RET返回地址、跳转指令jumper、字符串结尾”\x00” * 2:

最后只需要与目标主机正常交互发送这些数据,尝试一次攻击得到一个反向shell:

本文分享自微信公众号 - 字节脉搏实验室(zijiemaiboshiyanshi),作者:Jadore

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-02-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Tomcat后台弱口令Getshell

    war 包是一种打包格式 Java web工程,都是打成war包,进行发布,打成war包的好处是不会缺少目录,并且只管理好一个发布文件就好,并且tomcat服务...

    字节脉搏实验室
  • 网络安全自学篇-PHP代码审计(十一)

    作者复现的是Axublog1.1.0版本下对用户输入过滤不严导致login.php页面存在SQL注入漏洞,攻击者可以利用漏洞进行SQL注入直接登录网站后台。 使...

    字节脉搏实验室
  • 后渗透学习笔记(一)

    攻陷了服务器,主机取得一定权限(可能不是很高)就开始进入了后渗透阶段 把对方机器打蓝屏重启有什么作用? 使得我们修改注册表等配置信息可以生效 windows的控...

    字节脉搏实验室
  • 1466: [蓝桥杯2019初赛]等差数列

    数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一部分的数列,只记得其中N 个整数。现在给出这N 个整数,小明想知道包含这N 个整数的最短的等差数...

    可爱见见
  • 洛谷P4424 [HNOI/AHOI2018]寻宝游戏(思维题)

    那么我们把每一列上的数和他之前的操作符分别拿出来看成一些序列,显然这个序列要满足最后一个\(\mid 1\)要在\(\& 0\)之后

    attack
  • BZOJ4552: [Tjoi2016&Heoi2016]排序(线段树 二分)

    首先二分一个答案,表示假设询问的位置为$x$,把$>= x$的看成$1$,$< x$的看成$0$

    attack
  • 洛谷P3437 [POI2006]TET-Tetris 3D(二维线段树 标记永久化)

    对于这题来说,因为有修改操作,我们需要在外层线段树上也打标记,而且标记的形式是对一段区间赋值。所以我们对每个标记需要开线段树来维护更改的位置

    attack
  • BZOJ1086: [SCOI2005]王室联邦(贪心,分块?)

    Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special Judge

    attack
  • 海量数据处理之bitmap

    本文将讲述Bit-Map算法的相关原理,Bit-Map算法的一些利用场景,例如BitMap解决海量数据寻找重复、判断个别元素是否在海量数据当中等问题.最后说说B...

    Spark学习技巧
  • 51Nod--1001 数组中和等于K的数对

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1001

    指点

扫码关注云+社区

领取腾讯云代金券