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

📄 chntpw.c

📁 修改NT密码的程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * chntpw.c - Offline Password Edit Utility for NT 3.51 & 4.0 SAM database. * 1999-feb: Now able to browse registry hives. (write support to come) * 2000-jan: Attempt to detect and disable syskey *  * Copyright (c) 1997-2000 Petter Nordahl-Hagen. * Freely distributable in source or binary for noncommercial purposes. *  * Uses (links with) DES SSL Library by Eric Young (eay@mincom.oz.au) * and MD4 routines by RSA. *  * Part of some routines, information and ideas taken from * pwdump by Jeremy Allison. * * Some stuff (like proto.h) from NTCrack by Jonathan Wilkins. *  * Please see the COPYING file for more details on * copyrights & credits. *   * THIS SOFTWARE IS PROVIDED BY PETTER NORDAHL-HAGEN `AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <ctype.h>#include <stdlib.h>#include <string.h>/* #include <unistd.h> *//* These are from the DESlib & MD packages, see Makefile & README */#include <des.h>#include <mddriver/global.h>#include <md4/md4.h>#include "proto.h"#include "ntreg.h"const char chntpw_version[] = "chntpw version 0.98.1 000607, (c) Petter N Hagen";extern char *val_types[REG_MAX+1];#define MAX_HIVES 10#define H_SAM 0#define H_SYS 1#define H_SEC 2/* Array of loaded hives */struct hive *hive[MAX_HIVES+1];int no_hives = 0;int syskeyreset = 0;int dirty = 0;/* * of user with RID 500, because silly MS decided * to localize the bloody admin-username!! AAAGHH! */char admuser[129]="StupidMS";/* ============================================================== *//* Crypto-stuff & support for what we'll do in the V-value *//* Zero out string for lanman passwd, then uppercase * the supplied password and put it in here */void make_lanmpw(char *p, char *lm, int len){   int i;      for (i=0; i < 15; i++) lm[i] = 0;   for (i=0; i < len; i++) lm[i] = toupper(p[i]);}/* * Convert a 7 byte array into an 8 byte des key with odd parity. */void str_to_key(unsigned char *str,unsigned char *key){	void des_set_odd_parity(des_cblock *);	int i;	key[0] = str[0]>>1;	key[1] = ((str[0]&0x01)<<6) | (str[1]>>2);	key[2] = ((str[1]&0x03)<<5) | (str[2]>>3);	key[3] = ((str[2]&0x07)<<4) | (str[3]>>4);	key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5);	key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6);	key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7);	key[7] = str[6]&0x7F;	for (i=0;i<8;i++) {		key[i] = (key[i]<<1);	}	des_set_odd_parity((des_cblock *)key);}/* * Function to convert the RID to the first decrypt key. */void sid_to_key1(unsigned long sid,unsigned char deskey[8]){	unsigned char s[7];	s[0] = (unsigned char)(sid & 0xFF);	s[1] = (unsigned char)((sid>>8) & 0xFF);	s[2] = (unsigned char)((sid>>16) & 0xFF);	s[3] = (unsigned char)((sid>>24) & 0xFF);	s[4] = s[0];	s[5] = s[1];	s[6] = s[2];	str_to_key(s,deskey);}/* * Function to convert the RID to the second decrypt key. */void sid_to_key2(unsigned long sid,unsigned char deskey[8]){	unsigned char s[7];		s[0] = (unsigned char)((sid>>24) & 0xFF);	s[1] = (unsigned char)(sid & 0xFF);	s[2] = (unsigned char)((sid>>8) & 0xFF);	s[3] = (unsigned char)((sid>>16) & 0xFF);	s[4] = s[0];	s[5] = s[1];	s[6] = s[2];	str_to_key(s,deskey);}/* DES encrypt, for LANMAN */void E1(uchar *k, uchar *d, uchar *out){  des_key_schedule ks;  des_cblock deskey;  str_to_key(k,(uchar *)deskey);#ifdef __FreeBSD__  des_set_key(&deskey,ks);#else /* __FreeBsd__ */  des_set_key((des_cblock *)deskey,ks);#endif /* __FreeBsd__ */  des_ecb_encrypt((des_cblock *)d,(des_cblock *)out, ks, DES_ENCRYPT);}/* Decode the V-struct, and change the password * vofs - offset into SAM buffer, start of V struct * rid - the users RID, required for the DES decrypt stage *       If rid==0 it will try to extract the rid out of the V struct *       else the supplied one will be used * * Some of this is ripped & modified from pwdump by Jeremy Allison *  */char *change_pw(char *buf, int rid, int vlen, int stat){      uchar x1[] = {0x4B,0x47,0x53,0x21,0x40,0x23,0x24,0x25};   char magic[] = {0x24, 0, 0x44 };   int pl,ridofs,vend;   char *vp;   static char username[128],fullname[128];   char comment[128],homedir[128],md4[32],lanman[32];   char newunipw[34], newp[20], despw[20], newlanpw[16], newlandes[20];   char yn[4];   int username_offset,username_len;   int fullname_offset,fullname_len;   int comment_offset,comment_len;   int homedir_offset,homedir_len;   int ntpw_len,lmpw_len,ntpw_offs,lmpw_offs,i;   des_key_schedule ks1, ks2;   des_cblock deskey1, deskey2;   MD4_CTX context;   unsigned char digest[16];   vp = buf;   username_offset = get_int(vp + 0xC);   username_len = get_int(vp + 0x10);    fullname_offset = get_int(vp + 0x18);   fullname_len = get_int(vp + 0x1c);   comment_offset = get_int(vp + 0x24);   comment_len = get_int(vp + 0x28);   homedir_offset = get_int(vp + 0x48);   homedir_len = get_int(vp + 0x4c);   lmpw_offs = get_int(vp + 0x9c);   lmpw_len = get_int(vp + 0xa0);   ntpw_offs = get_int(vp + 0xa8);   ntpw_len = get_int(vp + 0xac);#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 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   if (!rid) {      printf("No RID supplied, doing some magic to find it.\n");      ridofs = find_in_buf(buf, magic,3, 0);      if (!ridofs || ridofs > vlen) {	 printf("No RID found in struct..\n");	 rid = 0;      } else {	 rid = get_int(buf+ridofs+0x1e);      }   }#endif#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) {      printf("RID: %04x, Username: <%s>%s\n",	     rid, username,  ( !rid ? ", account 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);      if (ntpw_len < 16) {      printf("** This user _probably_ has a BLANK password! (Unable to change it, let NT do it instead :)\n\n");      return(0);   }      if (!rid) {     printf("No RID given. Unable to change passwords..\n");     return(0);   }      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);         hexprnt("MD4 hash     : ",md4,16);   hexprnt("LANMAN hash  : ",lanman,16);      pl = fmyinput("\nPlease enter new password\nor nothing to leave unchanged: ",newp,16);      /*   printf("password: [%s] have length %d\n",newp,pl); */   if (!pl) { printf("Nothing changed.\n"); return(0); }      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);      hexprnt("\nNEW MD4 hash    : ",digest,16);      E1(newlanpw,   x1, lanman);   E1(newlanpw+7, x1, lanman+8);      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);         hexprnt("NEW DES crypt   : ",despw,16);   hexprnt("NEW LANMAN crypt: ",newlandes,16);     fmyinput("\nDo you really wish to change it? (y/n) [n] ",yn,2);   /* 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;   }   if (*yn == 'y') {      for (i = 0; i < 16; i++) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -