Ho il seguente pseudo-codice riepilogato in C89 da una libreria server ssh che fornisce solo l'accesso a cose come git-shell ( /bin/bash
è sostituito con il programma da eseguire, quindi non è possibile fare qualcos'altro ) :
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;
}
Ecco come viene eseguito il comando più tardi (la stringa command
è invariata dopo 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.
Non posso fare memcpy(command,string.st.data,0)
dal momento che il terzo membro di memcpy
ha una dimensione minima di 1, e nel mio contesto, size_t
usa un intero a 64 bit, non posso eseguire un buffer overflow, poiché c'è len
.
Tutto quello che posso fare è impostare len
su un valore maggiore di quello assegnato a string.st.data
. Questo è un underflow del buffer che mi consente di leggere la memoria non allocata.
Posso leggere la memoria del server, tuttavia, non riesco a vedere quali dati sensibili un server ssh pubblico può contenere (nel mio caso l'elenco di utenti che possono eseguire ssh è pubblico) .
Così un underflow del buffer su memcpy
consente l'esecuzione di codice in modalità remota?