diff --git a/libr/core/cmd_search.c b/libr/core/cmd_search.c index f399054eab..a31f60b355 100644 --- a/libr/core/cmd_search.c +++ b/libr/core/cmd_search.c @@ -461,18 +461,20 @@ static int cmd_search(void *data, const char *input) { dosearch = R_TRUE; } break; case 'C': { + dosearch = crypto_search = R_TRUE; switch (input[1]) { case 'a': - dosearch = aes_search = crypto_search = R_TRUE; + aes_search = R_TRUE; break; case 'r': - dosearch = rsa_search = crypto_search = R_TRUE; + rsa_search = R_TRUE; break; default:{ + dosearch = crypto_search = R_FALSE; const char* help_msg[] = { "Usage: /C", "", "Search for crypto materials", "/Ca", "" , "Search for AES keys", - "/Cr", "", "Search for RSA keys", + "/Cr", "", "Search for private RSA keys", NULL}; r_core_cmd_help (core, help_msg); } diff --git a/libr/search/rsa-find.c b/libr/search/rsa-find.c index b41b0dbc04..55f79b655d 100644 --- a/libr/search/rsa-find.c +++ b/libr/search/rsa-find.c @@ -1,13 +1,10 @@ // RSAKeyFinder 1.0 (2008-07-18) // By Nadia Heninger and J. Alex Halderman // Contribution to r2 by @santitox -// Integrated by jvoisin +// Integrated and refactored by jvoisin #include -#define NB_PRIVATES_FIELDS 10 -#define NB_PUBLIC_FIELDS 3 - /*Baby BER parser, just good enough for RSA keys. This is not robust to errors in the memory image, but if we added @@ -17,68 +14,62 @@ Parses a single field of the key, beginning at start. Each field consists of a type, a length, and a value. Puts the type of field into type, the number of bytes into len, and returns a pointer to the beginning of the value. */ -static ut8* parse_next_rsa_field(const ut8* start, ut32 *type, ut32 *len) { - ut8 *val = malloc(1); - *type = start[0]; - *len = 0; - if (!(start[1] & 0x80)) { - *len = start[1]; - *val = start[2]; +static const ut8* parse_next_rsa_field(const ut8* start, ut32 *type, ut32 *len) { + type = (ut32*) start; + *len = 0; + if (!(start[1] & 128)) { + len = (ut32*)(start + 1); + return start + 2; } else { int i; - const int lensize = start[1] & 0x7F; + const int lensize = start[1] & 127; for (i=0; i < lensize; i++) *len = (*len << 8) | start[2+i]; - *val = start[2+lensize]; + return start + 2 + lensize; } - return val; } -static int check_rsa_fields(const ut8* start, int nbfields) { - ut32 len = 0, type; +// Check if `start` points to an ensemble of BER fields +static int check_rsa_fields(const ut8* start) { +#define NB_PRIV_FIELDS 10 + ut32 type, len = 0; int i; ut8 const* ptr = start; - ptr = parse_next_rsa_field (ptr, &type, &len); // skip sequence field + + ptr = parse_next_rsa_field (start, &type, &len); // skip sequence field + if (!len || len > 1024) return R_FALSE; - for (i = 0; i < nbfields; i++) + + for (i = 0; i < NB_PRIV_FIELDS; i++) if (!(ptr = parse_next_rsa_field (ptr, &type, &len))) return R_FALSE; + return R_TRUE; } -// Returns a pointer to the beginning of a BER-encoded key by working -// backwards from the given memory map offset, looking for the -// sequence identifier (this is not completely safe) -static int find_rsa_key_start(const ut8 *map, int offset) { - int k; - for (k = offset; k >= 0 && k > offset-20; k--) - if (map[k] == 0x30) - return k; - return 0; -} - -// Finds and prints private (or private and public) keys in the memory -// map by searching for given target pattern +// Finds and return index of private RSA key R_API int r_search_rsa_update(void* s, ut64 from, const ut8 *buf, int len) { - unsigned int i, index; - const ut8 versionmarker[4] = {0x02, 0x01, 0x00, 0x02}; + unsigned int i, k, index; + const ut8 versionmarker[] = {0x02, 0x01, 0x00, 0x02}; + for (i = 0; i < len - sizeof (versionmarker); i++) { if (memcmp (&buf[i], versionmarker, sizeof (versionmarker))) continue; - index = find_rsa_key_start (buf, i); + index = 0; + for (k=i; k >= 0 && k > i - 20; k--) { + if (buf[k] == '0'){ // The sequence identifier is '0' + index = k; + break; + } + } + if (!index) continue; - const ut8* key = buf + index; - if (check_rsa_fields(key, NB_PRIVATES_FIELDS)) { - printf("FOUND PRIVATE KEY AT %x\n", (ut32)(key-buf)); + if (check_rsa_fields(buf + index)) return i; - } else if (check_rsa_fields(key, NB_PUBLIC_FIELDS)) { - printf("FOUND PUBLIC KEY AT %x\n", (ut32)(key-buf)); - return i; - } } return -1; }