BoF en inet_network(), afecta a Servidor DNS: BIND

Bien, recientemente he empesado a ver en la lista de SECURITY ADVISORIES de FreeBSD, la cual normalmente no veia, sin embargo quiero ser un buen adminsitrador del sistema que utilizo. wink y estar al dia con las actulizaciones grin. he visto que hay algunos bugs, ya descubiertos con todo y parche. Obviamente anuncian esto cuando ya se tiene el parche tongue, pero bueno el Motivo de este mensaje es el siguente:

Ver si somos o mas bien soy capaz de construir un exploit para dicha Vulnerabilidad, he hecho exploits para programas sencillos, y BoF bien ubicados, pero de ahi en mas no lo he hecho con aplicaciones complejas.

Por si alguien me quiere ayudar... se lo agradecere de antemano.



Bien los link de bug que me intereso son los siguentes:


Ahora para los que no sepen y quieran enterarse, BIND, es un Servidor DNS muy extendido hoy en dia, con la ayuda de este, ustedes pueden entrar a google, o al foro.

Mas informacion en BIND by Wikipedia

La funcion donde se encuentra la falla, es una funcion estandar en libc, esto quiere decir y por si no vieron los primeros Links, FreeBSD no es el unico Afectado por esto, tambien hay muchas Versiones de Linux, UNIX, etc. Y ademas todas las versiones del Servidor BIND, hasta ultima version de 22/01/2008.

La pagina de BIND, considera esto como un Riesgo de Seguridad Bajo, y tienen Razon, el parche ya existe, pero cuantos son los Administradores de Sistemas (me Incluyo) que pocas veces (si no es que ninguna) han aplicado parches de seguridad.

La falla Esta en la funcion inet_network(), la cual es usada por BIND.

he hecho un archivo para testearla, pero no consigo burlarla, pero bueno ya que, aqui esta mi codigo de test, creo yo que asi se puede testear. que alguien con mas experiencia me corrija si es que me equivoco.

test_network.c
Código
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc,char *argv[]) {
char *host = (argc > 1) ? argv[1] : "192.168.0.1";
in_addr_t net = inet_network(host);
printf("0x%x\n",net);
return 0;
}

Ahora, todos los links que mostre muestran que si tratas de explotar dicho bug, y fallas ocacionarias un DoS a los usuarios legitimos del servidor. Pero si das en el punto exacto podras ejecutar codigo arbitrario en la maquina remota. lo cual te puede permitir el acceso al servidor.

Successfully exploiting this issue may allow attackers to execute arbitrary machine code in the context of applications that use the affected library. Failed exploit attempts may crash applications, denying service to legitimate users.

He instaldo el servidor BIND en una maquina de prueba para ir probando los avances en la aplicacion mas Afectada por este BoF.



Bien ahora estoy analizando la funcion Vulnerable, cabe mencionar que es casi la misma en mi sistema FreeBSD que la que trae incluida el Servidor BIND.

Código
u_long
inet_network(cp)
register const char *cp;
{
register u_long val, base, n, i;
register char c;
u_long parts[4], *pp = parts;
int digit;

again:
val = 0; base = 10; digit = 0;
if (*cp == '0')
digit = 1, base = 8, cp++;
if (*cp == 'x' || *cp == 'X')
base = 16, cp++;
while ((c = *cp) != 0) {
if (isdigit((unsigned char)c)) {
if (base == 8U && (c == '8' || c == '9'))
return (INADDR_NONE);
val = (val * base) + (c - '0');
cp++;
digit = 1;
continue;
}
if (base == 16U && isxdigit((unsigned char)c)) {
val = (val << 4) +
(c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
cp++;
digit = 1;
continue;
}
break;
}
if (!digit)
return (INADDR_NONE);
if (*cp == '.') {
if (pp >= parts + 4 || val > 0xffU)
return (INADDR_NONE);
*pp++ = val, cp++;
goto again;
}
if (*cp && !isspace(*cp&0xff))
return (INADDR_NONE);
*pp++ = val;
n = pp - parts;
if (n > 4U)
return (INADDR_NONE);
for (val = 0, i = 0; i < n; i++) {
val <<= 8;
val |= parts[i] & 0xff;
}
return (val);
}

Lo que he hecho es lo siguiente.
  • Instalar BIND en la Computadora de prueba con la opcion -g
Esto es para mayor depuracion del mismo.
  • Active la creacion de archivos core en el sistema de prueba
Esto es por si la aplicacione se llega a caer en alguna de las pruebas, poder analizar esto mejor.
  • Agregar a mi ejemplo test_network.c, la funcion Vulnerable.
La agrege con otro nombre esto para poderlo compilar con la opcion -g -static para poder depurarlo sin tener que terner el server abierto.

Asi mi codigo para testear la funcion vulnerable queda asi.

Código
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

in_addr_t inet_networkbuf(const char *cp);

int main(int argc,char *argv[]) {
char *host = (argc > 1) ? argv[1] : "192.168.0.1";
in_addr_t net = inet_networkbuf(host);
printf("0x%x\n",net);
return 0;
}

in_addr_t
inet_networkbuf(cp)
const char *cp;
{
in_addr_t val, base, n;
char c;
in_addr_t parts[4], *pp = parts;
int i, digit;

again:
val = 0; base = 10; digit = 0;
if (*cp == '0')
digit = 1, base = 8, cp++;
if (*cp == 'x' || *cp == 'X')
base = 16, cp++;
while ((c = *cp) != 0) {
if (isdigit((unsigned char)c)) {
if (base == 8U && (c == '8' || c == '9'))
return (INADDR_NONE);
val = (val * base) + (c - '0');
cp++;
digit = 1;
continue;
}
if (base == 16U && isxdigit((unsigned char)c)) {
val = (val << 4) +
(c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
cp++;
digit = 1;
continue;
}
break;
}
if (!digit)
return (INADDR_NONE);
if (*cp == '.') {
if (pp >= parts + 4 || val > 0xffU)
return (INADDR_NONE);
*pp++ = val, cp++;
goto again;
}
if (*cp && !isspace(*cp&0xff))
return (INADDR_NONE);
*pp++ = val;
n = pp - parts;
if (n > 4U)
return (INADDR_NONE);
for (val = 0, i = 0; i < n; i++) {
val <<= 8;
val |= parts[i] & 0xff;
}
return (val);
}

Como vemos la unica diferencia entre la funcion existemente en FreeBSD y la del Servidor BIND, es que BIND declara las variables mas utilizadas como register, esto es para que sea mas efeciente. Lo cual me da a entender que va a ser un poco diferente la Explotacion de la funcion inet_network(), dentro de aplicaciones comunes de FreeBSD, que la del Servidor BIND.

Comentarios

Entradas populares de este blog

Clave WPA2 por Defecto de equipos TotalPlay (Huawei HG8245H)

Cable modem Ubee - WPA2 y WPS por defecto