Merge remote-tracking branch 'upstream/master'

This commit is contained in:
marshmellow42 2016-06-05 22:20:36 -04:00
commit c0d32c3186
14 changed files with 2495 additions and 28 deletions

View file

@ -5,6 +5,9 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
## [unreleased][unreleased]
### Added
- Added experimental HitagS support (Oguzhan Cicek, Hendrik Schwartke, Ralf Spenneberg)
see https://media.ccc.de/v/32c3-7166-sicherheit_von_125khz_transpondern_am_beispiel_hitag_s
English video available
- Added a LF ASK Sequence Terminator detection option to the standard ask demod - and applied it to `lf search u`, `lf t55xx detect`, and `data rawdemod am s` (marshmellow)
- `lf t55xx bruteforce <start password> <end password> [i <*.dic>]` - Simple bruteforce attack to find password - (iceman and others)
- `lf viking clone`- clone viking tag to t55x7 or Q5 from 4byte hex ID input

View file

@ -15,7 +15,7 @@ APP_CFLAGS = -DWITH_ISO14443a_StandAlone -DWITH_LF -DWITH_ISO15693 -DWITH_ISO144
#-DWITH_LCD
#SRC_LCD = fonts.c LCD.c
SRC_LF = lfops.c hitag2.c lfsampling.c pcf7931.c lfdemod.c protocols.c
SRC_LF = lfops.c hitag2.c hitagS.c lfsampling.c pcf7931.c lfdemod.c protocols.c
SRC_ISO15693 = iso15693.c iso15693tools.c
SRC_ISO14443a = epa.c iso14443a.c mifareutil.c mifarecmd.c mifaresniff.c
SRC_ISO14443b = iso14443b.c

View file

