📄 chntpw.c
字号:
int ntpw_len,lmpw_len,ntpw_offs,lmpw_offs,i; int dontchange = 0; struct user_V *v; des_key_schedule ks1, ks2; des_cblock deskey1, deskey2; MD4_CTX context; unsigned char digest[16]; unsigned short acb; v = (struct user_V *)buf; vp = buf; username_offset = v->username_ofs; username_len = v->username_len; fullname_offset = v->fullname_ofs; fullname_len = v->fullname_len; comment_offset = v->comment_ofs; comment_len = v->comment_len; homedir_offset = v->homedir_ofs; homedir_len = v->homedir_len; lmpw_offs = v->lmpw_ofs; lmpw_len = v->lmpw_len; ntpw_offs = v->ntpw_ofs; ntpw_len = v->ntpw_len;#if 0 printf("lmpw_offs: 0x%x, lmpw_len: %d (0x%x)\n",lmpw_offs,lmpw_len,lmpw_len); printf("ntpw_offs: 0x%x, ntpw_len: %d (0x%x)\n",ntpw_offs,ntpw_len,ntpw_len);#endif *username = 0; *fullname = 0; *comment = 0; *homedir = 0; if(username_len <= 0 || username_len > vlen || username_offset <= 0 || username_offset >= vlen || comment_len < 0 || comment_len > vlen || fullname_len < 0 || fullname_len > vlen || homedir_offset < 0 || homedir_offset >= vlen || comment_offset < 0 || comment_offset >= vlen || lmpw_offs < 0 || lmpw_offs >= vlen) { if (stat != 1) printf("Not a legal struct? (negative struct lengths)\n"); return(NULL); } /* Offsets in top of struct is relative to end of pointers, adjust */ username_offset += 0xCC; fullname_offset += 0xCC; comment_offset += 0xCC; homedir_offset += 0xCC; ntpw_offs += 0xCC; lmpw_offs += 0xCC; cheap_uni2ascii(vp + username_offset,username,username_len); cheap_uni2ascii(vp + fullname_offset,fullname,fullname_len); cheap_uni2ascii(vp + comment_offset,comment,comment_len); cheap_uni2ascii(vp + homedir_offset,homedir,homedir_len); #if 0 /* Reset hash-lengths to 16 if syskey has been reset */ if (syskeyreset && ntpw_len > 16 && !stat) { ntpw_len = 16; lmpw_len = 16; ntpw_offs -= 4; (unsigned int)*(vp+0xa8) = ntpw_offs - 0xcc; *(vp + 0xa0) = 16; *(vp + 0xac) = 16; }#endif if (stat) { acb = handle_F(rid,0); printf("RID: %04x, Username: <%s>%s\n", rid, username, ( acb & 0x8000 ? ", *disabled or locked*" : (ntpw_len < 16) ? ", *BLANK password*" : "") ); return(username); } printf("RID : %04d [%04x]\n",rid,rid); printf("Username: %s\n",username); printf("fullname: %s\n",fullname); printf("comment : %s\n",comment); printf("homedir : %s\n\n",homedir); acb = handle_F(rid,2); if (lmpw_len < 16) { printf("** LANMAN password not set. User MAY have a blank password.\n** Usually safe to continue\n"); } if (ntpw_len < 16) { printf("** No NT MD4 hash found. This user probably has a BLANK password!\n"); if (lmpw_len < 16) { printf("** No LANMAN hash found either. Sorry, cannot change. Try login with no password!\n"); dontchange = 1; } else { printf("** LANMAN password IS however set. Will now install new password as NT pass instead.\n"); printf("** NOTE: Continue at own risk!\n"); ntpw_offs = lmpw_offs; (unsigned int)*(vp+0xa8) = ntpw_offs - 0xcc; ntpw_len = 16; lmpw_len = 0; } } if (!rid) { printf("No RID given. Unable to change passwords..\n"); return(0); } if (gverbose) { hexprnt("Crypted NT pw: ",(vp+ntpw_offs),16); hexprnt("Crypted LM pw: ",(vp+lmpw_offs),16); } /* Get the two decrpt keys. */ sid_to_key1(rid,(unsigned char *)deskey1); des_set_key((des_cblock *)deskey1,ks1); sid_to_key2(rid,(unsigned char *)deskey2); des_set_key((des_cblock *)deskey2,ks2); /* Decrypt the NT md4 password hash as two 8 byte blocks. */ des_ecb_encrypt((des_cblock *)(vp+ntpw_offs ), (des_cblock *)md4, ks1, DES_DECRYPT); des_ecb_encrypt((des_cblock *)(vp+ntpw_offs + 8), (des_cblock *)&md4[8], ks2, DES_DECRYPT); /* Decrypt the lanman password hash as two 8 byte blocks. */ des_ecb_encrypt((des_cblock *)(vp+lmpw_offs), (des_cblock *)lanman, ks1, DES_DECRYPT); des_ecb_encrypt((des_cblock *)(vp+lmpw_offs + 8), (des_cblock *)&lanman[8], ks2, DES_DECRYPT); if (gverbose) { hexprnt("MD4 hash : ",md4,16); hexprnt("LANMAN hash : ",lanman,16); } printf("\n* = blank the password (This may work better than setting a new password!)\n"); /* printf("@ = promote user to administrator\n"); */ printf("Enter nothing to leave it unchanged\n"); pl = fmyinput("Please enter new password: ",newp,16); /* printf("password: [%s] have length %d\n",newp,pl); */ if (!pl) { printf("Nothing changed.\n"); return(0); } if (pl == 1 && *newp == '*') { printf("Blanking password!\n"); } else if (pl == 1 && *newp == '@') { promote_user(rid); printf("Changes saved!\n"); return(username); } else { cheap_ascii2uni(newp,newunipw,pl); make_lanmpw(newp,newlanpw,pl); /* printf("Ucase Lanman: %s\n",newlanpw); */ MD4Init (&context); MD4Update (&context, newunipw, pl<<1); MD4Final (digest, &context); if (gverbose) hexprnt("\nNEW MD4 hash : ",digest,16); E1(newlanpw, x1, lanman); E1(newlanpw+7, x1, lanman+8); if (gverbose) hexprnt("NEW LANMAN hash : ",lanman,16); /* Encrypt the NT md4 password hash as two 8 byte blocks. */ des_ecb_encrypt((des_cblock *)digest, (des_cblock *)despw, ks1, DES_ENCRYPT); des_ecb_encrypt((des_cblock *)(digest+8), (des_cblock *)&despw[8], ks2, DES_ENCRYPT); des_ecb_encrypt((des_cblock *)lanman, (des_cblock *)newlandes, ks1, DES_ENCRYPT); des_ecb_encrypt((des_cblock *)(lanman+8), (des_cblock *)&newlandes[8], ks2, DES_ENCRYPT); if (gverbose) { hexprnt("NEW DES crypt : ",despw,16); hexprnt("NEW LANMAN crypt: ",newlandes,16); } } /* blankit check */ fmyinput("\nDo you really wish to change it? (y/n) [n] ",yn,2); if (*yn == 'y') { if (pl == 1 && *newp == '*') { /* Setting hash lengths to zero seems to make NT think it is blank * However, since we cant cut the previous hash bytes out of the V value * due to missing resize-support of values, it may leak about 40 bytes * each time we do this. */ v->ntpw_len = 0; v->lmpw_len = 0; } else if (pl > 1 && *newp != '@') { if (!dontchange) { /* Reset hash length to 16 if syskey enabled, this will cause * a conversion to syskey-hashes upon next boot */ if (syskeyreset && ntpw_len > 16) { ntpw_len = 16; lmpw_len = 16; ntpw_offs -= 4; (unsigned int)*(vp+0xa8) = ntpw_offs - 0xcc; *(vp + 0xa0) = 16; *(vp + 0xac) = 16; } for (i = 0; i < 16; i++) { (unsigned char)*(vp+ntpw_offs+i) = despw[i]; if (lmpw_len >= 16) (unsigned char)*(vp+lmpw_offs+i) = newlandes[i]; } } else { printf("Unable to set since it is blank.\n"); } }#if 0 hexprnt("Pw in buffer: ",(vp+ntpw_offs),16); hexprnt("Lm in buffer: ",(vp+lmpw_offs),16);#endif dirty = 1; printf("Changed!\n"); } else { printf("Password not changed.\n"); } printf("\n"); return(username);}/* Here we put our knowledge to use, basic routines to * decode and display registry contents almost like a filesystem *//* display (cat) the value, * vofs = offset to 'nk' node, paths relative to this (or 0 for root) * path = path string to value * Does not handle all types yet (does a hexdump instead) * MULTI_SZ (multi unicode-string) - only displays first string, * but also does a hexdump. */void cat_vk(struct hive *hdesc, int nkofs, char *path, int dohex){ void *data; int len,i,type; char string[SZ_MAX+1]; type = get_val_type(hdesc, nkofs, path); if (type == -1) { printf("cat_vk: No such value <%s>\n",path); return; } len = get_val_len(hdesc, nkofs, path); if (!len) { printf("cat_vk: Value <%s> has zero length\n",path); return; } data = (void *)get_val_data(hdesc, nkofs, path, 0); if (!data) { printf("cat_vk: Value <%s> references NULL-pointer (bad boy!)\n",path); abort(); return; } printf("Value <%s> of type %s, data length %d [0x%x]\n", path, (type < REG_MAX ? val_types[type] : "(unknown)"), len, len); if (dohex) type = REG_BINARY; switch (type) { case REG_SZ: case REG_EXPAND_SZ: case REG_MULTI_SZ: cheap_uni2ascii(data,string,len); for (i = 0; i < (len>>1)-1; i++) { if (string[i] == 0) string[i] = '\n'; if (type == REG_SZ) break; } puts(string); break; case REG_DWORD: printf("0x%08x",*(unsigned short *)data); break; default: printf("Don't know how to handle type yet!\n"); case REG_BINARY: hexdump((char *)data, 0, len, 1); } putchar('\n');}/* =================================================================== *//* Registry editor frontend */struct cmds { char cmd_str[12]; int cmd_num;};#define MCMD_CD 1#define MCMD_LS 2#define MCMD_QUIT 3#define MCMD_CAT 4#define MCMD_STRUCT 5#define MCMD_DEBUG 6#define MCMD_HELP 7#define MCMD_PASSWD 8#define MCMD_HIVE 9#define MCMD_EDIT 10#define MCMD_ALLOC 11#define MCMD_FREE 12#define MCMD_ADDV 13#define MCMD_DELV 14#define MCMD_DELVALL 15#define MCMD_NEWKEY 16#define MCMD_DELKEY 17#define MCMD_CATHEX 18#define MCMD_RDEL 19#define MCMD_CK 20struct cmds maincmds[] = { { "cd" , MCMD_CD } , { "ls" , MCMD_LS } , { "dir", MCMD_LS } , { "q" , MCMD_QUIT } , { "cat", MCMD_CAT } , { "type",MCMD_CAT } , { "st" , MCMD_STRUCT } , { "pw" , MCMD_PASSWD } , { "passwd", MCMD_PASSWD } , { "debug", MCMD_DEBUG } , { "hive", MCMD_HIVE } , { "ed", MCMD_EDIT } ,#if ALLOC_DEBUG { "alloc", MCMD_ALLOC } , { "free", MCMD_FREE } ,#endif { "nv", MCMD_ADDV } , { "dv", MCMD_DELV } , { "delallv", MCMD_DELVALL } , { "nk", MCMD_NEWKEY } , { "dk", MCMD_DELKEY } , { "hex", MCMD_CATHEX } , { "rdel", MCMD_RDEL } , { "ck", MCMD_CK } , { "?", MCMD_HELP } , { "", 0 }};/* Edit value: Invoke whatever is needed to edit it * based on its type */void edit_val(struct hive *h, int nkofs, char *path){ struct keyval *kv, *newkv; int type,len,n,i,in,go, newsize, d = 0, done, insert = 0; char inbuf[SZ_MAX+4]; char origstring[SZ_MAX+4]; char *newstring; char *dbuf; type = get_val_type(h, nkofs, path); if (type == -1) { printf("Value <%s> not found!\n",path); return; } kv = get_val2buf(h, NULL, nkofs, path, type); if (!kv) { printf("Unable to get data of value <%s>\n",path); return; } len = kv->len; printf("EDIT: <%s> of type %s with length %d [0x%x]\n", path, (type < REG_MAX ? val_types[type] : "(unknown)"), len, len); switch(type) { case REG_DWORD: printf("DWORD: Old value %d [0x%x], ", kv->data, kv->data); fmyinput("enter new value (prepend 0x if hex, empty to keep old value)\n-> ", inbuf, 12); if (*inbuf) { sscanf(inbuf,"%i",&kv->data); d = 1; } printf("DWORD: New value %d [0x%x], ", kv->data, kv->data); break; case REG_SZ: case REG_EXPAND_SZ: case REG_MULTI_SZ: newstring = NULL; dbuf = (char *)&kv->data; cheap_uni2ascii(dbuf,origstring,len); n = 0; i = 0; while (i < (len>>1)-1) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -