FreeRDP
Loading...
Searching...
No Matches
tools/hash-cli/hash.c
1
20#include <stdio.h>
21#include <string.h>
22#include <stdlib.h>
23#include <errno.h>
24
25#include <winpr/ntlm.h>
26#include <winpr/ssl.h>
27#include <winpr/assert.h>
28
50static int usage_and_exit(void)
51{
52 printf("winpr-hash: NTLM hashing tool\n");
53 printf("Usage: winpr-hash -u <username> -p <password> [-d <domain>] [-f <_default_,sam>] [-v "
54 "<_1_,2>]\n");
55 return 1;
56}
57
58int main(int argc, char* argv[])
59{
60 int index = 1;
61 int format = 0;
62 unsigned long version = 1;
63 BYTE NtHash[16];
64 char* User = NULL;
65 size_t UserLength = 0;
66 char* Domain = NULL;
67 size_t DomainLength = 0;
68 char* Password = NULL;
69 size_t PasswordLength = 0;
70 errno = 0;
71
72 while (index < argc)
73 {
74 if (strcmp("-d", argv[index]) == 0)
75 {
76 index++;
77
78 if (index == argc)
79 {
80 printf("missing domain\n\n");
81 return usage_and_exit();
82 }
83
84 Domain = argv[index];
85 }
86 else if (strcmp("-u", argv[index]) == 0)
87 {
88 index++;
89
90 if (index == argc)
91 {
92 printf("missing username\n\n");
93 return usage_and_exit();
94 }
95
96 User = argv[index];
97 }
98 else if (strcmp("-p", argv[index]) == 0)
99 {
100 index++;
101
102 if (index == argc)
103 {
104 printf("missing password\n\n");
105 return usage_and_exit();
106 }
107
108 Password = argv[index];
109 }
110 else if (strcmp("-v", argv[index]) == 0)
111 {
112 index++;
113
114 if (index == argc)
115 {
116 printf("missing version parameter\n\n");
117 return usage_and_exit();
118 }
119
120 version = strtoul(argv[index], NULL, 0);
121
122 if (((version != 1) && (version != 2)) || (errno != 0))
123 {
124 printf("unknown version %lu \n\n", version);
125 return usage_and_exit();
126 }
127 }
128 else if (strcmp("-f", argv[index]) == 0)
129 {
130 index++;
131
132 if (index == argc)
133 {
134 printf("missing format\n\n");
135 return usage_and_exit();
136 }
137
138 if (strcmp("default", argv[index]) == 0)
139 format = 0;
140 else if (strcmp("sam", argv[index]) == 0)
141 format = 1;
142 }
143 else if (strcmp("-h", argv[index]) == 0)
144 {
145 return usage_and_exit();
146 }
147
148 index++;
149 }
150
151 if ((!User) || (!Password))
152 {
153 printf("missing username or password\n\n");
154 return usage_and_exit();
155 }
156 winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT);
157
158 UserLength = strlen(User);
159 PasswordLength = strlen(Password);
160 DomainLength = (Domain) ? strlen(Domain) : 0;
161
162 WINPR_ASSERT(UserLength <= UINT32_MAX);
163 WINPR_ASSERT(PasswordLength <= UINT32_MAX);
164 WINPR_ASSERT(DomainLength <= UINT32_MAX);
165
166 if (version == 2)
167 {
168 if (!Domain)
169 {
170 printf("missing domain (version 2 requires a domain to specified)\n\n");
171 return usage_and_exit();
172 }
173
174 if (!NTOWFv2A(Password, (UINT32)PasswordLength, User, (UINT32)UserLength, Domain,
175 (UINT32)DomainLength, NtHash))
176 {
177 (void)fprintf(stderr, "Hash creation failed\n");
178 return 1;
179 }
180 }
181 else
182 {
183 if (!NTOWFv1A(Password, (UINT32)PasswordLength, NtHash))
184 {
185 (void)fprintf(stderr, "Hash creation failed\n");
186 return 1;
187 }
188 }
189
190 if (format == 0)
191 {
192 for (int idx = 0; idx < 16; idx++)
193 printf("%02" PRIx8 "", NtHash[idx]);
194
195 printf("\n");
196 }
197 else if (format == 1)
198 {
199 printf("%s:", User);
200
201 if (DomainLength > 0)
202 printf("%s:", Domain);
203 else
204 printf(":");
205
206 printf(":");
207
208 for (int idx = 0; idx < 16; idx++)
209 printf("%02" PRIx8 "", NtHash[idx]);
210
211 printf(":::");
212 printf("\n");
213 }
214
215 return 0;
216}