]> git.zerfleddert.de Git - proxmark3-svn/blame - client/cmdhficlass.c
ADD: Holimans new changes in master.
[proxmark3-svn] / client / cmdhficlass.c
CommitLineData
cee5a30d 1//-----------------------------------------------------------------------------
2// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>, Hagen Fritsch
3// Copyright (C) 2011 Gerhard de Koning Gans
f38a1528 4// Copyright (C) 2014 Midnitesnake & Andy Davies & Martin Holst Swende
cee5a30d 5//
6// This code is licensed to you under the terms of the GNU GPL, version 2 or,
7// at your option, any later version. See the LICENSE.txt file for the text of
8// the license.
9//-----------------------------------------------------------------------------
10// High frequency iClass commands
11//-----------------------------------------------------------------------------
12
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
9f6e9d15 16#include <sys/stat.h>
cee5a30d 17#include "iso14443crc.h" // Can also be used for iClass, using 0xE012 as CRC-type
18#include "data.h"
902cb3c0 19#include "proxmark3.h"
cee5a30d 20#include "ui.h"
21#include "cmdparser.h"
22#include "cmdhficlass.h"
f38a1528 23#include "../include/common.h"
14006804 24#include "util.h"
17cba269 25#include "cmdmain.h"
f38a1528 26#include "loclass/des.h"
27#include "loclass/cipherutils.h"
28#include "loclass/cipher.h"
29#include "loclass/ikeys.h"
30#include "loclass/elite_crack.h"
31#include "loclass/fileutils.h"
cee5a30d 32
33static int CmdHelp(const char *Cmd);
34
17cba269
MHS
35int xorbits_8(uint8_t val)
36{
37 uint8_t res = val ^ (val >> 1); //1st pass
38 res = res ^ (res >> 1); // 2nd pass
39 res = res ^ (res >> 2); // 3rd pass
40 res = res ^ (res >> 4); // 4th pass
41 return res & 1;
42}
43
d3a22c7d 44#define ICLASS_CMD_ACTALL 0x0A
45#define ICLASS_CMD_IDENTIFY 0x0C
46#define ICLASS_CMD_READ 0x0C
17cba269 47
d3a22c7d 48#define ICLASS_CMD_SELECT 0x81
49#define ICLASS_CMD_PAGESEL 0x84
50#define ICLASS_CMD_READCHECK 0x88
51#define ICLASS_CMD_CHECK 0x05
52#define ICLASS_CMD_SOF 0x0F
53#define ICLASS_CMD_HALT 0x00
17cba269 54
17cba269 55
d3a22c7d 56void explain(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
57{
cee5a30d 58
d3a22c7d 59 if(cmdsize > 1 && cmd[0] == ICLASS_CMD_READ)
60 {
61 snprintf(exp,size,"READ(%d)",cmd[1]);
62 return;
cee5a30d 63 }
cee5a30d 64
d3a22c7d 65 switch(cmd[0])
66 {
67 case ICLASS_CMD_ACTALL: snprintf(exp,size,"ACTALL"); break;
68 case ICLASS_CMD_IDENTIFY: snprintf(exp,size,"IDENTIFY"); break;
69 case ICLASS_CMD_SELECT: snprintf(exp,size,"SELECT"); break;
70 case ICLASS_CMD_PAGESEL: snprintf(exp,size,"PAGESEL"); break;
71 case ICLASS_CMD_READCHECK: snprintf(exp,size,"READCHECK"); break;
72 case ICLASS_CMD_CHECK: snprintf(exp,size,"CHECK"); break;
73 case ICLASS_CMD_SOF: snprintf(exp,size,"SOF"); break;
74 case ICLASS_CMD_HALT: snprintf(exp,size,"HALT"); break;
75 default: snprintf(exp,size,"?"); break;
76 }
77 return;
78}
79
80int CmdHFiClassList(const char *Cmd)
81{
82 PrintAndLog("Deprecated command, use 'hf list iclass' instead");
cee5a30d 83 return 0;
84}
85
cee5a30d 86int CmdHFiClassSnoop(const char *Cmd)
87{
88 UsbCommand c = {CMD_SNOOP_ICLASS};
89 SendCommand(&c);
90 return 0;
91}
a501c82b 92#define NUM_CSNS 15
1e262141 93int CmdHFiClassSim(const char *Cmd)
94{
95 uint8_t simType = 0;
96 uint8_t CSN[8] = {0, 0, 0, 0, 0, 0, 0, 0};
97
17cba269
MHS
98 if (strlen(Cmd)<1) {
99 PrintAndLog("Usage: hf iclass sim [0 <CSN>] | x");
100 PrintAndLog(" options");
101 PrintAndLog(" 0 <CSN> simulate the given CSN");
102 PrintAndLog(" 1 simulate default CSN");
103 PrintAndLog(" 2 iterate CSNs, gather MACs");
1e262141 104 PrintAndLog(" sample: hf iclass sim 0 031FEC8AF7FF12E0");
17cba269 105 PrintAndLog(" sample: hf iclass sim 2");
1e262141 106 return 0;
107 }
108
109 simType = param_get8(Cmd, 0);
17cba269
MHS
110
111 if(simType == 0)
112 {
113 if (param_gethex(Cmd, 1, CSN, 16)) {
114 PrintAndLog("A CSN should consist of 16 HEX symbols");
115 return 1;
116 }
117 PrintAndLog("--simtype:%02x csn:%s", simType, sprint_hex(CSN, 8));
118
119 }
77abe781 120 if(simType > 2)
17cba269
MHS
121 {
122 PrintAndLog("Undefined simptype %d", simType);
123 return 1;
1e262141 124 }
17cba269 125 uint8_t numberOfCSNs=0;
1e262141 126
9f6e9d15
MHS
127 if(simType == 2)
128 {
a501c82b 129 UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,NUM_CSNS}};
9f6e9d15 130 UsbCommand resp = {0};
17cba269 131
f5ed4d12 132 /*uint8_t csns[8 * NUM_CSNS] = {
133 0x00,0x0B,0x0F,0xFF,0xF7,0xFF,0x12,0xE0 ,
134 0x00,0x13,0x94,0x7e,0x76,0xff,0x12,0xe0 ,
135 0x2a,0x99,0xac,0x79,0xec,0xff,0x12,0xe0 ,
136 0x17,0x12,0x01,0xfd,0xf7,0xff,0x12,0xe0 ,
137 0xcd,0x56,0x01,0x7c,0x6f,0xff,0x12,0xe0 ,
138 0x4b,0x5e,0x0b,0x72,0xef,0xff,0x12,0xe0 ,
139 0x00,0x73,0xd8,0x75,0x58,0xff,0x12,0xe0 ,
140 0x0c,0x90,0x32,0xf3,0x5d,0xff,0x12,0xe0 };
141*/
142
a501c82b 143 uint8_t csns[8*NUM_CSNS] = {
144 0x00, 0x0B, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0,
145 0x00, 0x04, 0x0E, 0x08, 0xF7, 0xFF, 0x12, 0xE0,
146 0x00, 0x09, 0x0D, 0x05, 0xF7, 0xFF, 0x12, 0xE0,
147 0x00, 0x0A, 0x0C, 0x06, 0xF7, 0xFF, 0x12, 0xE0,
148 0x00, 0x0F, 0x0B, 0x03, 0xF7, 0xFF, 0x12, 0xE0,
149 0x00, 0x08, 0x0A, 0x0C, 0xF7, 0xFF, 0x12, 0xE0,
150 0x00, 0x0D, 0x09, 0x09, 0xF7, 0xFF, 0x12, 0xE0,
151 0x00, 0x0E, 0x08, 0x0A, 0xF7, 0xFF, 0x12, 0xE0,
152 0x00, 0x03, 0x07, 0x17, 0xF7, 0xFF, 0x12, 0xE0,
153 0x00, 0x3C, 0x06, 0xE0, 0xF7, 0xFF, 0x12, 0xE0,
154 0x00, 0x01, 0x05, 0x1D, 0xF7, 0xFF, 0x12, 0xE0,
155 0x00, 0x02, 0x04, 0x1E, 0xF7, 0xFF, 0x12, 0xE0,
156 0x00, 0x07, 0x03, 0x1B, 0xF7, 0xFF, 0x12, 0xE0,
157 0x00, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x12, 0xE0,
158 0x00, 0x05, 0x01, 0x21, 0xF7, 0xFF, 0x12, 0xE0 };
159
160 memcpy(c.d.asBytes, csns, 8*NUM_CSNS);
9f6e9d15
MHS
161
162 SendCommand(&c);
163 if (!WaitForResponseTimeout(CMD_ACK, &resp, -1)) {
164 PrintAndLog("Command timed out");
165 return 0;
166 }
1e262141 167
77abe781 168 uint8_t num_mac_responses = resp.arg[1];
a501c82b 169 PrintAndLog("Mac responses: %d MACs obtained (should be %d)", num_mac_responses, NUM_CSNS);
9f6e9d15 170
a501c82b 171 size_t datalen = NUM_CSNS*24;
9f6e9d15
MHS
172 /*
173 * Now, time to dump to file. We'll use this format:
77abe781 174 * <8-byte CSN><8-byte CC><4 byte NR><4 byte MAC>....
9f6e9d15 175 * So, it should wind up as
77abe781
MHS
176 * 8 * 24 bytes.
177 *
178 * The returndata from the pm3 is on the following format
179 * <4 byte NR><4 byte MAC>
180 * CC are all zeroes, CSN is the same as was sent in
9f6e9d15 181 **/
77abe781
MHS
182 void* dump = malloc(datalen);
183 memset(dump,0,datalen);//<-- Need zeroes for the CC-field
9f6e9d15 184 uint8_t i = 0;
a501c82b 185 for(i = 0 ; i < NUM_CSNS ; i++)
9f6e9d15 186 {
77abe781
MHS
187 memcpy(dump+i*24, csns+i*8,8); //CSN
188 //8 zero bytes here...
189 //Then comes NR_MAC (eight bytes from the response)
190 memcpy(dump+i*24+16,resp.d.asBytes+i*8,8);
1e262141 191
9f6e9d15
MHS
192 }
193 /** Now, save to dumpfile **/
77abe781
MHS
194 saveFile("iclass_mac_attack", "bin", dump,datalen);
195 free(dump);
9f6e9d15
MHS
196 }else
197 {
198 UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,numberOfCSNs}};
199 memcpy(c.d.asBytes, CSN, 8);
200 SendCommand(&c);
201 }
f38a1528 202
1e262141 203 return 0;
204}
205
206int CmdHFiClassReader(const char *Cmd)
f38a1528 207{
208 UsbCommand c = {CMD_READER_ICLASS, {0}};
209 SendCommand(&c);
210 UsbCommand resp;
211 while(!ukbhit()){
212 if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
213 uint8_t isOK = resp.arg[0] & 0xff;
214 uint8_t * data = resp.d.asBytes;
215
216 PrintAndLog("isOk:%02x", isOK);
d3a22c7d 217 if( isOK == 0){
218 //Aborted
219 PrintAndLog("Quitting...");
220 return 0;
221 }
f38a1528 222 if(isOK > 0)
223 {
224 PrintAndLog("CSN: %s",sprint_hex(data,8));
225 }
226 if(isOK >= 1)
227 {
228 PrintAndLog("CC: %s",sprint_hex(data+8,8));
229 }else{
230 PrintAndLog("No CC obtained");
231 }
232 } else {
233 PrintAndLog("Command execute timeout");
234 }
235 }
236
237 return 0;
238}
239
240int CmdHFiClassReader_Replay(const char *Cmd)
1e262141 241{
242 uint8_t readerType = 0;
f38a1528 243 uint8_t MAC[4]={0x00, 0x00, 0x00, 0x00};
1e262141 244
245 if (strlen(Cmd)<1) {
f38a1528 246 PrintAndLog("Usage: hf iclass replay <MAC>");
247 PrintAndLog(" sample: hf iclass replay 00112233");
1e262141 248 return 0;
c3963755 249 }
1e262141 250
f38a1528 251 if (param_gethex(Cmd, 0, MAC, 8)) {
252 PrintAndLog("MAC must include 8 HEX symbols");
253 return 1;
254 }
255
256 UsbCommand c = {CMD_READER_ICLASS_REPLAY, {readerType}};
257 memcpy(c.d.asBytes, MAC, 4);
258 SendCommand(&c);
259
260 return 0;
261}
262
263int CmdHFiClassReader_Dump(const char *Cmd)
264{
265 uint8_t readerType = 0;
266 uint8_t MAC[4]={0x00,0x00,0x00,0x00};
267 uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
268 uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
269 uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
270 //uint8_t CC_temp[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
271 uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
272 uint8_t keytable[128] = {0};
273 int elite = 0;
274 uint8_t *used_key;
275 int i;
276 if (strlen(Cmd)<1)
277 {
278 PrintAndLog("Usage: hf iclass dump <Key> [e]");
279 PrintAndLog(" Key - A 16 byte master key");
280 PrintAndLog(" e - If 'e' is specified, the key is interpreted as the 16 byte");
281 PrintAndLog(" Custom Key (KCus), which can be obtained via reader-attack");
282 PrintAndLog(" See 'hf iclass sim 2'. This key should be on iclass-format");
283 PrintAndLog(" sample: hf iclass dump 0011223344556677");
284
285
286 return 0;
287 }
288
fecd8202 289 if (param_gethex(Cmd, 0, KEY, 16))
290 {
f38a1528 291 PrintAndLog("KEY must include 16 HEX symbols");
292 return 1;
293 }
9b82de75 294
f38a1528 295 if (param_getchar(Cmd, 1) == 'e')
296 {
297 PrintAndLog("Elite switch on");
298 elite = 1;
299
300 //calc h2
301 hash2(KEY, keytable);
302 printarr_human_readable("keytable", keytable, 128);
303
304 }
305
f5ed4d12 306 UsbCommand resp;
307 uint8_t key_sel[8] = {0};
308 uint8_t key_sel_p[8] = { 0 };
309
310 //HACK -- Below is for testing without access to a tag
311 uint8_t fake_dummy_test = false;
312 if(fake_dummy_test)
313 {
314 uint8_t xdata[16] = {0x01,0x02,0x03,0x04,0xF7,0xFF,0x12,0xE0, //CSN from http://www.proxmark.org/forum/viewtopic.php?pid=11230#p11230
315 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; // Just a random CC. Would be good to add a real testcase here
316 memcpy(resp.d.asBytes,xdata, 16);
317 resp.arg[0] = 2;
318 }
319
320 //End hack
321
f38a1528 322
323 UsbCommand c = {CMD_READER_ICLASS, {0}};
d3a22c7d 324 c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE| FLAG_ICLASS_READER_GET_CC;
f5ed4d12 325 if(!fake_dummy_test)
1e262141 326 SendCommand(&c);
f38a1528 327
f5ed4d12 328
329
330 if (fake_dummy_test || WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
f38a1528 331 uint8_t isOK = resp.arg[0] & 0xff;
332 uint8_t * data = resp.d.asBytes;
333
334 memcpy(CSN,data,8);
335 memcpy(CCNR,data+8,8);
336
337 PrintAndLog("isOk:%02x", isOK);
338
339 if(isOK > 0)
340 {
341 PrintAndLog("CSN: %s",sprint_hex(CSN,8));
342 }
343 if(isOK > 1)
344 {
345 if(elite)
346 {
f38a1528 347 //Get the key index (hash1)
348 uint8_t key_index[8] = {0};
349
350 hash1(CSN, key_index);
351 printvar("hash1", key_index,8);
352 for(i = 0; i < 8 ; i++)
353 key_sel[i] = keytable[key_index[i]] & 0xFF;
f5ed4d12 354 PrintAndLog("Pre-fortified 'permuted' HS key that would be needed by an iclass reader to talk to above CSN:");
f38a1528 355 printvar("k_sel", key_sel,8);
356 //Permute from iclass format to standard format
357 permutekey_rev(key_sel,key_sel_p);
358 used_key = key_sel_p;
359 }else{
360 //Perhaps this should also be permuted to std format?
361 // Something like the code below? I have no std system
362 // to test this with /Martin
363
364 //uint8_t key_sel_p[8] = { 0 };
365 //permutekey_rev(KEY,key_sel_p);
366 //used_key = key_sel_p;
367
368 used_key = KEY;
369
370 }
f5ed4d12 371
372 PrintAndLog("Pre-fortified key that would be needed by the OmniKey reader to talk to above CSN:");
f38a1528 373 printvar("Used key",used_key,8);
374 diversifyKey(CSN,used_key, div_key);
f5ed4d12 375 PrintAndLog("Hash0, a.k.a diversified key, that is computed using Ksel and stored in the card (Block 3):");
f38a1528 376 printvar("Div key", div_key, 8);
377 printvar("CC_NR:",CCNR,12);
378 doMAC(CCNR,12,div_key, MAC);
379 printvar("MAC", MAC, 4);
380
381 UsbCommand d = {CMD_READER_ICLASS_REPLAY, {readerType}};
382 memcpy(d.d.asBytes, MAC, 4);
f5ed4d12 383 if(!fake_dummy_test) SendCommand(&d);
f38a1528 384
385 }else{
386 PrintAndLog("Failed to obtain CC! Aborting");
387 }
388 } else {
389 PrintAndLog("Command execute timeout");
390 }
391
392 return 0;
393}
1e262141 394
f38a1528 395int CmdHFiClass_iso14443A_write(const char *Cmd)
396{
397 uint8_t readerType = 0;
398 uint8_t MAC[4]={0x00,0x00,0x00,0x00};
399 uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
400 uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
401 uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
402 uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
403
404 uint8_t blockNo=0;
405 uint8_t bldata[8]={0};
406
407 if (strlen(Cmd)<3)
408 {
409 PrintAndLog("Usage: hf iclass write <Key> <Block> <Data>");
410 PrintAndLog(" sample: hf iclass write 0011223344556677 10 AAAAAAAAAAAAAAAA");
411 return 0;
412 }
413
414 if (param_gethex(Cmd, 0, KEY, 16))
415 {
416 PrintAndLog("KEY must include 16 HEX symbols");
417 return 1;
418 }
419
420 blockNo = param_get8(Cmd, 1);
421 if (blockNo>32)
422 {
423 PrintAndLog("Error: Maximum number of blocks is 32 for iClass 2K Cards!");
fecd8202 424 return 1;
f38a1528 425 }
426 if (param_gethex(Cmd, 2, bldata, 8))
427 {
428 PrintAndLog("Block data must include 8 HEX symbols");
429 return 1;
430 }
431
432 UsbCommand c = {CMD_ICLASS_ISO14443A_WRITE, {0}};
433 SendCommand(&c);
434 UsbCommand resp;
435
436 if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
437 uint8_t isOK = resp.arg[0] & 0xff;
438 uint8_t * data = resp.d.asBytes;
439
440 memcpy(CSN,data,8);
441 memcpy(CCNR,data+8,8);
442 PrintAndLog("DEBUG: %s",sprint_hex(CSN,8));
443 PrintAndLog("DEBUG: %s",sprint_hex(CCNR,8));
1e262141 444 PrintAndLog("isOk:%02x", isOK);
445 } else {
446 PrintAndLog("Command execute timeout");
f38a1528 447 }
448
449 diversifyKey(CSN,KEY, div_key);
450
451 PrintAndLog("Div Key: %s",sprint_hex(div_key,8));
452 doMAC(CCNR, 12,div_key, MAC);
453
454 UsbCommand c2 = {CMD_ICLASS_ISO14443A_WRITE, {readerType,blockNo}};
455 memcpy(c2.d.asBytes, bldata, 8);
456 memcpy(c2.d.asBytes+8, MAC, 4);
457 SendCommand(&c2);
458
459 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
460 uint8_t isOK = resp.arg[0] & 0xff;
461 uint8_t * data = resp.d.asBytes;
1e262141 462
f38a1528 463 if (isOK)
464 PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 4));
465 else
466 PrintAndLog("isOk:%02x", isOK);
467 } else {
468 PrintAndLog("Command execute timeout");
469 }
1e262141 470 return 0;
471}
472
f38a1528 473
cee5a30d 474static command_t CommandTable[] =
475{
476 {"help", CmdHelp, 1, "This help"},
d3a22c7d 477 {"list", CmdHFiClassList, 0, "[Deprecated] List iClass history"},
cee5a30d 478 {"snoop", CmdHFiClassSnoop, 0, "Eavesdrop iClass communication"},
1e262141 479 {"sim", CmdHFiClassSim, 0, "Simulate iClass tag"},
fecd8202 480 {"reader",CmdHFiClassReader, 0, "Read an iClass tag"},
f38a1528 481 {"replay", CmdHFiClassReader_Replay, 0, "Read an iClass tag via Reply Attack"},
482 {"dump", CmdHFiClassReader_Dump, 0, "Authenticate and Dump iClass tag"},
483 {"write", CmdHFiClass_iso14443A_write, 0, "Authenticate and Write iClass block"},
cee5a30d 484 {NULL, NULL, 0, NULL}
485};
486
487int CmdHFiClass(const char *Cmd)
488{
489 CmdsParse(CommandTable, Cmd);
490 return 0;
491}
492
493int CmdHelp(const char *Cmd)
494{
495 CmdsHelp(CommandTable);
9f6e9d15
MHS
496 return 0;
497}
Impressum, Datenschutz