github.com/google/osv-scalibr@v0.4.1/detector/weakcredentials/winlocal/samreg/userinfo_test.go (about) 1 // Copyright 2025 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package samreg 16 17 import ( 18 "errors" 19 "slices" 20 "strings" 21 "testing" 22 ) 23 24 func TestUsername(t *testing.T) { 25 tests := []struct { 26 name string 27 userVBuffer []byte 28 userF *userF 29 want string 30 wantErr bool 31 wantErrText string 32 }{ 33 { 34 name: "returns_username", 35 userVBuffer: []byte(strings.Repeat("\x00", 16) + "\x08" + strings.Repeat("\x00", 187) + "\x42\x00\x43\x00\x44\x00\x45\x00"), 36 want: "BCDE", 37 }, 38 { 39 name: "userV_parse_failure_returns_error", 40 userVBuffer: []byte(strings.Repeat("\xFF", 0xCC)), 41 wantErr: true, 42 wantErrText: errReadOutOfBounds.Error(), 43 }, 44 } 45 46 for _, tc := range tests { 47 t.Run(tc.name, func(t *testing.T) { 48 userV, err := newUserV(tc.userVBuffer, "irrelevant") 49 if err != nil { 50 t.Fatalf("Failed to create userV for tests: %v", err) 51 } 52 53 userinfo := UserInfo{ 54 userV: userV, 55 userF: tc.userF, 56 } 57 58 got, gotErr := userinfo.Username() 59 if (gotErr != nil) != tc.wantErr { 60 t.Errorf("Username(): unexpected error: %v", gotErr) 61 } 62 63 if tc.wantErr { 64 if !strings.Contains(gotErr.Error(), tc.wantErrText) { 65 t.Errorf("Username(): unexpected error, got: %v, want: %v", gotErr, tc.wantErr) 66 } 67 68 return 69 } 70 71 if got != tc.want { 72 t.Errorf("Username(): got %v, want %v", got, tc.want) 73 } 74 }) 75 } 76 } 77 78 func TestEnabled(t *testing.T) { 79 tests := []struct { 80 name string 81 userV *userV 82 userF *userF 83 want bool 84 wantErr error 85 }{ 86 { 87 name: "user_enabled_returns_true", 88 userV: nil, 89 userF: newUserF([]byte(strings.Repeat("A", 56)+"\x00"), "irrelevant"), 90 want: true, 91 }, 92 { 93 name: "user_disabled_returns_false", 94 userV: nil, 95 userF: newUserF([]byte(strings.Repeat("A", 56)+"\x01"), "irrelevant"), 96 want: false, 97 }, 98 { 99 name: "userF_parsing_failure_returns_error", 100 userV: nil, 101 userF: newUserF([]byte(""), "irrelevant"), 102 wantErr: errUserFTooShort, 103 }, 104 } 105 106 for _, tc := range tests { 107 t.Run(tc.name, func(t *testing.T) { 108 userinfo := UserInfo{ 109 userV: tc.userV, 110 userF: tc.userF, 111 } 112 113 got, gotErr := userinfo.Enabled() 114 if !errors.Is(gotErr, tc.wantErr) { 115 t.Errorf("Enabled(): unexpected error, got: %v, want: %v", gotErr, tc.wantErr) 116 } 117 118 if tc.wantErr != nil { 119 return 120 } 121 122 if got != tc.want { 123 t.Errorf("Enabled(): got %v, want %v", got, tc.want) 124 } 125 }) 126 } 127 } 128 129 func TestHashes(t *testing.T) { 130 tests := []struct { 131 name string 132 userVBuffer []byte 133 rid string 134 syskey []byte 135 wantLM []byte 136 wantNT []byte 137 wantErr bool 138 wantErrText string 139 }{ 140 { 141 name: "hash_with_RC4_succeeds", 142 rid: "000003E9", 143 userVBuffer: []byte("\x00\x00\x00\x00\xd4\x00\x00\x00\x02\x00\x01\x00\xd4\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x00\x00\x08\x00\x00\x00\x01\x00\x00\x00\xe8\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\xfc\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x10\x01\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x14\x01\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x01\x00\x14\x80\xb4\x00\x00\x00\xc4\x00\x00\x00\x14\x00\x00\x00\x44\x00\x00\x00\x02\x00\x30\x00\x02\x00\x00\x00\x02\xc0\x14\x00\x44\x00\x05\x01\x01\x01\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x02\xc0\x14\x00\xff\xff\x1f\x00\x01\x01\x00\x00\x00\x00\x00\x05\x07\x00\x00\x00\x02\x00\x70\x00\x04\x00\x00\x00\x00\x00\x14\x00\x5b\x03\x02\x00\x01\x01\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x18\x00\xff\x07\x0f\x00\x01\x02\x00\x00\x00\x00\x00\x05\x20\x00\x00\x00\x20\x02\x00\x00\x00\x00\x18\x00\xff\x07\x0f\x00\x01\x02\x00\x00\x00\x00\x00\x05\x20\x00\x00\x00\x24\x02\x00\x00\x00\x00\x24\x00\x44\x00\x02\x00\x01\x05\x00\x00\x00\x00\x00\x05\x15\x00\x00\x00\xee\x9d\xd5\xc6\x43\xed\x3f\x53\x2e\xc8\x5e\x0a\xe9\x03\x00\x00\x01\x02\x00\x00\x00\x00\x00\x05\x20\x00\x00\x00\x20\x02\x00\x00\x01\x02\x00\x00\x00\x00\x00\x05\x20\x00\x00\x00\x20\x02\x00\x00\x6c\x00\x6d\x00\x75\x00\x73\x00\x65\x00\x72\x00\x01\x02\x00\x00\x07\x00\x00\x00\x03\x00\x01\x00\x0c\x4b\x53\xdf\x15\xed\xf9\xeb\x41\x05\xfe\xca\x48\x02\x70\x55\x03\x00\x01\x00\x72\x10\xad\x76\x18\xf1\x1f\x38\x49\x24\x6d\x13\x38\x15\x8b\x03\x03\x00\x01\x00\x03\x00\x01\x00"), 144 syskey: []byte("\x3d\x21\x2c\xe8\xa2\xda\x83\x43\xbd\xad\x1e\xf2\xcf\xb6\xb3\x1c"), 145 wantLM: []byte("\xe5\x2c\xac\x67\x41\x9a\x9a\x22\x66\x43\x45\x14\x0a\x85\x2f\x61"), 146 wantNT: []byte("\x58\xa4\x78\x13\x5a\x93\xac\x3b\xf0\x58\xa5\xea\x0e\x8f\xdb\x71"), 147 }, 148 { 149 name: "hash_with_RC4_only_NTLM_succeeds", 150 rid: "000001F4", 151 userVBuffer: []byte("\x00\x00\x00\x00\xbc\x00\x00\x00\x02\x00\x01\x00\xbc\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\xd8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\x00\x00\x00\x6c\x00\x00\x00\x00\x00\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x01\x00\x00\x15\x00\x00\x00\xa8\x00\x00\x00\x5c\x01\x00\x00\x08\x00\x00\x00\x01\x00\x00\x00\x64\x01\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x68\x01\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x7c\x01\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x80\x01\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x01\x00\x14\x80\x9c\x00\x00\x00\xac\x00\x00\x00\x14\x00\x00\x00\x44\x00\x00\x00\x02\x00\x30\x00\x02\x00\x00\x00\x02\xc0\x14\x00\x44\x00\x05\x01\x01\x01\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x02\xc0\x14\x00\xff\xff\x1f\x00\x01\x01\x00\x00\x00\x00\x00\x05\x07\x00\x00\x00\x02\x00\x58\x00\x03\x00\x00\x00\x00\x00\x14\x00\x5b\x03\x02\x00\x01\x01\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x18\x00\xff\x07\x0f\x00\x01\x02\x00\x00\x00\x00\x00\x05\x20\x00\x00\x00\x20\x02\x00\x00\x00\x00\x24\x00\x44\x00\x02\x00\x01\x05\x00\x00\x00\x00\x00\x05\x15\x00\x00\x00\xee\x9d\xd5\xc6\x43\xed\x3f\x53\x2e\xc8\x5e\x0a\xf4\x01\x00\x00\x01\x02\x00\x00\x00\x00\x00\x05\x20\x00\x00\x00\x20\x02\x00\x00\x01\x02\x00\x00\x00\x00\x00\x05\x20\x00\x00\x00\x20\x02\x00\x00\x41\x00\x64\x00\x6d\x00\x69\x00\x6e\x00\x69\x00\x73\x00\x74\x00\x72\x00\x61\x00\x74\x00\x6f\x00\x72\x00\x64\x00\x42\x00\x75\x00\x69\x00\x6c\x00\x74\x00\x2d\x00\x69\x00\x6e\x00\x20\x00\x61\x00\x63\x00\x63\x00\x6f\x00\x75\x00\x6e\x00\x74\x00\x20\x00\x66\x00\x6f\x00\x72\x00\x20\x00\x61\x00\x64\x00\x6d\x00\x69\x00\x6e\x00\x69\x00\x73\x00\x74\x00\x65\x00\x72\x00\x69\x00\x6e\x00\x67\x00\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\x63\x00\x6f\x00\x6d\x00\x70\x00\x75\x00\x74\x00\x65\x00\x72\x00\x2f\x00\x64\x00\x6f\x00\x6d\x00\x61\x00\x69\x00\x6e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x01\x00\x01\x02\x00\x00\x07\x00\x00\x00\x03\x00\x01\x00\x03\x00\x01\x00\xed\x92\x87\x92\x78\x3b\x69\x2c\x21\x37\x49\xbc\xdb\xe3\x1a\xf5\x03\x00\x01\x00\x03\x00\x01\x00"), 152 syskey: []byte("\x3d\x21\x2c\xe8\xa2\xda\x83\x43\xbd\xad\x1e\xf2\xcf\xb6\xb3\x1c"), 153 wantLM: []byte(""), 154 wantNT: []byte("\x58\xa4\x78\x13\x5a\x93\xac\x3b\xf0\x58\xa5\xea\x0e\x8f\xdb\x71"), 155 }, 156 { 157 name: "hash_with_AES_succeeds", 158 rid: "000003EA", 159 userVBuffer: []byte("\x00\x00\x00\x00\x0c\x01\x00\x00\x03\x00\x01\x00\x0c\x01\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x18\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x01\x00\x00\x08\x00\x00\x00\x01\x00\x00\x00\x20\x01\x00\x00\x38\x00\x00\x00\x00\x00\x00\x00\x58\x01\x00\x00\x38\x00\x00\x00\x00\x00\x00\x00\x90\x01\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\xa8\x01\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x01\x00\x14\x80\xec\x00\x00\x00\xfc\x00\x00\x00\x14\x00\x00\x00\x44\x00\x00\x00\x02\x00\x30\x00\x02\x00\x00\x00\x02\xc0\x14\x00\x44\x00\x05\x01\x01\x01\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x02\xc0\x14\x00\xff\xff\x1f\x00\x01\x01\x00\x00\x00\x00\x00\x05\x07\x00\x00\x00\x02\x00\xa8\x00\x05\x00\x00\x00\x00\x00\x14\x00\x5b\x03\x02\x00\x01\x01\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x18\x00\xff\x07\x0f\x00\x01\x02\x00\x00\x00\x00\x00\x05\x20\x00\x00\x00\x20\x02\x00\x00\x00\x00\x18\x00\xff\x07\x0f\x00\x01\x02\x00\x00\x00\x00\x00\x05\x20\x00\x00\x00\x24\x02\x00\x00\x00\x00\x38\x00\x1b\x03\x02\x00\x01\x0a\x00\x00\x00\x00\x00\x0f\x03\x00\x00\x00\x00\x04\x00\x00\xde\xa2\x28\x67\x21\x3e\xd2\xaf\x19\xad\x5d\x79\xb0\xc1\x07\x29\x27\x56\xfc\x20\xd8\xad\x66\xf6\x10\xf2\x68\xfa\xdf\x2a\xf8\x0f\x00\x00\x24\x00\x44\x00\x02\x00\x01\x05\x00\x00\x00\x00\x00\x05\x15\x00\x00\x00\xed\xfd\x54\x5c\x76\xc8\xf0\x10\x1c\xda\xe3\x70\xea\x03\x00\x00\x01\x02\x00\x00\x00\x00\x00\x05\x20\x00\x00\x00\x20\x02\x00\x00\x01\x02\x00\x00\x00\x00\x00\x05\x20\x00\x00\x00\x20\x02\x00\x00\x6c\x00\x6d\x00\x75\x00\x73\x00\x65\x00\x72\x00\x01\x02\x00\x00\x07\x00\x00\x00\x02\x00\x02\x00\x10\x00\x00\x00\x6a\xea\xb0\x62\x73\x97\xf9\xd0\x0d\x5d\x50\xcc\x3d\xef\xa8\xec\xed\xa9\x97\x59\x01\xe9\xa0\x17\x91\x9f\x8d\xf2\x52\x01\xd9\x6f\x69\x0f\x88\xe0\x2c\xe9\x22\x81\x9b\xf4\x14\x8f\x4b\xf9\x26\x8c\x02\x00\x02\x00\x10\x00\x00\x00\x86\xc1\x0a\xea\xc7\x24\x06\xdb\xb2\x9f\x09\x42\x87\xcf\xab\xbd\xed\xb0\x32\x75\xfb\x5d\xaf\x0a\xff\x48\xe3\x91\x51\x28\xff\xaa\x20\x93\xb3\x55\x53\xf1\x7d\x23\xde\xe0\xa6\xac\xaa\x27\x1e\xdd\x02\x00\x02\x00\x00\x00\x00\x00\x4e\x4d\xe5\x26\xdc\x17\xfa\x6f\x26\xb1\x59\xa6\xec\x09\x94\xae\x02\x00\x02\x00\x00\x00\x00\x00\x4b\x5e\x9a\x54\xa0\xc5\x6c\x8a\x07\x4e\x31\xfa\xf0\x62\xd1\xef"), 160 syskey: []byte("\xfc\xde\xe8\x3a\xc6\xc1\x4b\x28\xf5\x26\x50\x1f\xc6\xe8\xbb\xc3"), 161 wantLM: []byte("\xe5\x2c\xac\x67\x41\x9a\x9a\x22\x66\x43\x45\x14\x0a\x85\x2f\x61"), 162 wantNT: []byte("\x58\xa4\x78\x13\x5a\x93\xac\x3b\xf0\x58\xa5\xea\x0e\x8f\xdb\x71"), 163 }, 164 { 165 name: "hash_with_AES_only_NTLM_succeeds", 166 rid: "000001F4", 167 userVBuffer: []byte("\x00\x00\x00\x00\xf4\x00\x00\x00\x03\x00\x01\x00\xf4\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x10\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x01\x00\x00\x6c\x00\x00\x00\x00\x00\x00\x00\x7c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7c\x01\x00\x00\x15\x00\x00\x00\xa8\x00\x00\x00\x94\x01\x00\x00\x08\x00\x00\x00\x01\x00\x00\x00\x9c\x01\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\xb4\x01\x00\x00\x38\x00\x00\x00\x00\x00\x00\x00\xec\x01\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x04\x02\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x01\x00\x14\x80\xd4\x00\x00\x00\xe4\x00\x00\x00\x14\x00\x00\x00\x44\x00\x00\x00\x02\x00\x30\x00\x02\x00\x00\x00\x02\xc0\x14\x00\x44\x00\x05\x01\x01\x01\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x02\xc0\x14\x00\xff\xff\x1f\x00\x01\x01\x00\x00\x00\x00\x00\x05\x07\x00\x00\x00\x02\x00\x90\x00\x04\x00\x00\x00\x00\x00\x14\x00\x5b\x03\x02\x00\x01\x01\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x18\x00\xff\x07\x0f\x00\x01\x02\x00\x00\x00\x00\x00\x05\x20\x00\x00\x00\x20\x02\x00\x00\x00\x00\x38\x00\x1b\x03\x02\x00\x01\x0a\x00\x00\x00\x00\x00\x0f\x03\x00\x00\x00\x00\x04\x00\x00\xde\xa2\x28\x67\x21\x3e\xd2\xaf\x19\xad\x5d\x79\xb0\xc1\x07\x29\x27\x56\xfc\x20\xd8\xad\x66\xf6\x10\xf2\x68\xfa\xdf\x2a\xf8\x0f\x00\x00\x24\x00\x44\x00\x02\x00\x01\x05\x00\x00\x00\x00\x00\x05\x15\x00\x00\x00\xed\xfd\x54\x5c\x76\xc8\xf0\x10\x1c\xda\xe3\x70\xf4\x01\x00\x00\x01\x02\x00\x00\x00\x00\x00\x05\x20\x00\x00\x00\x20\x02\x00\x00\x01\x02\x00\x00\x00\x00\x00\x05\x20\x00\x00\x00\x20\x02\x00\x00\x41\x00\x64\x00\x6d\x00\x69\x00\x6e\x00\x69\x00\x73\x00\x74\x00\x72\x00\x61\x00\x74\x00\x6f\x00\x72\x00\x64\x00\x42\x00\x75\x00\x69\x00\x6c\x00\x74\x00\x2d\x00\x69\x00\x6e\x00\x20\x00\x61\x00\x63\x00\x63\x00\x6f\x00\x75\x00\x6e\x00\x74\x00\x20\x00\x66\x00\x6f\x00\x72\x00\x20\x00\x61\x00\x64\x00\x6d\x00\x69\x00\x6e\x00\x69\x00\x73\x00\x74\x00\x65\x00\x72\x00\x69\x00\x6e\x00\x67\x00\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\x63\x00\x6f\x00\x6d\x00\x70\x00\x75\x00\x74\x00\x65\x00\x72\x00\x2f\x00\x64\x00\x6f\x00\x6d\x00\x61\x00\x69\x00\x6e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xb2\xb9\x06\x01\x02\x00\x00\x07\x00\x00\x00\x02\x00\x02\x00\x00\x00\x00\x00\x36\xf4\xab\xc3\x1a\x2c\xf9\x76\x09\xa4\xcb\xbb\xe4\xbc\xac\x1c\x02\x00\x02\x00\x10\x00\x00\x00\xa3\x28\x48\xec\x7d\x73\x12\xec\x81\xeb\x50\xd0\x65\x09\x55\xd4\x48\xf2\xb6\x8b\xd9\x06\xa2\xbd\xb2\xaf\x39\x1c\xe2\x60\x44\x56\x6b\x80\x62\xb6\x55\xf4\x2b\x05\x9d\xfb\x5c\x68\x55\x4a\x5b\xc3\x02\x00\x02\x00\x00\x00\x00\x00\xf4\x62\x28\xbc\x7b\xf3\x36\xe7\xaf\x0f\x7d\xf4\x88\xd6\x78\x07\x02\x00\x02\x00\x00\x00\x00\x00\x0f\x24\x35\xc2\x94\x02\xd9\x4f\x28\xe0\xe7\x92\x86\x92\xde\x0b"), 168 syskey: []byte("\xfc\xde\xe8\x3a\xc6\xc1\x4b\x28\xf5\x26\x50\x1f\xc6\xe8\xbb\xc3"), 169 wantLM: []byte(""), 170 wantNT: []byte("\x58\xa4\x78\x13\x5a\x93\xac\x3b\xf0\x58\xa5\xea\x0e\x8f\xdb\x71"), 171 }, 172 { 173 name: "userV_parsing_failure_returns_error", 174 rid: "000001F4", 175 userVBuffer: []byte(strings.Repeat("\x00", 0xCC)), 176 wantErr: true, 177 wantErrText: errNoHashInfoFound.Error(), 178 }, 179 { 180 name: "decryption_failures_return_error", 181 rid: "", 182 userVBuffer: []byte("\x00\x00\x00\x00\xbc\x00\x00\x00\x02\x00\x01\x00\xbc\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\xd8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\x00\x00\x00\x6c\x00\x00\x00\x00\x00\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x01\x00\x00\x15\x00\x00\x00\xa8\x00\x00\x00\x5c\x01\x00\x00\x08\x00\x00\x00\x01\x00\x00\x00\x64\x01\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x68\x01\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x7c\x01\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x80\x01\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x01\x00\x14\x80\x9c\x00\x00\x00\xac\x00\x00\x00\x14\x00\x00\x00\x44\x00\x00\x00\x02\x00\x30\x00\x02\x00\x00\x00\x02\xc0\x14\x00\x44\x00\x05\x01\x01\x01\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x02\xc0\x14\x00\xff\xff\x1f\x00\x01\x01\x00\x00\x00\x00\x00\x05\x07\x00\x00\x00\x02\x00\x58\x00\x03\x00\x00\x00\x00\x00\x14\x00\x5b\x03\x02\x00\x01\x01\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x18\x00\xff\x07\x0f\x00\x01\x02\x00\x00\x00\x00\x00\x05\x20\x00\x00\x00\x20\x02\x00\x00\x00\x00\x24\x00\x44\x00\x02\x00\x01\x05\x00\x00\x00\x00\x00\x05\x15\x00\x00\x00\xee\x9d\xd5\xc6\x43\xed\x3f\x53\x2e\xc8\x5e\x0a\xf4\x01\x00\x00\x01\x02\x00\x00\x00\x00\x00\x05\x20\x00\x00\x00\x20\x02\x00\x00\x01\x02\x00\x00\x00\x00\x00\x05\x20\x00\x00\x00\x20\x02\x00\x00\x41\x00\x64\x00\x6d\x00\x69\x00\x6e\x00\x69\x00\x73\x00\x74\x00\x72\x00\x61\x00\x74\x00\x6f\x00\x72\x00\x64\x00\x42\x00\x75\x00\x69\x00\x6c\x00\x74\x00\x2d\x00\x69\x00\x6e\x00\x20\x00\x61\x00\x63\x00\x63\x00\x6f\x00\x75\x00\x6e\x00\x74\x00\x20\x00\x66\x00\x6f\x00\x72\x00\x20\x00\x61\x00\x64\x00\x6d\x00\x69\x00\x6e\x00\x69\x00\x73\x00\x74\x00\x65\x00\x72\x00\x69\x00\x6e\x00\x67\x00\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\x63\x00\x6f\x00\x6d\x00\x70\x00\x75\x00\x74\x00\x65\x00\x72\x00\x2f\x00\x64\x00\x6f\x00\x6d\x00\x61\x00\x69\x00\x6e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x01\x00\x01\x02\x00\x00\x07\x00\x00\x00\x03\x00\x01\x00\x03\x00\x01\x00\xed\x92\x87\x92\x78\x3b\x69\x2c\x21\x37\x49\xbc\xdb\xe3\x1a\xf5\x03\x00\x01\x00\x03\x00\x01\x00"), 183 wantErr: true, 184 wantErrText: errInvalidRIDSize.Error(), 185 }, 186 } 187 188 for _, tc := range tests { 189 t.Run(tc.name, func(t *testing.T) { 190 userV, err := newUserV(tc.userVBuffer, tc.rid) 191 if err != nil { 192 t.Fatalf("Failed to create userV for tests: %v", err) 193 } 194 195 userinfo := UserInfo{ 196 rid: tc.rid, 197 userV: userV, 198 } 199 200 gotLM, gotNT, gotErr := userinfo.Hashes(tc.syskey) 201 if (gotErr != nil) != tc.wantErr { 202 t.Errorf("Hashes(): unexpected error: %v", gotErr) 203 } 204 205 if tc.wantErr { 206 if !strings.Contains(gotErr.Error(), tc.wantErrText) { 207 t.Errorf("Hashes(): unexpected error, got: %v, want: %v", gotErr, tc.wantErr) 208 } 209 210 return 211 } 212 213 if !slices.Equal(gotLM, tc.wantLM) { 214 t.Errorf("Hashes(): got LM hash %x, want %x", gotLM, tc.wantLM) 215 } 216 217 if !slices.Equal(gotNT, tc.wantNT) { 218 t.Errorf("Hashes(): got NT hash %x, want %x", gotNT, tc.wantNT) 219 } 220 }) 221 } 222 }