¿Se puede escanear un ejecutable en busca de llamadas a las funciones vulnerables del fantasma de glibc?

1

La vulnerabilidad fantasma tiene el potencial de ser vulnerable a muchas piezas de software que llaman a las funciones gethostbyname () y gethostbyname2 (). ¿Hay una manera fácil de escanear un ejecutable para determinar si utiliza alguna de estas dos funciones vulnerables? Si bien esto no le diría si un programa era vulnerable, puede decirle si NO es vulnerable.

Para usar cualquiera de estas funciones, creo que el ejecutable (o la biblioteca de terceros) debe vincularse a él. Me parece que debería poder escanear el archivo ejecutable en busca de un enlace a la biblioteca compartida.

    
pregunta Steve Sether 30.01.2015 - 22:44
fuente

2 respuestas

1

Para averiguar si se utilizan estas llamadas, simplemente puede hacer un

strings -a /bin/ip | grep gethost

Otro enfoque que devuelve más información es

readelf --dyn-syms /bin/ip | grep gethost
    
respondido por el ott-- 31.01.2015 - 21:08
fuente
0

Sí, hay algunas formas de obtener la información, nm y objdump son tus amigos.

Demo

Para fines de demostración, he usado un PoC desarrollado por la Universidad de Chicago para probar si un sistema es vulnerable o no a la vulnerabilidad Ghost .

Aquí está el código:

/*
 * GHOST vulnerability check
 * http://www.openwall.com/lists/oss-security/2015/01/27/9
 * Usage: gcc GHOST.c -o GHOST && ./GHOST
 */ 

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

#define CANARY "in_the_coal_mine"

struct {
  char buffer[1024];
  char canary[sizeof(CANARY)];
} temp = { "buffer", CANARY };

int main(void) {
  struct hostent resbuf;
  struct hostent *result;
  int herrno;
  int retval;

  /*** strlen (name) = size_needed - sizeof (*host_addr) - sizeof (*h_addr_ptrs) - 1; ***/
  size_t len = sizeof(temp.buffer) - 16*sizeof(unsigned char) - 2*sizeof(char *) - 1;
  char name[sizeof(temp.buffer)];
  memset(name, '0', len);
  name[len] = '
$ gcc GHOST.c -o ghost
'; retval = gethostbyname_r(name, &resbuf, temp.buffer, sizeof(temp.buffer), &result, &herrno); if (strcmp(temp.canary, CANARY) != 0) { puts("vulnerable"); exit(EXIT_SUCCESS); } if (retval == ERANGE) { puts("not vulnerable"); exit(EXIT_SUCCESS); } puts("should not happen"); exit(EXIT_FAILURE); }

Luego compile el código para generar el binario:

/*
 * GHOST vulnerability check
 * http://www.openwall.com/lists/oss-security/2015/01/27/9
 * Usage: gcc GHOST.c -o GHOST && ./GHOST
 */ 

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

#define CANARY "in_the_coal_mine"

struct {
  char buffer[1024];
  char canary[sizeof(CANARY)];
} temp = { "buffer", CANARY };

int main(void) {
  struct hostent resbuf;
  struct hostent *result;
  int herrno;
  int retval;

  /*** strlen (name) = size_needed - sizeof (*host_addr) - sizeof (*h_addr_ptrs) - 1; ***/
  size_t len = sizeof(temp.buffer) - 16*sizeof(unsigned char) - 2*sizeof(char *) - 1;
  char name[sizeof(temp.buffer)];
  memset(name, '0', len);
  name[len] = '
$ gcc GHOST.c -o ghost
'; retval = gethostbyname_r(name, &resbuf, temp.buffer, sizeof(temp.buffer), &result, &herrno); if (strcmp(temp.canary, CANARY) != 0) { puts("vulnerable"); exit(EXIT_SUCCESS); } if (retval == ERANGE) { puts("not vulnerable"); exit(EXIT_SUCCESS); } puts("should not happen"); exit(EXIT_FAILURE); }

Probar si un binario sin tirar contiene gethostbyname* símbolos: %código% ... y seguro que sí.

Ahora, también es posible que el binario haya sido despojado de los símbolos de depuración:

$ nm ghost | grep gethost U gethostbyname_r@@GLIBC_2.2.5

En ese caso, puedes usar # stripping away debug symbols $ strip -o ghost-stripped ghost $ nm ghost-stripped nm: ghost-stripped: no symbols : objdump

... filtrar solo lo que estamos buscando: $ objdump -T ghost-stripped ghost-stripped: file format elf64-x86-64 DYNAMIC SYMBOL TABLE: ... 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 gethostbyname_r ...

    
respondido por el fduff 01.02.2015 - 21:27
fuente

Lea otras preguntas en las etiquetas