Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >网安-演示整数的溢出漏洞实验

网安-演示整数的溢出漏洞实验

原创
作者头像
会洗碗的CV工程师
发布于 2023-12-29 13:45:43
发布于 2023-12-29 13:45:43
28000
代码可运行
举报
文章被收录于专栏:LongJava学习资料LongJava学习资料
运行总次数:0
代码可运行

1. 实验目的

了解整数及整数溢出的基本概念

了解整数溢出的常见类型

掌握整数溢出的基本原理

通过编写代码,体验整数溢出

2. 实验环境

Microsoft Visual C++ 6.0

Windows XP。

3. 实验原理

1、整数及整数溢出

关于整数的概念,应该说我们在上中学的时候就学过了。这里我们需要了解的是:整数分为无符号和有符号两类,其中有负符号整数最高位为 1,正整数最高位为 0,无符号整数无此限制;此外,常见的整数类型有 8 位(布尔、单字节字符等)、16 位(短整型、Unicode等)、32 位(整型、长整型)以及 64 位(__int64)等等。对于本文来说,了解这些就基本足够了。

关于整数溢出,简而言之,就是往存储整数的内存单位中存放的数据大于该内存单位所能存储的最大值,从而导致了溢出。归根到底,造成整数溢出漏洞的根本原因还是编程人员由于自身疏忽而对整数进行了错误操作引起的。

2、导致漏洞的几种整数误操作

一般说来,主要有三类整数操作可以导致安全性漏洞,下面列出每类的典型例子:

2.1.无符号整数的下溢和上溢

无符号整数的下溢问题是由于无符号整数不能识别负数所导致的。示例代码如下:

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
BOOL fun(size_tcbSize)
{
if(cbSize> 1024)
rerurn FALSE;
char *pBuf = new char[cbSize – 1];
//未对 new 的返回直进行检查
memset(pBuf, 0x90,cbSize – 1);
……
return TRUE;
}

在上面代码中,在调用 new 分配内存后,程序未对调用结果的正确性进行检测。如果cbSize 为 0 的话,则 cbSize – 1 为-1。但是 Memset 中第 3 个参数本身是无符号数,因此会将-1 视为正的 0xffffffff,函数执行之后程序当然就只有崩溃了。无符号整数的上溢问题也不难理解,示例代码如下:

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
BOOL fun(char *s1,size_t len1, char *s2,size_t len2)
{
if(len1 + len2 + 1 > 1024)
return FALSE;
charpBuf = new char[len1 + len2 + 1];
if(buf == NULL)
return FALSE;
memcpy(buf, s1, len1);
memcpy(buf + len1, s2, len2); //可能造成程序崩溃
……
return TRUE;
}

本例子中代码看起来没什么问题,该检测的地方也都检测了。但这段代码却可能出现整数上溢问题,len1 和 len2 都是无符号整数,如果 len1 = 8,len2 = 0xffffffff,由于加操作的限制,8+0xffffffff+1 产生的结果是 8。也就是说,new 操作只分配 8 字节的内存,而后面却要进行长达 0xffffffff 的串拷贝工作,结果肯定也是程序崩溃。

2.2.符号的问题

符号问题可以是多种多样的,但有几点是应该注意的:有符号整数之间的比较;有符号整数的运算;无符号整数和有符号整数的对比。这里举一个典型的例子:

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
intcopy_something(char *buf,intlen)
{
charszBuf[800];
if(len>sizeof(szBuf)) /* [1] */
{
return -1;
}
return memcpy(szBuf,buf,len); /* [2] */
}

上面代码的问题在于 memcpy 使用无符号整数作为 len 参数,但是在之前的数据边界检测使用了有符号整数。假设提供一个负数的 len,这样可以绕过[1]的检测,但是这个值同样被使用在[2]的 memcpy 函数的参数里面,len 可能被转换成一个非常大的正整数,导致 kbuf缓冲区后面的数据被重写,进而使得程序崩溃。

2.3.截断的问题

截断问题主要发生在大范围整数(如 32 位)拷贝给小范围整数(如 16 位)的时候可能产生的。同样来看一个例子:

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
BOOL fun(byte *name, DWORD cbBuf)
{
unsigned short cbCalculatedBufSize = cbBuf;
byte *buf = new byte[cbCalculatedBufSize];
if (buf == NULL)
return FALSE;
memcpy(buf, name,cbBuf);
……
return TRUE;
}

如果 cbBuf 是 0x00010020,又会如何呢?cbCalculatedBufSize 只有 0x20,因为只从0x00010020 复制了低 16 位。因此,仅分配了 0x20 个字节,并且 0x00010020字节复制到新分配的目标缓冲区中。如果整数溢出发生,之后的所有相关操作的结果都将发生变化。与缓冲区溢出不同的是,整数溢出发生时不会马上发生异常,即使程序执行结果与预期的不同,也很不容易发现问题所在。前面提到,整数溢出在很多时候会导致缓冲区溢出漏洞的发生,包括堆栈溢出和堆溢出。但并不是所有由整数溢出导致的缓冲区溢出都是可以利用的。相反,大多数情况是不能利用的,原因就在于其中涉及到诸如近乎 4G这样的大内存操作,会发生段错误。

