⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chntpw.c

📁 The Offline NT Password Editor (c) 1997-2004 Petter Nordahl-Hagen
💻 C
📖 第 1 页 / 共 4 页
字号:
   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 + -