@ -23,6 +23,7 @@
#include "legicrf.h"
#include <hitag2.h>
#include <hitagS.h>
#include "lfsampling.h"
#include "BigBuf.h"
#include "mifareutil.h"
@ -1014,6 +1015,18 @@ void UsbPacketReceived(uint8_t *packet, int len)
case CMD_READER_HITAG: // Reader for Hitag tags, args = type and function
ReaderHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes);
break;
case CMD_SIMULATE_HITAG_S:// Simulate Hitag s tag, args = memory content
SimulateHitagSTag((bool)c->arg[0],(byte_t*)c->d.asBytes);
break;
case CMD_TEST_HITAGS_TRACES:// Tests every challenge within the given file
check_challenges((bool)c->arg[0],(byte_t*)c->d.asBytes);
break;
case CMD_READ_HITAG_S://Reader for only Hitag S tags, args = key or challenge
ReadHitagS((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes);
break;
case CMD_WR_HITAG_S://writer for Hitag tags args=data to write,page and key or challenge
WritePageHitagS((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes,c->arg[2]);
break;
#endif
#ifdef WITH_ISO15693

View file

@ -16,6 +16,7 @@
#include <stddef.h>
#include "common.h"
#include "hitag2.h"
#include "hitagS.h"
#include "mifare.h"
#include "../common/crc32.h"
#include "BigBuf.h"
@ -179,6 +180,13 @@ void SnoopHitag(uint32_t type);
void SimulateHitagTag(bool tag_mem_supplied, byte_t* data);
void ReaderHitag(hitag_function htf, hitag_data* htd);
//hitagS.h
void SimulateHitagSTag(bool tag_mem_supplied, byte_t* data);
void ReadHitagS(hitag_function htf, hitag_data* htd);
void WritePageHitagS(hitag_function htf, hitag_data* htd,int page);
void check_challenges(bool file_given, byte_t* data);
// cmd.h
bool cmd_receive(UsbCommand* cmd);
bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, size_t len);

View file

@ -1148,7 +1148,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
case RHT2F_CRYPTO: {
DbpString("Authenticating using key:");
memcpy(key,htd->crypto.key,4); //HACK; 4 or 6?? I read both in the code.
memcpy(key,htd->crypto.key,6); //HACK; 4 or 6?? I read both in the code.
Dbhexdump(6,key,false);
blocknr = 0;
bQuiet = false;

2146
armsrc/hitagS.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -64,7 +64,6 @@ int CmdLFCommandRead(const char *Cmd)
bool errors = FALSE;
//uint8_t divisor = 95; //125khz
uint8_t cmdp = 0;
int strLength = 0;
while(param_getchar(Cmd, cmdp) != 0x00)
{
switch(param_getchar(Cmd, cmdp))
@ -80,7 +79,7 @@ int CmdLFCommandRead(const char *Cmd)
cmdp++;
break;
case 'c':
strLength = param_getstr(Cmd, cmdp+1, (char *)&c.d.asBytes);
param_getstr(Cmd, cmdp+1, (char *)&c.d.asBytes);
cmdp+=2;
break;
case 'd':

View file

@ -18,6 +18,7 @@
#include "common.h"
#include "util.h"
#include "hitag2.h"
#include "hitagS.h"
#include "sleep.h"
#include "cmdmain.h"
@ -190,14 +191,20 @@ int CmdLFHitagSim(const char *Cmd) {
}
int CmdLFHitagReader(const char *Cmd) {
// UsbCommand c = {CMD_READER_HITAG};
// param_get32ex(Cmd,1,0,16);
UsbCommand c = {CMD_READER_HITAG};//, {param_get32ex(Cmd,0,0,10),param_get32ex(Cmd,1,0,16),param_get32ex(Cmd,2,0,16),param_get32ex(Cmd,3,0,16)}};
hitag_data* htd = (hitag_data*)c.d.asBytes;
hitag_function htf = param_get32ex(Cmd,0,0,10);
switch (htf) {
case 01: { //RHTSF_CHALLENGE
c = (UsbCommand){ CMD_READ_HITAG_S };
num_to_bytes(param_get32ex(Cmd,1,0,16),4,htd->auth.NrAr);
num_to_bytes(param_get32ex(Cmd,2,0,16),4,htd->auth.NrAr+4);
} break;
case 02: { //RHTSF_KEY
c = (UsbCommand){ CMD_READ_HITAG_S };
num_to_bytes(param_get64ex(Cmd,1,0,16),6,htd->crypto.key);
} break;
case RHT2F_PASSWORD: {
num_to_bytes(param_get32ex(Cmd,1,0,16),4,htd->pwd.password);
} break;
@ -216,6 +223,8 @@ int CmdLFHitagReader(const char *Cmd) {
PrintAndLog("Error: unkown reader function %d",htf);
PrintAndLog("Hitag reader functions");
PrintAndLog(" HitagS (0*)");
PrintAndLog(" 01 <nr> <ar> (Challenge) read all pages from a Hitag S tag");
PrintAndLog(" 02 <key> (set to 0 if no authentication is needed) read all pages from a Hitag S tag");
PrintAndLog(" Hitag1 (1*)");
PrintAndLog(" Hitag2 (2*)");
PrintAndLog(" 21 <password> (password mode)");
@ -257,14 +266,126 @@ int CmdLFHitagReader(const char *Cmd) {
return 0;
}
int CmdLFHitagSimS(const char *Cmd) {
UsbCommand c = { CMD_SIMULATE_HITAG_S };
char filename[FILE_PATH_SIZE] = { 0x00 };
FILE* pf;
bool tag_mem_supplied;
int len = strlen(Cmd);
if (len > FILE_PATH_SIZE)
len = FILE_PATH_SIZE;
memcpy(filename, Cmd, len);
if (strlen(filename) > 0) {
if ((pf = fopen(filename, "rb+")) == NULL) {
PrintAndLog("Error: Could not open file [%s]", filename);
return 1;
}
tag_mem_supplied = true;
if (fread(c.d.asBytes, 4*64, 1, pf) == 0) {
PrintAndLog("Error: File reading error");
fclose(pf);
return 1;
}
fclose(pf);
} else {
tag_mem_supplied = false;
}
// Does the tag comes with memory
c.arg[0] = (uint32_t) tag_mem_supplied;
SendCommand(&c);
return 0;
}
int CmdLFHitagCheckChallenges(const char *Cmd) {
UsbCommand c = { CMD_TEST_HITAGS_TRACES };
char filename[FILE_PATH_SIZE] = { 0x00 };
FILE* pf;
bool file_given;
int len = strlen(Cmd);
if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
memcpy(filename, Cmd, len);
if (strlen(filename) > 0) {
if ((pf = fopen(filename,"rb+")) == NULL) {
PrintAndLog("Error: Could not open file [%s]",filename);
return 1;
}
file_given = true;
if (fread(c.d.asBytes,8*60,1,pf) == 0) {
PrintAndLog("Error: File reading error");
fclose(pf);
return 1;
}
fclose(pf);
} else {
file_given = false;
}
//file with all the challenges to try
c.arg[0] = (uint32_t)file_given;
SendCommand(&c);
return 0;
}
int CmdLFHitagWP(const char *Cmd) {
UsbCommand c = { CMD_WR_HITAG_S };
hitag_data* htd = (hitag_data*)c.d.asBytes;
hitag_function htf = param_get32ex(Cmd,0,0,10);
switch (htf) {
case 03: { //WHTSF_CHALLENGE
num_to_bytes(param_get64ex(Cmd,1,0,16),8,htd->auth.NrAr);
c.arg[2]= param_get32ex(Cmd, 2, 0, 10);
num_to_bytes(param_get32ex(Cmd,3,0,16),4,htd->auth.data);
} break;
case 04: { //WHTSF_KEY
num_to_bytes(param_get64ex(Cmd,1,0,16),6,htd->crypto.key);
c.arg[2]= param_get32ex(Cmd, 2, 0, 10);
num_to_bytes(param_get32ex(Cmd,3,0,16),4,htd->crypto.data);
} break;
default: {
PrintAndLog("Error: unkown writer function %d",htf);
PrintAndLog("Hitag writer functions");
PrintAndLog(" HitagS (0*)");
PrintAndLog(" 03 <nr,ar> (Challenge) <page> <byte0...byte3> write page on a Hitag S tag");
PrintAndLog(" 04 <key> (set to 0 if no authentication is needed) <page> <byte0...byte3> write page on a Hitag S tag");
PrintAndLog(" Hitag1 (1*)");
PrintAndLog(" Hitag2 (2*)");
return 1;
} break;
}
// Copy the hitag function into the first argument
c.arg[0] = htf;
// Send the command to the proxmark
SendCommand(&c);
UsbCommand resp;
WaitForResponse(CMD_ACK,&resp);
// Check the return status, stored in the first argument
if (resp.arg[0] == false) return 1;
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"list", CmdLFHitagList, 1, "<outfile> List Hitag trace history"},
{"reader", CmdLFHitagReader, 1, "Act like a Hitag Reader"},
{"sim", CmdLFHitagSim, 1, "<infile> Simulate Hitag transponder"},
{"snoop", CmdLFHitagSnoop, 1, "Eavesdrop Hitag communication"},
{NULL, NULL, 0, NULL}
{"help", CmdHelp, 1, "This help"},
{"list", CmdLFHitagList, 1, "<outfile> List Hitag trace history"},
{"reader", CmdLFHitagReader, 1, "Act like a Hitag Reader"},
{"sim", CmdLFHitagSim, 1, "<infile> Simulate Hitag transponder"},
{"snoop", CmdLFHitagSnoop, 1, "Eavesdrop Hitag communication"},
{"writer", CmdLFHitagWP, 1, "Act like a Hitag Writer" },
{"simS", CmdLFHitagSimS, 1, "<hitagS.hts> Simulate HitagS transponder" },
{"checkChallenges", CmdLFHitagCheckChallenges, 1, "<challenges.cc> test all challenges" }, {
NULL,NULL, 0, NULL }
};
int CmdLFHitag(const char *Cmd)

View file

@ -107,6 +107,12 @@ typedef struct {
#define CMD_SIMULATE_HITAG 0x0371
#define CMD_READER_HITAG 0x0372
#define CMD_SIMULATE_HITAG_S 0x0368
#define CMD_TEST_HITAGS_TRACES 0x0367
#define CMD_READ_HITAG_S 0x0373
#define CMD_WR_HITAG_S 0x0375
#define CMD_EMU_HITAG_S 0x0376
#define CMD_SIMULATE_TAG_ISO_14443B 0x0381
#define CMD_SNOOP_ISO_14443B 0x0382
#define CMD_SNOOP_ISO_14443a 0x0383

View file

@ -7,11 +7,17 @@
//-----------------------------------------------------------------------------
// Hitag2 type prototyping
//-----------------------------------------------------------------------------
// HitagS added
//-----------------------------------------------------------------------------
#ifndef _HITAG2_H_
#define _HITAG2_H_
typedef enum {
RHTSF_CHALLENGE = 01,
RHTSF_KEY = 02,
WHTSF_CHALLENGE = 03,
WHTSF_KEY = 04,
RHT2F_PASSWORD = 21,
RHT2F_AUTHENTICATE = 22,
RHT2F_CRYPTO = 23,
@ -24,10 +30,12 @@ typedef struct {
typedef struct {
byte_t NrAr[8];
byte_t data[4];
} PACKED rht2d_authenticate;
typedef struct {
byte_t key[4];
byte_t key[6];
byte_t data[4];
} PACKED rht2d_crypto;
typedef union {

53
include/hitagS.h Normal file
View file

@ -0,0 +1,53 @@
//-----------------------------------------------------------------------------
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// HitagS emulation (preliminary test version)
//
// (c) 2016 Oguzhan Cicek, Hendrik Schwartke, Ralf Spenneberg
// <info@os-s.de>
//-----------------------------------------------------------------------------
#include <stdlib.h>
#include <string.h>
#include <hitag2.h>
#ifndef _HITAGS_H_
#define _HITAGS_H_
typedef enum PROTO_STATE {READY=0,INIT,AUTHENTICATE,SELECTED,QUIET,TTF,FAIL} PSTATE; //protocol-state
typedef enum TAG_STATE {NO_OP=0,READING_PAGE,WRITING_PAGE_ACK,WRITING_PAGE_DATA,WRITING_BLOCK_DATA} TSATE; //tag-state
typedef enum SOF_TYPE {STANDARD=0,ADVANCED,FAST_ADVANCED,ONE,NO_BITS} stype; //number of start-of-frame bits
struct hitagS_tag {
PSTATE pstate; //protocol-state
TSATE tstate; //tag-state
uint32_t uid;
uint32_t pages[16][4];
uint64_t key;
byte_t pwdl0,pwdl1,pwdh0;
//con0
int max_page;
stype mode;
//con1
bool auth; //0=Plain 1=Auth
bool TTFC; //Transponder Talks first coding. 0=Manchester 1=Biphase
int TTFDR; //data rate in TTF Mode
int TTFM; //the number of pages that are sent to the RWD
bool LCON; //0=con1/2 read write 1=con1 read only and con2 OTP
bool LKP; //0=page2/3 read write 1=page2/3 read only in Plain mode and no access in authenticate mode
//con2
//0=read write 1=read only
bool LCK7; //page4/5
bool LCK6; //page6/7
bool LCK5; //page8-11
bool LCK4; //page12-15
bool LCK3; //page16-23
bool LCK2; //page24-31
bool LCK1; //page32-47
bool LCK0; //page48-63
} ;
#endif

View file

@ -124,6 +124,13 @@ typedef struct{
#define CMD_SIMULATE_HITAG 0x0371
#define CMD_READER_HITAG 0x0372
#define CMD_SIMULATE_HITAG_S 0x0368
#define CMD_TEST_HITAGS_TRACES 0x0367
#define CMD_READ_HITAG_S 0x0373
#define CMD_WR_HITAG_S 0x0375
#define CMD_EMU_HITAG_S 0x0376
#define CMD_SIMULATE_TAG_ISO_14443B 0x0381
#define CMD_SNOOP_ISO_14443B 0x0382
#define CMD_SNOOP_ISO_14443a 0x0383

View file

@ -13,3 +13,67 @@
./mfkey64 9c599b32 82a4166c a1e458ce 6eea41e0 5cadf439
### Communication decryption
RDR 26
TAG 04 00
RDR 93 20
TAG 14 57 9f 69 b5
RDR 93 70 14 57 9f 69 b5 2e 51
TAG 08 b6 dd
RDR 60 14 50 2d
TAG ce 84 42 61
RDR f8 04 9c cb 05 25 c8 4f
TAG 94 31 cc 40
RDR 70 93 df 99
TAG 99 72 42 8c e2 e8 52 3f 45 6b 99 c8 31 e7 69 dc ed 09
RDR 8c a6 82 7b
TAG ab 79 7f d3 69 e8 b9 3a 86 77 6b 40 da e3 ef 68 6e fd
RDR c3 c3 81 ba
TAG 49 e2 c9 de f4 86 8d 17 77 67 0e 58 4c 27 23 02 86 f4
RDR fb dc d7 c1
TAG 4a bd 96 4b 07 d3 56 3a a0 66 ed 0a 2e ac 7f 63 12 bf
RDR 9f 91 49 ea
./mfkey64 14579f69 ce844261 f8049ccb 0525c84f 9431cc40 7093df99 9972428ce2e8523f456b99c831e769dced09 8ca6827b ab797fd369e8b93a86776b40dae3ef686efd c3c381ba 49e2c9def4868d1777670e584c27230286f4 fbdcd7c1 4abd964b07d3563aa066ed0a2eac7f6312bf 9f9149ea
Recovering key for:
uid: 14579f69
nt: ce844261
{nr}: f8049ccb
{ar}: 0525c84f
{at}: 9431cc40
{enc0}: 7093df99
{enc1}: 9972428ce2e8523f456b99c831e769dced09
{enc2}: 8ca6827b
{enc3}: ab797fd369e8b93a86776b40dae3ef686efd
{enc4}: c3c381ba
{enc5}: 49e2c9def4868d1777670e584c27230286f4
{enc6}: fbdcd7c1
{enc7}: 4abd964b07d3563aa066ed0a2eac7f6312bf
{enc8}: 9f9149ea
LFSR succesors of the tag challenge:
nt': 76d4468d
nt'': d5f3c476
Keystream used to generate {ar} and {at}:
ks2: 73f18ec2
ks3: 41c20836
Decrypted communication:
{dec0}: 3014a7fe
{dec1}: c26935cfdb95c4b4a27a84b8217ae9e48217
{dec2}: 30152eef
{dec3}: 493167c536c30f8e220b09675687067d4b31
{dec4}: 3016b5dd
{dec5}: 493167c536c30f8e220b09675687067d4b31
{dec6}: 30173ccc
{dec7}: 0000000000007e178869000000000000c4f2
{dec8}: 61148834
Found Key: [091e639cb715]

View file

@ -6,6 +6,7 @@
// Test-file: test2.c
#include "crapto1.h"
#include <stdio.h>
#include <string.h>
int main (int argc, char *argv[]) {
struct Crypto1State *revstate;
@ -21,32 +22,50 @@ int main (int argc, char *argv[]) {
printf("MIFARE Classic key recovery - based 64 bits of keystream\n");
printf("Recover key from only one complete authentication!\n\n");
if (argc < 6) {
printf(" syntax: %s <uid> <nt> <{nr}> <{ar}> <{at}>\n\n",argv[0]);
if (argc < 6 ) {
printf(" syntax: %s <uid> <nt> <{nr}> <{ar}> <{at}> [enc] [enc...]\n\n", argv[0]);
return 1;
}
sscanf(argv[1],"%x",&uid);
sscanf(argv[2],"%x",&nt);
sscanf(argv[3],"%x",&nr_enc);
sscanf(argv[4],"%x",&ar_enc);
sscanf(argv[5],"%x",&at_enc);
int encc = argc - 6;
int enclen[encc];
uint8_t enc[encc][120];
sscanf(argv[1], "%x", &uid);
sscanf(argv[2], "%x", &nt);
sscanf(argv[3], "%x", &nr_enc);
sscanf(argv[4], "%x", &ar_enc);
sscanf(argv[5], "%x", &at_enc);
for (int i = 0; i < encc; i++) {
enclen[i] = strlen(argv[i + 6]) / 2;
for (int i2 = 0; i2 < enclen[i]; i2++) {
sscanf(argv[i+6] + i2*2,"%2x", (uint8_t*)&enc[i][i2]);
}
}
printf("Recovering key for:\n");
printf(" uid: %08x\n",uid);
printf(" nt: %08x\n",nt);
printf(" {nr}: %08x\n",nr_enc);
printf(" {ar}: %08x\n",ar_enc);
printf(" {at}: %08x\n",at_enc);
/*
printf(" uid: %08x\n", uid);
printf(" nt: %08x\n", nt);
printf(" {nr}: %08x\n", nr_enc);
printf(" {ar}: %08x\n", ar_enc);
printf(" {at}: %08x\n", at_enc);
for (int i = 0; i < encc; i++) {
printf("{enc%d}: ", i);
for (int i2 = 0; i2 < enclen[i]; i2++) {
printf("%02x", enc[i][i2]);
}
printf("\n");
}
/*
uint32_t uid = 0x9c599b32;
uint32_t tag_challenge = 0x82a4166c;
uint32_t nr_enc = 0xa1e458ce;
uint32_t reader_response = 0x6eea41e0;
uint32_t tag_response = 0x5cadf439;
*/
// Generate lfsr succesors of the tag challenge
// Generate lfsr succesors of the tag challenge
printf("\nLFSR succesors of the tag challenge:\n");
printf(" nt': %08x\n",prng_successor(nt, 64));
printf(" nt'': %08x\n",prng_successor(nt, 96));
@ -59,6 +78,26 @@ int main (int argc, char *argv[]) {
printf(" ks3: %08x\n",ks3);
revstate = lfsr_recovery64(ks2, ks3);
// Decrypting communication using keystream if presented
if (argc > 6 ) {
printf("\nDecrypted communication:\n");
uint8_t ks4;
int rollb = 0;
for (int i = 0; i < encc; i++) {
printf("{dec%d}: ", i);
for (int i2 = 0; i2 < enclen[i]; i2++) {
ks4 = crypto1_byte(revstate, 0, 0);
printf("%02x", ks4 ^ enc[i][i2]);
rollb += 1;
}
printf("\n");
}
for (int i = 0; i < rollb; i++) {
lfsr_rollback_byte(revstate, 0, 0);
}
}
lfsr_rollback_word(revstate, 0, 0);
lfsr_rollback_word(revstate, 0, 0);
lfsr_rollback_word(revstate, nr_enc, 1);