4. 实验内容及步骤

1、依次点击-开始-运行,对话框中输入cmd进入命令行。

2、可查看桌面-实验工具-Debug中width1.c的代码如下:

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
/* width1.c - exploiting a trivial widthness bug */
#include <stdio.h>
#include<stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
unsigned short s;
int i;
char buf[80];
if(argc< 3){
return -1;
}
i = atoi(argv[1]);
s = i;
if(s >= 80){ /* [w1] */
printf("Oh no you don't!\n");
return -1;
}
printf("s = %d\n", s);
memcpy(buf, argv[2], i); //给 s 赋值 65536 时会在这里发生整数溢出
buf[i] = '\0';
printf("buf : %s\n", buf);
return 0;
}

3、在命令行中输入如下内容,查看运行结果:

4、依次点击-开始-运行,对话框中输入cmd进入命令行。

5、可查看桌面-实验工具-Debug中arithoverflow.c的代码如下:

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
/* arithoverflow.c - exploiting a trivial widthness bug */
#include <stdio.h>
#include<stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
unsigned  int len1,len2;
char mybuf[256];
len1 = 0x104;
len2 = 0xfffffffc;
if(argc< 2){
return -1;
}
if((len1 + len2) > 256){ /* [3] */
printf("len1 + len2 > 256 !\n");
return -1;
}
memcpy(mybuf, argv[1], len1); /* [4] */
memcpy(mybuf + len1, argv[2], len2);
printf("mybuf: %s\n", mybuf);
return 0;
}

6、在命令行中输入如下内容,查看运行结果:

7、依次点击-开始-运行,对话框中输入cmd进入命令行。

8、可查看桌面-实验工具中sigoverflow.c的代码如下:

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(int argc, char *argv[])
{
char szBuf[800];
int len = 0xfffffffe;
if(len>sizeof(szBuf)) /* [1] */
{
return -1;
}
memcpy(szBuf, argv[1], len); /* [2] */
printf("szBuf:%s\n",szBuf);
return 0;
}

9、编译运行,结果如下所示:

5. 实验结果与分析

关于整数溢出,简而言之,就是往存储整数的内存单位中存放的数据大于该内存单位所能存储的最大值,从而导致了溢出。归根到底,造成整数溢出漏洞的根本原因还是编程人员由于自身疏忽而对整数进行了错误操作引起的。而无符号整数的下溢和上溢,符号的问题等都可以导致安全性漏洞、

