diff options
Diffstat (limited to 'Exfiltration/mimikatz-1.0/modules/mod_hive.cpp')
-rw-r--r-- | Exfiltration/mimikatz-1.0/modules/mod_hive.cpp | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/Exfiltration/mimikatz-1.0/modules/mod_hive.cpp b/Exfiltration/mimikatz-1.0/modules/mod_hive.cpp new file mode 100644 index 0000000..a0e79cd --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_hive.cpp @@ -0,0 +1,242 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_hive.h" + +mod_hive::nk_hdr* mod_hive::read_nk(nk_hdr *nk, hive *h, int offset ) +{ + memcpy(nk, h->base + offset + 4, sizeof(nk_hdr)); + nk->key_name = (h->base + offset + 4 + 76); + return nk; +} + +mod_hive::lf_hdr* mod_hive::read_lf(lf_hdr *lf, hive *h, int offset ) +{ + memcpy(lf, h->base+offset+4, sizeof(lf_hdr)); + lf->hr = (h->base+offset+4+4); + return lf; +} + +mod_hive::vk_hdr* mod_hive::read_vk(vk_hdr *vk, hive *h, int offset ) +{ + memcpy(vk, h->base+offset+4, sizeof(vk_hdr)); + vk->value_name = (h->base+offset+4+20); + return vk; +} + +int* mod_hive::read_valuevector(int *value, hive *h, int offset, int size ) +{ + memcpy(value, h->base+offset+4, size*sizeof(int)); + return value; +} + +mod_hive::hashrecord* mod_hive::read_hr(hashrecord *hr, unsigned char *pos, int index ) +{ + pos+=(8*index); + memcpy(hr, pos, sizeof(hashrecord)); + return hr; +} + + +unsigned char* mod_hive::read_data(hive *h, int offset ) +{ + return ((unsigned char*) (h->base + offset + 4)); +} + +bool mod_hive::InitHive(hive *h) +{ + h->base = NULL; + return true; +} + +bool mod_hive::RegOpenHive(const wchar_t *filename, hive *h) +{ + bool reussite = false; + FILE *hiveh; + unsigned long hsize; + + if(_wfopen_s(&hiveh, filename, L"rb" ) == 0) + { + if(fseek(hiveh, 0, SEEK_END) == 0) + { + hsize = ftell(hiveh); + h->base = new unsigned char[hsize]; + fseek(hiveh, 0, SEEK_SET); + + if(fread(h->base, hsize, 1, hiveh) == 1) + { + reussite = *((int *)h->base) == 0x66676572; + } + } + fclose(hiveh); + } + return reussite; +} + +bool mod_hive::RegCloseHive(hive *h ) +{ + if(h->base != NULL) + { + delete[] h->base; + } + return true; +} + + +long mod_hive::parself(hive *h, char *t, unsigned long off ) +{ + nk_hdr *n; + lf_hdr *l; + hashrecord *hr; + + int i; + + hr = (hashrecord*) malloc(sizeof(hashrecord)); + n = (nk_hdr*) malloc(sizeof(nk_hdr)); + l = (lf_hdr*) malloc(sizeof(lf_hdr)); + l = read_lf(l, h, off ); + + for(i = 0; i < l->key_num; i++ ) + { + hr = read_hr(hr, l->hr, i); + n = read_nk(n, h, hr->nk_offset + 0x1000 ); + if(!memcmp( t, n->key_name, n->name_len ) && (strlen(t) == n->name_len)) + { + free(n); + free(l); + return hr->nk_offset; + } + } + free(n); + free(l); + return -1; +} + +bool mod_hive::RegGetRootKey(hive *h, string *root_key) +{ + bool reussite = false; + nk_hdr * n = new nk_hdr(); + read_nk(n, h, 0x1020); + if (n->id == NK_ID && n->type == NK_ROOT) + { + root_key->assign((const char *) n->key_name, n->name_len); + reussite = true; + } + delete n; + return reussite; +} + +bool mod_hive::RegOpenKey(hive *h, string * path, nk_hdr **nr) +{ + bool reussite = false; + + nk_hdr *n = new nk_hdr(); + char *t, *tpath; + unsigned long noff = 0; + + read_nk(n, h, 0x1020); + + if(n->id == NK_ID && n->type == NK_ROOT) + { + tpath = strdup(path->c_str()); + t = strtok(tpath, "\\"); + + if(!memcmp(t, n->key_name, n->name_len)) + { + t = strtok(NULL, "\\"); + while(t != NULL) + { + noff = parself(h, t, n->lf_off + 0x1000); + if(noff != -1) + { + read_nk(n, h, noff + 0x1000); + t = strtok( NULL, "\\" ); + } + else + { + break; + } + } + + if(t == NULL && noff != 1) + { + memcpy(*nr, n, sizeof(nk_hdr)); + reussite = true; + } + } + free(tpath); + } + + delete n; + return reussite; +} + +bool mod_hive::RegQueryValue(hive *h, string *name, nk_hdr *nr, unsigned char **buff, int *len ) +{ + bool reussite = false; + + vk_hdr *v = new vk_hdr(); + int * l = new int[nr->value_cnt]; + + read_valuevector(l, h, nr->value_off + 0x1000, nr->value_cnt); + + for(unsigned int i = 0; i < nr->value_cnt; i++) + { + read_vk(v, h, l[i] + 0x1000); + if((!memcmp(name->c_str(), v->value_name, name->size()) && v->name_len == name->size()) || (name == NULL && (v->flag & 1) == 0)) + { + *len = v->data_len & 0x0000FFFF; + *buff = new unsigned char[*len]; + if (*len < 5) + { + memcpy(*buff, &(v->data_off), *len); + } + else + { + memcpy(*buff, read_data(h, v->data_off + 0x1000), *len); + } + reussite = true; + break; + } + } + delete[] l; + delete v; + return reussite; +} + +bool mod_hive::RegOpenKeyQueryValue(hive *h, string *path, string *name, unsigned char **buff, int *len) +{ + bool reussite = false; + mod_hive::nk_hdr * nodeKey = new mod_hive::nk_hdr(); + if(mod_hive::RegOpenKey(h, path, &nodeKey)) + { + reussite = mod_hive::RegQueryValue(h, name, nodeKey, buff, len); + } + delete nodeKey; + return reussite; +} + + + +bool mod_hive::RegEnumKey(hive *h, nk_hdr *nr, vector<string> * names) +{ + int index = 0; + + lf_hdr *lf = new lf_hdr(); + nk_hdr *nk = new nk_hdr(); + hashrecord *hr = new hashrecord(); + + while(index < nr->subkey_num) + { + lf = read_lf(lf, h, nr->lf_off + 0x1000 ); + hr = read_hr(hr, lf->hr, index); + nk = read_nk(nk, h, hr->nk_offset + 0x1000 ); + names->push_back(string(reinterpret_cast<char *>(nk->key_name), nk->name_len)); + index++; + } + + delete lf, nk, hr; + return !names->empty(); +} |