]>
git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdlfhid.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
4 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
5 // at your option, any later version. See the LICENSE.txt file for the text of
7 //-----------------------------------------------------------------------------
8 // Low frequency HID commands
9 //-----------------------------------------------------------------------------
13 #include "proxmark3.h"
16 #include "cmdparser.h"
22 static int CmdHelp(const char *Cmd
);
24 int usage_lf_hid_wiegand(void){
25 PrintAndLog("Usage: lf hid wiegand [h] [OEM] [FC] [CN]");
26 PrintAndLog("This command converts facility code/card number to Wiegand code");
27 PrintAndLog("Options:");
28 PrintAndLog(" h - This help");
29 PrintAndLog(" OEM - OEM number");
30 PrintAndLog(" FC - facility code");
31 PrintAndLog(" CN - card number");
32 PrintAndLog("Examples:");
33 PrintAndLog(" lf hid wiegand 0 101 2001");
36 int usage_lf_hid_brute(void){
37 PrintAndLog("Enables bruteforce of HID readers with specified facility code.");
38 PrintAndLog("Different formatlength is supported");
39 PrintAndLog("This is a incremental attack against reader.");
41 PrintAndLog("Usage: lf hid brute <format length> <facility code>");
42 PrintAndLog("Options :");
43 PrintAndLog(" <format length> - 26|33|34|35|37|40|44|84");
44 PrintAndLog(" <facility code> - 8-bit value HID facility code");
46 PrintAndLog("Sample : lf hid brute 26 224");
50 int CmdHIDDemod(const char *Cmd)
52 if (GraphTraceLen < 4800) {
53 PrintAndLog("too short; need at least 4800 samples");
58 for (int i = 0; i < GraphTraceLen; ++i) {
59 if (GraphBuffer[i] < 0) {
69 int CmdHIDDemodFSK(const char *Cmd
) {
70 int findone
= ( Cmd
[0] == '1' ) ? 1 : 0;
71 UsbCommand c
= {CMD_HID_DEMOD_FSK
, {findone
, 0 , 0}};
77 int CmdHIDSim(const char *Cmd
) {
78 unsigned int hi
= 0, lo
= 0;
81 while (sscanf(&Cmd
[i
++], "%1x", &n
) == 1) {
82 hi
= (hi
<< 4) | (lo
>> 28);
83 lo
= (lo
<< 4) | (n
& 0xf);
86 PrintAndLog("Emulating tag with ID %x%16x", hi
, lo
);
87 PrintAndLog("Press pm3-button to abort simulation");
89 UsbCommand c
= {CMD_HID_SIM_TAG
, {hi
, lo
, 0}};
95 int CmdHIDClone(const char *Cmd
) {
96 unsigned int hi2
= 0, hi
= 0, lo
= 0;
100 if (strchr(Cmd
,'l') != 0) {
101 while (sscanf(&Cmd
[i
++], "%1x", &n
) == 1) {
102 hi2
= (hi2
<< 4) | (hi
>> 28);
103 hi
= (hi
<< 4) | (lo
>> 28);
104 lo
= (lo
<< 4) | (n
& 0xf);
107 PrintAndLog("Cloning tag with long ID %x%08x%08x", hi2
, hi
, lo
);
111 while (sscanf(&Cmd
[i
++], "%1x", &n
) == 1) {
112 hi
= (hi
<< 4) | (lo
>> 28);
113 lo
= (lo
<< 4) | (n
& 0xf);
116 PrintAndLog("Cloning tag with ID %x%08x", hi
, lo
);
122 c
.cmd
= CMD_HID_CLONE_TAG
;
127 clearCommandBuffer();
132 static void getParity26(uint32_t *hi
, uint32_t *lo
){
136 for (i
= 24;i
>= 13;i
--)
137 result
^= (*lo
>> i
) & 1;
138 // even parity 26th bit
143 for (i
= 12;i
>= 1;i
--)
144 result
^= (*lo
>> i
) & 1;
147 static void getParity33(uint32_t *hi
, uint32_t *lo
){
150 static void getParity34(uint32_t *hi
, uint32_t *lo
){
155 for (i
= 7;i
>= 0;i
--)
156 result
^= (*hi
>> i
) & i
;
157 for (i
= 31;i
>= 24;i
--)
158 result
^= (*lo
>> i
) & 1;
164 for (i
= 23;i
>= 1;i
--)
165 result
^= (*lo
>> i
) & 1;
169 static void getParity35(uint32_t *hi
, uint32_t *lo
){
171 static void getParity37S(uint32_t *hi
,uint32_t *lo
){
176 for (i
= 4; i
>= 0; i
--)
177 result
^= (*hi
>> i
) & 1;
179 for (i
= 31; i
>= 20; i
--)
180 result
^= (*lo
>> i
) & 1;
186 for (i
= 19; i
>= 1; i
--)
187 result
^= (*lo
>> i
) & 1;
191 static void getParity37H(uint32_t *hi
, uint32_t *lo
){
196 for (i
= 4;i
>= 0;i
--)
197 result
^= (*hi
>> i
) & 1;
198 for (i
= 31;i
>= 20;i
--)
199 result
^= (*lo
>> i
) & 1;
204 for (i
= 19;i
>= 1;i
--)
205 result
^= (*lo
>> i
) & 1;
209 static void calc26(uint16_t fc
, uint32_t cardno
, uint32_t *hi
, uint32_t *lo
){
210 *lo
= ((cardno
& 0xFFFF) << 1) | ((fc
& 0xFF) << 17) | (1 << 26);
213 static void calc33(uint16_t fc
, uint32_t cardno
, uint32_t *hi
, uint32_t *lo
){
216 static void calc34(uint16_t fc
, uint32_t cardno
, uint32_t *hi
, uint32_t *lo
){
217 // put card number first bit 1 .. 20 //
218 *lo
= ((cardno
& 0X000F7FFF) << 1) | ((fc
& 0XFFFF) << 17);
219 // set bit format for less than 37 bit format
220 *hi
= (1 << 5) | (fc
>> 15);
222 static void calc35(uint16_t fc
, uint32_t cardno
, uint32_t *hi
, uint32_t *lo
){
223 *lo
= ((cardno
& 0xFFFFF) << 1) | fc
<< 21;
224 *hi
= (1 << 5) | ((fc
>> 11) & 1);
226 static void calc37S(uint16_t fc
, uint32_t cardno
, uint32_t *hi
, uint32_t *lo
){
227 // FC 2 - 17 - 16 bit
228 // cardno 18 - 36 - 19 bit
233 *lo
= ((fc
<< 20) | (cardno
& 0x7FFFF) << 1);
236 static void calc37H(uint64_t cardno
, uint32_t *hi
, uint32_t *lo
){
238 // cardno 1-35 34 bits
239 // Even Parity 0th bit 1-18
240 // Odd Parity 36th bit 19-35
241 cardno
= (cardno
& 0x00000003FFFFFFFF);
243 *hi
= (cardno
>> 31);
245 static void calc40(uint64_t cardno
, uint32_t *hi
, uint32_t *lo
){
246 cardno
= (cardno
& 0xFFFFFFFFFF);
247 *lo
= ((cardno
& 0xFFFFFFFF) << 1 );
248 *hi
= (cardno
>> 31);
251 static void calcWiegand(uint8_t fmtlen
, uint16_t fc
, uint64_t cardno
, uint32_t *hi
, uint32_t *lo
){
253 uint32_t cn
= (cardno
& 0xFFFFFFFF);
256 calc26(fc
, cn
, hi
, lo
);
261 calc33(fc
, cn
, hi
, lo
);
266 calc34(fc
, cn
, hi
, lo
);
271 calc35(fc
, cn
, hi
, lo
);
276 calc37S(fc
, cn
, hi
, lo
);
277 getParity37S(hi
, lo
);
282 getParity37H(hi
, lo
);
285 case 40 : calc40(cardno
, hi
, lo
); break;
291 int CmdHIDWiegand(const char *Cmd
) {
293 uint32_t fc
, lo
= 0, hi
= 0;
294 uint64_t cardnum
= 0;
296 uint8_t ctmp
= param_getchar(Cmd
, 0);
297 if ( strlen(Cmd
) == 0 || strlen(Cmd
) < 3 || ctmp
== 'H' || ctmp
== 'h' ) return usage_lf_hid_wiegand();
299 oem
= param_get8(Cmd
, 0);
300 fc
= param_get32ex(Cmd
, 1, 0, 10);
301 cardnum
= param_get64ex(Cmd
, 2, 0, 10);
303 uint8_t ftmlen
[] = {26,33,34,35,37,38,40};
304 for (uint8_t i
= 0; i
< sizeof(ftmlen
); i
++){
305 calcWiegand( ftmlen
[i
], fc
, cardnum
, &hi
, &lo
);
306 PrintAndLog("HID %d bit | OEM: %d FC: %d CN: %llu | Wiegand code: %08X%08X", ftmlen
[i
], oem
, fc
, cardnum
, hi
, lo
);
311 int CmdHIDBrute(const char *Cmd
){
314 uint8_t fc
= 0, fmtlen
= 0;
315 uint32_t hi
= 0, lo
= 0;
317 UsbCommand c
= {CMD_HID_SIM_TAG
, {0, 0, 0}};
319 char cmdp
= param_getchar(Cmd
, 0);
320 if (strlen(Cmd
) > 2 || strlen(Cmd
) == 0 || cmdp
== 'h' || cmdp
== 'H') return usage_lf_hid_brute();
322 fmtlen
= param_get8(Cmd
, 0);
323 uint8_t ftms
[] = {26,33,34,35,37};
324 for ( uint8_t i
= 0; i
< sizeof(ftms
); i
++){
325 if ( ftms
[i
] == fmtlen
) {
330 if ( error
) return usage_lf_hid_brute();
332 fc
= param_get8(Cmd
, 1);
333 if ( fc
== 0) return usage_lf_hid_brute();
335 PrintAndLog("Brute-forcing HID reader");
336 PrintAndLog("Press pm3-button to abort simulation or run another command");
338 for ( uint16_t cn
= 1; cn
< 0xFFFF; ++cn
){
340 PrintAndLog("aborted via keyboard!");
345 clearCommandBuffer();
350 calcWiegand( fmtlen
, fc
, cn
, &hi
, &lo
);
354 clearCommandBuffer();
357 PrintAndLog("Trying FC: %u; CN: %u", fc
, cn
);
364 static command_t CommandTable
[] = {
365 {"help", CmdHelp
, 1, "This help"},
366 // {"demod", CmdHIDDemod, 1, "Demodulate HID Prox Card II (not optimal)"},
367 {"fskdemod",CmdHIDDemodFSK
, 0, "['1'] Realtime HID FSK demodulator (option '1' for one tag only)"},
368 {"sim", CmdHIDSim
, 0, "<ID> -- HID tag simulator"},
369 {"clone", CmdHIDClone
, 0, "<ID> ['l'] -- Clone HID to T55x7 (tag must be in antenna)(option 'l' for 84bit ID)"},
370 {"wiegand", CmdHIDWiegand
, 0, "<OEM> <facility code> <card number> -- convert facility code/card number to Wiegand code"},
371 {"brute", CmdHIDBrute
, 0, "<format length> <facility code> -- brute force card number"},
372 {NULL
, NULL
, 0, NULL
}
375 int CmdLFHID(const char *Cmd
) {
376 clearCommandBuffer();
377 CmdsParse(CommandTable
, Cmd
);
381 int CmdHelp(const char *Cmd
) {
382 CmdsHelp(CommandTable
);