我正在参与2023腾讯技术创作特训营第四期有奖征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
网络攻防实战技术之——缓冲区溢出篇
1. 1988年的Morris蠕虫病毒,感染了6000多台机器:利用UNIX服务finger中的缓冲区溢出漏洞来获得访问权限,得到一个shell
墨文
2020/02/28
6.7K0
网络攻防实战技术之——缓冲区溢出篇
C和C++安全编码复习
标准C语言库支持类型为char的字符串和类型为wchar_t的宽字符串。 字符串由一个以空字符(null)作为结束的连续字符序列组成,并包含此空字符(sizeof=strlen+1) 一个指向字符串的指针实际指向该字符串的起始字符。
小简
2022/12/28
2.3K0
SEED缓冲区溢出实验笔记
缓冲区溢出实验(Linux 32位) 参考教程与材料:http://www.cis.syr.edu/~wedu/seed/Labs_12.04/Software/Buffer_Overflow/  (本文记录了做SEED缓冲区溢出实验的体会与问题,侧重实践,而不是讲解缓冲区溢出原理的详细教程) 1. 准备工作 使用SEED ubuntu虚拟机进行缓冲区溢出实验,首先要关闭一些针对此攻击的防御机制来简化实验。 (1)内存地址随机化(Address Space Randomization):基于Linux的操作
ascii0x03
2018/04/12
2.1K0
SEED缓冲区溢出实验笔记
以UPX漏洞为例介绍整数溢出(基础篇)
*本文原创作者:tocttou,本文属FreeBuf原创奖励计划,未经许可禁止转载
FB客服
2018/07/30
1K0
以UPX漏洞为例介绍整数溢出(基础篇)
Linux (x86) Exploit 开发系列教程之十 使用 Malloc Maleficarum 的堆溢出
从 2004 年末开始,glibc malloc 变得更可靠了。之后,类似 unlink 的技巧已经废弃,攻击者没有线索。但是在 2005 年末,Phantasmal Phatasmagoria 带来了下面这些技巧,用于成功利用堆溢出。
ApacheCN_飞龙
2022/12/01
6080
Linux (x86) Exploit 开发系列教程之十 使用 Malloc Maleficarum 的堆溢出
6.1 C/C++ 封装字符串操作
C/C++语言是一种通用的编程语言,具有高效、灵活和可移植等特点。C语言主要用于系统编程,如操作系统、编译器、数据库等;C语言是C语言的扩展,增加了面向对象编程的特性,适用于大型软件系统、图形用户界面、嵌入式系统等。C/C++语言具有很高的效率和控制能力,但也需要开发人员自行管理内存等底层资源,对于初学者来说可能会有一定的难度。
王 瑞
2023/10/10
4690
6.1 C/C++ 封装字符串操作
交错字符串(动态规划)- leetcode 97
给定三个字符串 s1, s2, s3, 验证 s3 是否是由 s1 和 s2 交错组成的。
ACM算法日常
2018/08/07
9130
交错字符串(动态规划)- leetcode 97
CVE-2021-3156:sudo堆溢出提权漏洞分析
当sudo通过-s或-i命令行选项在shell模式下运行命令时,它将在命令参数中使用反斜杠转义特殊字符。但使用-s或 -i标志运行sudoedit时,实际上并未进行转义,从而可能导致缓冲区溢出,攻击者可以使用本地普通用户利用sudo获得系统root权限。
FB客服
2021/05/20
2.4K0
CVE-2021-3156:sudo堆溢出提权漏洞分析
【C语言笔记】整数溢出问题
整数溢出是一种未定义的行为,当产生溢出行为时,系统并不会通知用户,所以应当多加小心。如下是整数溢出的一个案例:
正念君
2019/06/26
4.8K0
【C语言笔记】整数溢出问题
C语言总结_数组与函数传参练习题
字符串标准处理函数介绍(string.h)、指针和数组当做函数形参,指针定义、函数返回指针、void类型定义指针、类型强制转换、常量声明、extern外边引用声明关键字。
DS小龙哥
2022/05/19
8930
2016″百度之星” – 资格赛(更新中)
Memory Limit: 65536/65536 K (Java/Others)
十四君
2019/11/28
3590
分析笔记:MS17-017 中的整数溢出漏洞
前面的文章分析了 CVE-2016-0165 整数上溢漏洞,这篇文章继续分析另一个同样发生在 GDI 子系统的一个整数向上溢出漏洞(在分析此漏洞时,误以为此漏洞是 MS17-017 公告中的 CVE-2017-0101 漏洞,近期根据 @MJ 的提醒,发现此漏洞不是 CVE-2017-0101 而可能是 CVE-2017-0102 或其他在此公告中隐性修复的漏洞,在此更正,并向给各位读者带来的误导致歉)。分析的环境是 Windows 7 x86 SP1 基础环境的虚拟机,配置 1.5GB 的内存。
稻草小刀
2022/12/12
1.8K0
分析笔记:MS17-017 中的整数溢出漏洞
盘它!PWN栈溢出漏洞。
在国内的CTF比赛中,PWN题最常见考点就是缓冲区溢出漏洞,而缓冲区溢出代表就是栈溢出漏洞。
漏斗社区
2019/03/07
1.1K0
[C语言]初阶指针和结构体
内存:内部存储器,暂存程序/数据——掉电丢失 SRAM,DRAM,DDR,DDR2,DDR3。
IT编程爱好者
2023/04/12
5400
[C语言]初阶指针和结构体
缓冲区溢出之Strcpy和Memcpy
问题:定义三个函数fu'n1,fun2,fun3,不使用嵌入式汇编调用和函数调用,仅仅字符串的操作按顺序调用他们。
FB客服
2020/04/14
2.3K0
缓冲区溢出之Strcpy和Memcpy
经典C语言面试题
1.gets()函数 问:请找出下面代码里的问题: #include<stdio.h> int main(void)  {  char buff[10];      memset(buff,0,sizeof(buff));      gets(buff);      printf("\n The buffer entered is [%s]\n",buff);  return 0;  }  答:上面代码里的问题在于函数gets()的使用,这个函数从stdin接收一个字符串而不检查它所复制的
猿人谷
2018/01/17
2.9K0
SEED:缓冲区溢出漏洞实验
前言:本文是基于美国雪城大学的seed实验所做的缓冲区溢出实验,笔者在进行实验的时候参考了网上已有的部分博客,但是发现存在部分细节没有详细解释,导致实验过程中难以复现上述攻击。因此重新梳理了整个实验过程,涉及原理的内容不再赘述,详见下面链接中提供的实验说明,希望对各位读者起到一定帮助。
FB客服
2019/12/23
1.4K0
SEED:缓冲区溢出漏洞实验
网络攻防实验之缓冲区溢出攻击
3、新建一个C++ Source File,文件名为server,作为服务器。
全栈程序员站长
2022/09/14
7830
12个有趣的C语言面试题
摘要:12个C语言面试题,涉及指针、进程、运算、结构体、函数、内存,看看你能做出几个!
阳光岛主
2022/01/10
8390
经典C面试题
摘要:12个C语言面试题,涉及指针、进程、运算、结构体、函数、内存,看看你能做出几个!
全栈程序员站长
2022/07/12
7520
相关推荐
网络攻防实战技术之——缓冲区溢出篇
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验