FreeRDP
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 
50 static WINPR_NORETURN(void 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  exit(1);
56 }
57 
58 int 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  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  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  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  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  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  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  usage_and_exit();
146  }
147 
148  index++;
149  }
150 
151  if ((!User) || (!Password))
152  {
153  printf("missing username or password\n\n");
154  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  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 }