整数溢出实验

视频链接:


 课程编写


类别


内容


实验课题名称


整数溢出实验


实验目的与要求


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

了解整数溢出的常见类型

掌握整数溢出的基本原理

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


实验环境


VPC1(虚拟PC)


Windows XP操作系统


软件描述


命令行窗口

实验代码


预备知识


1、整数及整数溢出

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

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

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

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

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

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

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,函数执行之后程序当然就只有崩溃了。无符号整数的上溢问题也不难理解,示例代码如下:

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.符号的问题

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

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 位)的时候可能产生的。同样来看一个例子:

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这样的大内存操作,会发生段错误。


实验内容


介绍与整数溢出相关的基本概念

掌握各种常见整数溢出的原理

编程模拟不同类型的整数溢出


实验步骤


1、打开控制台,进入虚拟环境。

2、 编程模拟 Widthness 整数溢出

步骤 1:“开始”“运行”,对话框中输入“cmd”进入命令行。

步骤 2:可查看d:\tools\51elab5008B中width1.c的代码如下:

/* 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:在命令行中输入如下内容,查看运行结果:

3、模拟整数运算(Arithmetic) 溢出

步骤 1:“开始”“运行”,对话框中输入“cmd”进入命令行。

步骤 2:可查看d:\tools\51elab5008B中arithoverflow.c的代码如下:

/* 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;

}

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

4、模拟符号问题导致的缓冲区溢出

步骤 1:“开始”“运行”,对话框中输入“cmd”进入命令行。

步骤 2:可查看d:\tools\51elab5008B中sigoverflow.c的代码如下:

#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;

}

步骤 3:编译运行,结果如下所示:

原文地址:https://www.cnblogs.com/nul1/p/10859443.html

时间: 2024-11-05 23:25:31

整数溢出实验的相关文章

缓冲区溢出分析第11课:整数溢出的原理

<缓冲区溢出分析>这一系列的内容是我为"i春秋"(www.ichunqiu.com)所录制的同名视频课程的讲稿汇总.每次我都是在写完课程的文档后,再依据文档内容进行课程的讲解.而本系列的内容也是从零开始,来给大家由浅入深地进行缓冲区溢出漏洞的讲解.整个课程是理论与实践相结合,每讲完几个基础理论后,都会配以实际的软件中的漏洞进行分析,以帮助大家更好地理解漏洞的原理.有兴趣的朋友可以结合本文与配套视频进行学习. 前言 我们之前所研究的漏洞,都是非常经典的栈溢出漏洞,也是最为常见

BEC合约整数溢出漏洞还原与分析

一.币圈一秒,人间一年 有道是币圈一日,人间一年.这个说法又得升级了,叫币圈一秒,人间一年. 前不久,币圈又出大事啦.BEC智能合约被爆出整数溢出漏洞,导致黑客能无限印币,在一次交易中,也就那么几秒钟的事情,黑客就“无中生有”地给两个账户转了天文数字般的BEC币,而原账户一分BEC币都没损失.大家来围观下这笔交易: https://etherscan.io/tx/0xad89ff16fd1ebe3a0a7cf4ed282302c06626c1af33221ebe0d3a470aba4a660f

整数溢出漏洞小结

有无符号数是CPU架构决定的,是硬件特性直接反映到汇编指令中.C语言忠实的展现了汇编的特性. 无符号数比较: ja.jae.jb.jbe.je或jne 小于.小于等于.等于.不等于.大于或大于等于: 有符号数比较: 则使用jl.jle.je.jne.jg.jge指令 小于.小于等于.等于.不等于.大于或大于等于: 无符号:十六进制表示 有符号:补码表示 无符号与有符号转换: 基本原则:保证底层的位模式保持不变 导致的问题:有符号数赋给无符号数之后,会从-1变成4294967295(导致溢出) (

CSAPP缓冲区溢出实验记录(一)

题目说明: 开启漏洞之旅,从基础做起.近日,下载了CMU为<深入理解计算机系统>(CSAPP)一书教学配合的缓冲区溢出实验Buffer Bomb,重温了栈溢出的原理. 题目提供了一个有漏洞溢出的程序bufbomb,包括五个Level,在每个Level中要求返回指定的函数.修改全局变量.执行Shellcode等,难度逐渐递增.为保证实验者作业的唯一性,实验提供了程序makecookie,生成指定用户名的cookie,在实验中将会用到这个cookie值.在我的机器上, [email protect

SEED缓冲区溢出实验笔记

缓冲区溢出实验(Linux 32位) 参考教程与材料:http://www.cis.syr.edu/~wedu/seed/Labs_12.04/Software/Buffer_Overflow/ (本文记录了做SEED缓冲区溢出实验的体会与问题,侧重实践,而不是讲解缓冲区溢出原理的详细教程) 1. 准备工作 使用SEED ubuntu虚拟机进行缓冲区溢出实验,首先要关闭一些针对此攻击的防御机制来简化实验. (1)内存地址随机化(Address Space Randomization):基于Lin

Java运行时环境JPEGImageWriter.writeImage函数整数溢出漏洞_

在使用PDFBOX的接口,代码如下: PDFImageWriter imageWriter = new PDFImageWriter(); imageWriter.writeImage(pdDoc, imageType, null, startPage, endPage, imageFilePath, 1, Constants.NUM_TWO_HUNDRED),发现图片生成了,但是报内存溢出错误.后面看了下源代码搜寻相关资料发现存在这样一个问题,所以更换JDK就OK了. Java运行时环境的JP

暂停交易?ERC20合约整数溢出安全漏洞案例技术分析(一)

区块链兄弟社区,区块链技术专业问答先行者,中国区块链技术爱好者聚集地 作者:吴寿鹤,<区块链开发实战--以太坊关键技术与案例分析>的第一作者,<区块链开发实战--Hyperledger Fabric关键技术与案例分析>联合作者,IONChain 离子链 首席架构师,hyperLedger核心项目开发人员,区块链技术社区-区块链兄弟联合创始人.github: https://github.com/gcc2ge 来源:区块链兄弟,国内第一家专注区块链技术分享实战的公益性媒体社区 原文链

2017-2018-2 20179215《网络攻防实践》seed缓冲区溢出实验

seed缓冲区溢出实验 有漏洞的程序: /* stack.c */ /* This program has a buffer overflow vulnerability. */ /* Our task is to exploit this vulnerability */ #include <stdlib.h> #include <stdio.h> #include <string.h> int bof(char *str) { char buffer[12]; /*

使用Linux进行缓冲区溢出实验的配置记录

在基础的软件安全实验中,缓冲区溢出是一个基础而又经典的问题.最基本的缓冲区溢出即通过合理的构造输入数据,使得输入数据量超过原始缓冲区的大小,从而覆盖数据输入缓冲区之外的数据,达到诸如修改函数返回地址等目的.但随着操作系统和编译器针对缓冲区溢出问题引入防护机制,初学者想要由简入繁的学习和实践缓冲区溢出的原理变得困难.在 Linux 环境下,用户可以通过设置编译和系统环境来去除某些防护措施,从而方便的完成某些简单的缓冲区溢出实验. 1.关闭SSP( Stack Smashing Protector