整数溢出实验报告

 

一、实验原理

(1)计算机中,整数用补码来表示,分为有符号整数和无符号整数。有符号整数最高位为符号位,1表示负数,0表示整数。无符号数没有符号位,只表示整数。将一个负的有符号数赋给无符号数,可能会变成一个很大的数。

(2)一个整数通过运算(加减、赋值等),超出了它的数据类型所能表示的范围,就会发生溢出。如:一个整数存入比它小的存储空间时,超出了类型所能表示的范围,就会发生溢出,高位会被丢弃(即截断)。

 

各种整数类型占有的字节数和表示范围如下。

整数溢出漏洞 java 整数溢出漏洞实验_反汇编

 

 

 

 

 

 

 

二、intof的利用

.1..查看反汇编代码

整数溢出漏洞 java 整数溢出漏洞实验_补码_02

画出栈图:

整数溢出漏洞 java 整数溢出漏洞实验_补码_03

 

2. 说明

head_len是16,buf区长度是68字节,程序让用户输入data_len,然后检查hean_len和data_len的和是否小于等于64,不超过64则接收data_len个字节输入,写入到buf处(从buf [head_len]开始写)。然后程序检查v9所在的起始字节是否为空,若不为空,则输出Your win。

 

3. 利用整数溢出漏洞

表面上看,用户只能输入64-16=48字节的内容,但其实,read函数的第三个参数是无符号数,因而给它传一个负的有符号数,会变成较大的正整数。而data_len和head_len都是有符号的int类型。head_len与一个负的data_len相加,结果必然小于64,程序必然会调用read,且可接收超过48个字节的输入。

 

如先输入-1(补码为0xffffffff),传给read函数,则read的第三个参数会变成它的数据类型所能表示的最大值。再输入超过48字节的内容,按回车,写入栈的内容就可溢出buf区了,就可修改v9所在的字节了。(实际上输入48个字节再按回车就可以了,因为换行符也会被写入)。

 

整数溢出漏洞 java 整数溢出漏洞实验_反汇编_04

 

 

 

 

 

 

 

二、int_overflow0的利用

 

通过整数溢出修改变量,使其输出You get 20 points!

 

查看反汇编代码

整数溢出漏洞 java 整数溢出漏洞实验_整数溢出漏洞 java_05

 

画出栈图

整数溢出漏洞 java 整数溢出漏洞实验_main函数_06

 

用户先输入size的大小,程序再接收size字节的输入,然后检查v7和v6的值,若v7等于-558907665,v6等于195951310,则输出You get 20 points!

 

V7和v6都是有符号int类型,有符号int类型下,-558907665的补码表示是0xdeafbeef,195951310的补码表示是0xbadface。

 

利用脚本(my0.py)

先发送32给size,让程序能接收32个字节。

再发送字符串给read函数接收:发送24个A填充buf区、size所在的4字节,发送0xbadface填充v6,发送0xdeafbeef填充v7,就能通过判断了。

整数溢出漏洞 java 整数溢出漏洞实验_整数溢出漏洞 java_07

运行结果:

整数溢出漏洞 java 整数溢出漏洞实验_整数溢出漏洞 java_08

三、int_overflow1的利用

 

1. 通过整数溢出修改变量,使程序输出You get another 20 points

 

查看源代码:

整数溢出漏洞 java 整数溢出漏洞实验_main函数_09

 

程序先接收一个有符号int型存到size,然后调用check函数检查size是否小于100,若不是,告知用户size太大,退出程序。若size小于100,则接收size字节的内容写到buf,最后检查magic的值是否等于0xdeadbeef,若等于,输出You get another 20 points。

 

main的部分反汇编代码:

整数溢出漏洞 java 整数溢出漏洞实验_反汇编_10

 

 

画出栈图:

整数溢出漏洞 java 整数溢出漏洞实验_补码_11

整数溢出漏洞 java 整数溢出漏洞实验_整数溢出漏洞 java_12

 

运行结果:

整数溢出漏洞 java 整数溢出漏洞实验_反汇编_13

 

 

 

 

2. 利用整数溢出和缓冲区溢出,使程序执行backdoor函数。

 

size的输入和上一题一样,使程序能进入read函数。

关键是修改main函数的ret_addr处的值,使其为backdoor函数的起始地址(0x804855a)。

 

整数溢出漏洞 java 整数溢出漏洞实验_整数溢出漏洞 java_14

 

main函数的部分反汇编代码:

整数溢出漏洞 java 整数溢出漏洞实验_反汇编_15

整数溢出漏洞 java 整数溢出漏洞实验_main函数_16

整数溢出漏洞 java 整数溢出漏洞实验_反汇编_17

 

注意到,函数最后将old_ebx的值弹出给ebx寄存器,再将ebx-4的值赋给esp,故存放main函数返回地址的栈起始地址为old_ebx-4。

 

可以在read(0,buf,size)函数处下断点,查看buf的地址,进而通过x /28xw buf地址查看buf,magic,old_ebx的内容,进而推算存放main函数返回地址处的地址。

 

 

利用过程使用交互模式。

先输入python开启一个python进程,再依次输入下面的命令

整数溢出漏洞 java 整数溢出漏洞实验_main函数_18

按下回车后,在gdb窗口键入c,回车,程序停在read函数处。

整数溢出漏洞 java 整数溢出漏洞实验_整数溢出漏洞 java_19

 

0000处的内容是0, 0004处(红圈标记)是buf的起始地址,0008处是size的值。

查看从buf开始,28个4字节单元存放的内容。

整数溢出漏洞 java 整数溢出漏洞实验_整数溢出漏洞 java_20

整数溢出漏洞 java 整数溢出漏洞实验_补码_21

整数溢出漏洞 java 整数溢出漏洞实验_main函数_22

整数溢出漏洞 java 整数溢出漏洞实验_main函数_23

整数溢出漏洞 java 整数溢出漏洞实验_整数溢出漏洞 java_24

 

再输入conn.interactive(),回车。gdb窗口输入c,回车。

结果如下。出现了You get another 20 points! (有叹号的是backdoor里的)

整数溢出漏洞 java 整数溢出漏洞实验_整数溢出漏洞 java_25

gdb窗口显示进入了/bin/dash

整数溢出漏洞 java 整数溢出漏洞实验_补码_26

gdb窗口键入q退出gdb。

则终端进入了shell,可输入ls,cat,exit等shell命令。

整数溢出漏洞 java 整数溢出漏洞实验_补码_27

 

 

 

 

四、实验总结

通过本次实验,了解了整数溢出漏洞的原理基础及利用。

遇到的问题及解决:

1.做int_overflow0的利用,写了gdb.attach,sendline的内容不能正确写入size,buf,conn.interactive()后不能正确输出。

解决方法:去掉gdb.attach一句。

 

2.int_overflow1的利用,用了各种方法不能进入backdoor函数。

解决方法:查看反汇编代码,发现程序最后将ebx-4赋给了esp,这里的ebx其实是前面压入的old_ebx,ebx-4处才是存放返回地址的。而前面有esp的对齐操作,故buf起始地址和存放ret_addr处的间隔不是固定的。要查看栈里old_ebx的值,需知道buf的地址,而buf的地址可通过在read函数处设断点,查看出来。然后据此推断需要用多少字符填充ret_addr存放处前面的内容,再修改ret_addr。