Tengo el siguiente pseudo código resumido en C89 de una biblioteca de servidor ssh que proporciona solo acceso a cosas como git-shell ( /bin/bash
se reemplaza con el programa que se ejecuta, por lo que no es posible hacer otra cosa ) :
struct _raw_uncapped_ssh_string { // no limit on the size of the string;
uint32_t len;
char non_null_terminated_string[]; // by protocol design it have a minimum length of 1
};
typedef struct _raw_uncapped_ssh_string raw_ssh_string;
union buffer {
void * uncapped_zlib_decompressed_network_data;
// yes, the size is uncapped, so it’s possible to put 4Gb of
// data in it that would be copied later into memory. zlib
// allow easily to turn some Mb in Gb of data, but it’s not
// the point of the question.
raw_ssh_string st;
};
get_command (compressed_network_data) {
size_t len;
char * command;
buffer string=uncompress_to_buffer(compressed_network_data);
len=ntohl(string.st.len)+1;
command=malloc(len+1);
command[len]=0;
// here’s the point, both the string length and content as
// well it’s supplied size is controlled by the attacker.
memcpy(command,string.st.data,len);
return command;
}
Aquí se explica cómo se ejecuta el comando más tarde (la cadena command
no se modifica después de get_command()
) .
const char *args[]={"/bin/bash",command,NULL}; // /bin/bash isn’t the shell, it has been replaced by git‑shell.
// redirect the program output to the network.
dup2(stdin, 0);
dup2(stdout,1);
dup2(stdout,2);
close(stdin);
close(stdout);
//if this return execution failed and print an error message
return execv(args[0],(char * const *)args); // I don’t know which is the system, so I can’t know about the libc behaviour.
No puedo hacer memcpy(command,string.st.data,0)
ya que el tercer miembro de memcpy
tiene un tamaño mínimo de 1, y en mi contexto, size_t
usa un entero de 64 bits, no puedo realizar un desbordamiento de búfer, ya que hay len
.
Todo lo que puedo hacer es establecer len
en un valor mayor que el asignado a string.st.data
. Este es un flujo insuficiente de búfer que me permite leer la memoria no asignada.
Puedo leer la memoria del servidor, sin embargo, no puedo ver qué datos confidenciales puede contener un servidor ssh público (en mi caso, la lista de usuarios que pueden realizar ssh es pública) .
Entonces, ¿un flujo insuficiente de búfer en memcpy
permite la ejecución remota de código?