📄 chntpw.c
字号:
} } FREE(v);}/* Check for presence of syskey and possibly disable it if * user wants it. * This is tricky, and extremely undocumented! * See docs for more info on what's going on when syskey is installed */#undef LSADATAvoid handle_syskey(void){ /* This is \SAM\Domains\Account\F */ struct samkeyf { char unknown[0x50]; /* 0x0000 - Unknown. May be machine SID */ char unknown2[0x14]; char syskeymode; /* 0x0064 - Type/mode of syskey in use */ char syskeyflags1[0xb]; /* 0x0065 - More flags/settings */ char syskeyobf[0x30]; /* 0x0070 - This may very well be the obfuscated syskey */ }; /* There may be more, usually 8 null-bytes? */ /* Security\Policy\SecretEncryptionKey\@, only on NT5 */ /* Probably contains some keyinfo for syskey. Second DWORD seems to be syskeymode */ struct secpoldata { int unknown1; /* Some kind of flag? usually 1 */ int syskeymode; /* Is this what we're looking for? */ int unknown2; /* Usually 0? */ char keydata[0x40]; /* Some kind of scrambled keydata? */ };#ifdef LSADATA /* SYSTEM\CurrentControlSet\Control\Lsa\Data, only on NT5?? */ /* Probably contains some keyinfo for syskey. Byte 0x34 seems to be mode */ struct lsadata { char keydata[0x34]; /* Key information */ int syskeymode; /* Is this what we're looking for? */ };#endif /* void *fdata; */ struct samkeyf *ff = NULL; struct secpoldata *sf = NULL; /* struct lsadata *ld = NULL; */ int /* len, */ i,secboot, samfmode, secmode /* , ldmode */ ; struct keyval *samf, *secpol /* , *lsad */ ; char *syskeytypes[4] = { "off", "key-in-registry", "enter-passphrase", "key-on-floppy" }; char yn[5]; printf("\n---------------------> SYSKEY CHECK <-----------------------\n"); if (H_SAM < 0) { printf("ERROR: SAM hive not loaded!\n"); return; } samf = get_val2buf(hive[H_SAM], NULL, 0, "\\SAM\\Domains\\Account\\F", REG_BINARY); if (samf && samf->len > 0x70 ) { ff = (struct samkeyf *)&samf->data; samfmode = ff->syskeymode; } else { samfmode = -1; } secboot = -1; if (H_SYS >= 0) { secboot = get_dword(hive[H_SYS], 0, "\\ControlSet001\\Control\\Lsa\\SecureBoot"); } secmode = -1; if (H_SEC >=0) { secpol = get_val2buf(hive[H_SEC], NULL, 0, "\\Policy\\PolSecretEncryptionKey\\@", REG_NONE); if (secpol) { /* Will not be found in NT 4, take care of that */ sf = (struct secpoldata *)&secpol->data; secmode = sf->syskeymode; } }#ifdef LSADATA lsad = get_val2buf(hive[H_SYS], NULL, 0, "\\ControlSet001\\Control\\Lsa\\Data\\Pattern", REG_BINARY); if (lsad && lsad->len >= 0x38) { ld = (struct lsadata *)&lsad->data; ldmode = ld->syskeymode; } else { ldmode = -1; }#endif printf("SYSTEM SecureBoot : %d -> %s\n", secboot, (secboot < 0 || secboot > 3) ? "Not Set (not installed, good!)" : syskeytypes[secboot]); printf("SAM Account\\F : %d -> %s\n", samfmode, (samfmode < 0 || samfmode > 3) ? "Not Set" : syskeytypes[samfmode]); printf("SECURITY PolSecretEncryptionKey: %d -> %s\n", secmode, (secmode < 0 || secmode > 3) ? "Not Set (OK if this is NT4)" : syskeytypes[secmode]);#ifdef LSADATA printf("SYSTEM LsaData : %d -> %s\n\n", ldmode, (ldmode < 0 || ldmode > 3) ? "Not Set (strange?)" : syskeytypes[ldmode]);#endif if (secboot != samfmode && secboot != -1) { printf("WARNING: Mismatch in syskey settings in SAM and SYSTEM!\n"); printf("WARNING: It may be dangerous to continue (however, resetting syskey\n"); printf(" may very well fix the problem)\n"); } if (secboot > 0 || samfmode > 0) { printf("\n***************** SYSKEY IS ENABLED! **************\n"); printf("This installation very likely has the syskey passwordhash-obfuscator installed\n"); printf("It's currently in mode = %d, %s-mode\n",secboot, (secboot < 0 || secboot > 3) ? "Unknown" : syskeytypes[secboot]); if (no_hives < 2) { printf("\nSYSTEM (and possibly SECURITY) hives not loaded, unable to disable syskey!\n"); printf("Please start the program with at least SAM & SYSTEM-hive filenames as arguments!\n\n"); return; } printf("SYSKEY is on! However, DO NOT DISABLE IT UNLESS YOU HAVE TO!\n"); printf("This program can change passwords even if syskey is on, however\n"); printf("if you have lost the key-floppy or passphrase you can turn it off,\n"); printf("but please read the docs first!!!\n"); printf("\n** IF YOU DON'T KNOW WHAT SYSKEY IS YOU DO NOT NEED TO SWITCH IT OFF!**\n"); printf("NOTE: On WINDOWS 2000 it will not be possible\n"); printf("to turn it on again! (and other problems may also show..)\n\n"); printf("NOTE: Disabling syskey will invalidate ALL\n"); printf("passwords, requiring them to be reset. You should at least reset the\n"); printf("administrator password using this program, then the rest ought to be\n"); printf("done from NT.\n"); fmyinput("\nDo you really wish to disable SYSKEY? (y/n) [n] ",yn,2); if (*yn == 'y') { /* Reset SAM syskey infostruct, fill with zeroes */ if (ff) { ff->syskeymode = 0; for (i = 0; i < 0x3b; i++) { ff->syskeyflags1[i] = 0; } put_buf2val(hive[H_SAM], samf, 0, "\\SAM\\Domains\\Account\\F", REG_BINARY); } /* Reset SECURITY infostruct (if any) */ if (sf) { memset(sf, 0, secpol->len); sf->syskeymode = 0; put_buf2val(hive[H_SEC], secpol, 0, "\\Policy\\PolSecretEncryptionKey\\@", REG_BINARY); }#if LSADATA if (ld) { ld->syskeymode = 0; put_buf2val(hive[H_SYS], lsad, 0, "\\ControlSet001\\Control\\Lsa\\Data\\Pattern", REG_BINARY); }#endif /* And SYSTEM SecureBoot parameter */ put_dword(hive[H_SYS], 0, "\\ControlSet001\\Control\\Lsa\\SecureBoot", 0); dirty = 1; syskeyreset = 1; printf("Updating passwordhash-lengths..\n"); list_users(1); printf("* SYSKEY RESET!\nNow please set new administrator password!\n"); } else { syskeyreset = 1; } } else { printf("Syskey not installed!\n"); return; }}/* Interactive user edit */void useredit(void){ char iwho[100]; int il; printf("\n\n===== chntpw Edit User Info & Passwords ====\n\n"); if (H_SAM < 0) { printf("ERROR: SAM registry file (which contains user data) is not loaded!\n\n"); return; } list_users(1); while (1) { printf("\nSelect: ! - quit, . - list users, 0x<RID> - User with RID (hex)\n"); printf("or simply enter the username to change: [%s] ",admuser); il = fmyinput("",iwho,32); if (il == 1 && *iwho == '.') { list_users(1); continue; } if (il == 1 && *iwho == '!') return; if (il == 0) strcpy(iwho,admuser); find_n_change(iwho); }}void recoveryconsole(){ int cmd = 0; int sec = 0; static char *scpath = "\\Microsoft\\Windows NT\\CurrentVersion\\Setup\\RecoveryConsole\\SetCommand"; static char *slpath = "\\Microsoft\\Windows NT\\CurrentVersion\\Setup\\RecoveryConsole\\SecurityLevel"; char yn[5]; if (H_SOF < 0) { printf("\nERROR: SOFTWARE-hive not loaded, and there's where RecoveryConsole settings are..\n"); return; } cmd = get_dword(hive[H_SOF],0,scpath); sec = get_dword(hive[H_SOF],0,slpath); if (cmd == -1 && sec == -1) { printf("\nDid not find registry entries for RecoveryConsole. Strange unless this is pre-win2k\n"); return; } printf("\nRecoveryConsole:\n- Extended SET command is \t%s\n", cmd>0 ? "ENABLED (1)" : "DISABLED (0)"); printf("- Administrator password login: %s\n", sec>0 ? "SKIPPED (1)" : "ENFORCED (0)"); fmyinput("\nDo you want to change it? (y/n) [n] ",yn,2); if (*yn == 'y') { cmd ^= 1; sec ^= 1; if (!put_dword(hive[0], 0, scpath, cmd)) printf("Update of SET level failed registry edit\n"); if (!put_dword(hive[0], 0, slpath, sec)) printf("Update of login level failed registry edit\n"); printf("Done!\n"); }}/* Interactive menu system */void interactive(void){ int il; char inbuf[20]; while(1) { printf("\n\n<>========<> chntpw Main Interactive Menu <>========<>\n\n" "Loaded hives:"); for (il = 0; il < no_hives; il++) { printf(" <%s>",hive[il]->filename); } printf("\n\n 1 - Edit user data and passwords\n" " 2 - Syskey status & change\n" " 3 - RecoveryConsole settings\n" " - - -\n" " 9 - Registry editor, now with full write support!\n" " q - Quit (you will be asked if there is something to save)\n" "\n\n"); il = fmyinput("What to do? [1] -> ", inbuf, 10); if (!il) useredit(); if (il) { switch(inbuf[0]) { case '1': useredit(); break; case '2': handle_syskey(); break; case '3': recoveryconsole(); break; case '9': mainloop(); break; case 'q': return; break; } } }} void usage(void) { printf("chntpw: change password of a user in a NT SAM file, or invoke registry editor.\n" "chntpw [OPTIONS] <samfile> [systemfile] [securityfile] [otherreghive] [...]\n" " -h This message\n" " -u <user> Username to change, Administrator is default\n" " -l list all users in SAM file\n" " -i Interactive. List users (as -l) then ask for username to change\n" " -e Registry editor. Now with full write support!\n" " -d Enter buffer debugger instead (hex editor), \n" " -t Trace. Show hexdump of structs/segments. (deprecated debug function)\n" " -v Be a little more verbose (for debuging)\n" " -L Write names of changed files to /tmp/changed\n" " -N No allocation mode. Only (old style) same length overwrites possible\n" "See readme file on how to extract/read/write the NT's SAM file\n" "if it's on an NTFS partition!\n" "Source/binary freely distributable. See README/COPYING for details\n" "NOTE: This program is somewhat hackish! You are on your own!\n" );}int main(int argc, char **argv){ /* int vofs; */ int dodebug = 0, list = 1, inter = 0,edit = 0,il,d = 0, dd = 0, logchange = 0, noalloc = 0; extern int /* opterr, */ optind; extern char* optarg; char *filename,c; char *who = "Administrator"; char iwho[100]; FILE *ch; /* Write out names of touched files to this */ char *options = "LNidehltvu:"; printf("%s\n",chntpw_version); while((c=getopt(argc,argv,options)) > 0) { switch(c) { case 'd': dodebug = 1; break; case 'e': edit = 1; break; case 'L': logchange = 1; break; case 'N': noalloc = HMODE_NOALLOC; break; case 'l': list = 1; who = 0; break; case 't': list = 2; who = 0; break; case 'v': gverbose = 1; break; case 'i': list = 1; who = 0; inter = 1; break; case 'u': who = optarg; list = 1; break; case 'h': usage(); exit(0); break; default: usage(); exit(1); break; } } filename=argv[optind]; if (!filename || !*filename) { usage(); exit(1); } do { if (!(hive[no_hives] = openHive(filename, HMODE_RW|noalloc|(list == 2 ? HMODE_VERBOSE : 0)))) { printf("Unable to open/read a hive, exiting..\n"); exit(1); } switch(hive[no_hives]->type) { case HTYPE_SAM: H_SAM = no_hives; break; case HTYPE_SOFTWARE: H_SOF = no_hives; break; case HTYPE_SYSTEM: H_SYS = no_hives; break; case HTYPE_SECURITY: H_SEC = no_hives; break; } no_hives++; filename = argv[optind+no_hives]; } while (filename && *filename && no_hives < MAX_HIVES); if (dodebug) debugit(hive[0]->buffer,hive[0]->size); else { check_get_samdata(); if (list && !edit && !inter) { if ( list_users(1) ) edit = 1; } if (edit) mainloop(); else if (who) { handle_syskey(); find_n_change(who); } if (inter) interactive(); } printf("\nHives that have changed:\n # Name\n"); for (il = 0; il < no_hives; il++) { if (hive[il]->state & HMODE_DIRTY) { if (!logchange) printf("%2d <%s>\n",il,hive[il]->filename); d = 1; } } if (d) { /* Only prompt user if logging of changed files has not been set */ /* Thus we assume confirmations are done externally if they ask for a list of changes */ if (!logchange) fmyinput("Write hive files? (y/n) [n] : ",iwho,3); if (*iwho == 'y' || logchange) { if (logchange) { ch = fopen("/tmp/changed","w"); } for (il = 0; il < no_hives; il++) { if (hive[il]->state & HMODE_DIRTY) { printf("%2d <%s> - ",il,hive[il]->filename); if (!writeHive(hive[il])) { printf("OK\n"); if (logchange) fprintf(ch,"%s ",hive[il]->filename); dd = 2; } } } if (logchange) { fprintf(ch,"\n"); fclose(ch); } } else { printf("Not written!\n\n"); } } else { printf("None!\n\n"); } return(dd);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -