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.
Sneak preview of what I've been working on....
> hf iclass reader 0
#db# Selected CSN: 90 e9 74 01 f7 ff 12 e0
#db# Readcheck on Sector 2
#db# CC: fa f7 ff ff ff ff ff ff
#db# Authenticate
#db# CC: c5 8e a4 00
#db# Dump Contents
#db# 00: xx xx xx xx f7 ff 12 e0
#db# 01: 12 ff ff ff e9 7f ff 3c
#db# 02: fa f7 ff ff ff ff ff ff
#db# 03: ff ff ff ff ff ff ff ff
#db# 04: ff ff ff ff ff ff ff ff
#db# 05: ff ff ff ff ff ff ff ff
#db# 07: d2 5e ea ba ab 2c 7a 93
#db# 08: 2a d4 c8 21 1f 99 68 71
#db# 09: 2a d4 c8 21 1f 99 68 71
#db# 0a: ff ff ff ff ff ff ff ff
#db# 0b: ff ff ff ff ff ff ff ff
#db# 0c: ff ff ff ff ff ff ff ff
#db# 0e: ff ff ff ff ff ff ff ff
#db# 0f: ff ff ff ff ff ff ff ff
Offline
Number 1 !
Offline
cool
Offline
sweet!
Offline
I am also diving into iclass... Could you explain what you are doing ? Are you using the global static keys to dump contents of a iclass standard tag?
The system I am working on now is using Elite class, which means that I am going to try to reproduce the attack from "dismantling iclass" and proxclone (http://proxclone.com/pdfs/Covert_Approa … HSKeys.pdf) by forum user carl55, but this time using proxmark. The first step will be to emulate the different CSN:s to obtain part of the key. After that, I'm going to have to implement the key diversification algorithm. I've searched, but haven't found that implemented anywhere, only described "mathematically" in Roel et al's paper. Any and all help appreciated in that task..
Offline
A related question: can the reader determine if a tag is using Elite mode or Standard mode? And vice versa, can a simulated tag determine if a reader uses standard or elite?
Last edited by holiman (2014-04-16 09:56:30)
Offline
I too would be interested in the specifics of what Pentura_prox is trying to develop. Implementing all of the iclass algorithms (including DES) in the Proxmark would seem to be an extremely difficult task.
Holiman:
Neither the card nor the reader can tell if the other entity is operating in Elite mode. They both simply calculate a MAC using the DivKey whenever they are trying to authenticate. If one of them is operating in Elite mode then their MAC will be rejected by the other since it was calculated using a different diversified key.
If they are both operating in the same mode then their calculated MACs will match since they were calculated using the same diversified key.
Regarding your other request ...
I have done a little work with the Diversified key algorithm. I have got it to work with approximately 98% of my test cases. Unfortunately it appears that HID has implemented their algorithm to require that each byte of the DivKey be unique. As a result, there are a few of these special cases where it is unclear how the replicated bytes are being modified. Be aware however that my test algorithm was written in Liberty Basic and not C/C++. You are welcome to it if it will be of any help. You are also welcome to my Diversified key Look-Up-Tables that were discussed in the paper you referenced above. Send me an email if you are interested. (info at proxclone dot com)
Offline
At the moment I'm working on (among other things) attempting to implement the math from Roel's paper into a working authentication method for the proxmark. The readers I currently have are standard, and for some bizzare reason don't update the e-purse, so currently I can snoop with the proxmark - capture the MAC, and then replay it with the proxmark on the command line (though the example above was originally with a hardset MAC).
Last edited by pentura_prox (2014-04-16 18:00:54)
Offline
@pentura_prox, that's what I'm attempting also (replicating Roels stuff). I've only just begun, not much to show yet, but it'd be interesting to see your code.
I have created a branch on github: https://github.com/Proxmark/proxmark3/tree/iclass-fixes where I've started to implement so a bunch of CSN's can be sent to the device in order to gather reader MAC's.
Last edited by holiman (2014-04-17 09:02:27)
Offline
A tidied up version of my MAC replay is here: https://github.com/PenturaLabs/proxmark … s-research
The authentication mechanism is currently private, very messy c poc, think i have the cipher state down, just need to build the DES and hash0 parts; email me and I'll sent it to you.
Last edited by pentura_prox (2014-04-17 14:29:46)
Offline
Don't have your email address; mine is martin at the domain swende dot se.
I have a first attempt at the cipher state, in c:ish language, and hash1 working in python.
Offline
I've implemented the cipher, and can now do MAC calculations. Here's the repo: https://github.com/holiman/loclass/tree/master/loclass
Still todo is key diversification, it's not complete yet.
Offline
Cool! Nice work... we're getting there.
Offline
Getting even closer, I committed a non-working implementation the key diversification algorithm now. Any help appreciated getting those last few bytes correct...
EDIT: (Oh, let me know if you need to compile, there's a piece intentionally missing from the codebase)
Last edited by holiman (2014-04-23 20:04:13)
Offline
I think I've got the DES bit down, so its just hash0 for me.
Last edited by midnitesnake (2014-04-23 22:03:56)
Offline
I've also got the DES down, hash0 is the only remaining part.. If you throw it up somewhere, we can compare notes... ?
Offline
According to this article it should produce something like:
key: 1122334455667788
csn: bbbbaaaabbbbeeee
hash2: 8a e9 68 11 03 52 6e 2e bb 3f ec dd da 8e 90 e8
b3 90 09 54 b1 b4 5f e8 7e dd 37 3f 0d 00 e1 ee
61 f8 ea 79 fe f6 be 5e a6 15 16 84 ef 6d a2 0a
06 1a 3e d4 4b 19 b9 8d 1a a8 77 30 9c 0e d5 ee
35 d0 1b 73 e1 76 65 b2 dc 1f 4e cc e3 8d 2f f4
12 27 0c 9e c2 88 87 b1 d7 3d 60 d7 5c ed eb a5
a7 1f 96 5f d5 fc d6 a1 e2 42 c1 70 fb 99 06 ee
58 08 4c f7 37 fd a0 4e f4 de 46 fa 31 b6 98 5e
hash1: 001c365508601122
Ksel: 6c8d44f92a2d01bf
{csn}: d6ad3ca619659e6b
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
original: d6 ad 2b 39 19 19 19 18 0a 0f
x|y|z': d6 ad 2b 3a 1b 1c 19 19 0c 12
x|y|z^: d6 ad 2b 3a 1b 1c 19 00 0c 12
p|y|z^: 1e ad 2b 3a 1b 1c 19 00 0c 12
p|y|z~: 1e ad 19 2c 3b 1c 1d 00 0c 12
k: cd 58 8a c8 3a ff 19 db
hash0: cd588ac83aff19db
and
key: cd588ac83aff19db
cC: 1122334455667788
nR: aabbccdd
reader tag
1122334455667788
<-----------------------
05 aabbccdddfbb211d
----------------------->
f2d98b5f
<-----------------------
Offline
My current status;
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
origin : d6 ad 2b 39 19 19 19 18 0a 0f
x|y|z' : 00 00 2b 3a 1b 1c 19 19 0c 12
x|y|z^ : 00 00 2b 3a 1b 1c 19 19 0c 12
p:1e
0|0|z~ : 00 00 19 2c 3b 1c 1d 00 0c 12
uint8_t hash0[] = {0xcd,0x59,0x89,0xc8,0x3a,0x00,0x18,0xdb,};
So, compared to the correct key, it's got these differences:
{0, +1,-1, 0, 0, +1, +1,0]
Offline
I think I got it
origin : d6 ad 2b 39 19 19 19 18 0a 0f
x|y|z' : 00 00 2b 3a 1b 1c 19 19 0c 12
x|y|z^ : 00 00 2b 3a 1b 1c 19 19 0c 12
p:1e
0|0|z~ : 00 00 19 2c 3b 1c 1d 00 0c 12
uint8_t hash0__[] = {0xcd,0x58,0x8a,0xc8,0x3a,0xff,0x19,0xdb,};
uint8_t correct[] = {0xcd,0x58,0x8a,0xc8,0x3a,0xff,0x19,0xdb,};
But not quite, most of my other testcases failed:
48 errors occurred (57 testcases)
Last edited by holiman (2014-04-23 22:32:51)
Offline
I've updated the repo with my changes. I now changed two things to align with "lockpicking " algorithm instead of "dismantling".
* k[ i] leftmost bit (0) is set to y[7-1]
* p is complemented depending on x[7], not x[0]
Last edited by holiman (2014-04-23 23:03:11)
Offline
proxmarkzzz, I hope you didn't pay for that document.
Offline
It is a different document, but indeed according to google another version of the article is publicly available. Hash0 is indeed challenging.
{csn}: 0102030405060708
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
original: 01 02 08 1c 20 01 05 10 30 00
x|y|z': 01 02 08 1d 22 04 05 11 32 03
x|y|z^: 01 02 08 1d 22 04 05 11 32 03
p|y|z^: e8 02 08 1d 22 04 05 11 32 03
p|y|z~: e8 02 05 11 32 09 03 1e 23 05
k: 0b dd 65 12 07 3c 46 0a
hash0: 0bdd6512073c460a
{csn}: 1020304050607080
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
original: 10 20 00 02 07 18 10 01 04 0c
x|y|z': 10 20 00 03 09 1b 10 02 06 0f
x|y|z^: 10 20 00 03 09 1b 10 02 06 0f
p|y|z^: 4b 20 00 03 09 1b 10 02 06 0f
p|y|z~: 4b 20 01 04 10 0a 02 06 1c 0f
k: 02 08 21 14 05 f3 38 1f
hash0: 0208211405f3381f
{csn}: 1122334455667788
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
original: 11 22 08 1e 27 19 15 11 34 0c
x|y|z': 11 22 08 1f 29 1c 15 12 36 0f
x|y|z^: 11 22 08 1f 29 1c 15 12 36 0f
p|y|z^: b2 22 08 1f 29 1c 15 12 36 0f
p|y|z~: b2 22 15 09 12 36 20 2a 0f 1d
k: 2b ee 25 6d 40 ac 1f 3a
hash0: 2bee256d40ac1f3a
{csn}: abcdabcdabcdabcd
hash0: a91c9ec66f7da592
{csn}: bcdabcdabcdabcda
hash0: 79ca5796a474e19b
{csn}: cdabcdabcdabcdab
hash0: a8901b9f7ec76da4
{csn}: dabcdabcdabcdabc
hash0: 357aa8e0979a5b8d
Offline
I have been busy trying the CSN-iteration attack against actual reader(s). There are some problems, both against my Omnikey 5321 and the HID wall-mounted reader (one of these, don't know which http://www.hidglobal.com/products/readers/iclass). I guess it's the same issues carl55 noticed when trying the attack using proxmark. I also believe that it is due to timing issues.
Additionally, after piwi's remake of 'hf 14 list', the iclass trace-functionality which used the same mechanism didn't work anymore. I have fixed some of those issues on my iclass-fixes branch (https://github.com/Proxmark/proxmark3/tree/iclass-fixes), but the timing-information I use is sloppy at best.
So, my hope was to snoop some valid transactions and see what timings a 'legit' transaction has, and then try to emulate that. Therefore, I would like to be able to measure timings with the same accuracy as iso14443a.
Some questions,
1. When reading reader->tag data, OutOfNDecoding is used. It looks very much like the millerdecoding in use by iso14443a.
2. When reading tag->reader data, Manchesterdecoding is used. It looks very much like the manchesterdecoding in use by iso14443a.
My idea is that maybe I could reuse the same functions in both cases. Feasible?
Now, I'm going to take a new look at those hash0 inputs!
Offline
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
origin : d6 ad 2b 39 19 19 19 18 0a 0f
x|y|z' : 00 00 2b 3a 1b 1c 19 19 0c 12
x|y|z^ : 00 00 2b 3a 1b 1c 19 19 0c 12
p:1e
0|0|z~ : 00 00 19 2c 3b 1c 1d 00 0c 12
hash0 :cd588ac83aff19db
expected :cd588ac83aff19db
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
origin : 01 02 08 1c 20 01 05 10 30 00
x|y|z' : 00 00 08 1d 22 04 05 11 32 03
x|y|z^ : 00 00 08 1d 22 04 05 11 32 03
p:e8
0|0|z~ : 00 00 05 11 32 09 03 1e 23 05
hash0 :0bdd6512073c460a
expected :0bdd6512073c460a
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
origin : 10 20 00 02 07 18 10 01 04 0c
x|y|z' : 00 00 00 03 09 1b 10 02 06 0f
x|y|z^ : 00 00 00 03 09 1b 10 02 06 0f
p:4b
0|0|z~ : 00 00 01 04 10 0a 02 06 1c 0f
hash0 :0208211405f3381f
expected :0208211405f3381f
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
origin : 11 22 08 1e 27 19 15 11 34 0c
x|y|z' : 00 00 08 1f 29 1c 15 12 36 0f
x|y|z^ : 00 00 08 1f 29 1c 15 12 36 0f
p:b2
0|0|z~ : 00 00 15 09 12 36 20 2a 0f 1d
hash0 :2bee256d40ac1f3a
expected :2bee256d40ac1f3a
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
origin : ab cd 2b 0d 2b 0d 2b 0d 2b 0d
x|y|z' : 00 00 2b 0e 2d 10 2b 0e 2d 10
x|y|z^ : 00 00 2b 0e 2d 10 2b 0e 2d 10
p:8e
0|0|z~ : 00 00 2b 2c 0f 2e 0e 2d 10 11
hash0 :a958e2a41d5bdfde
expected :a91c9ec66f7da592
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
origin : cd ab 3c 1a 3c 1a 3c 1a 3c 1a
x|y|z' : 00 00 3c 1b 3e 1d 3c 1b 3e 1d
x|y|z^ : 00 00 3c 1b 3e 1d 3c 1b 3e 1d
p:93
0|0|z~ : 00 00 3d 1c 3c 1b 3f 3e 1d 1e
hash0 :86c879c97e833bc4
expected :79ca5796a474e19b
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
origin : da bc 0d 2b 0d 2b 0d 2b 0d 2b
x|y|z' : 00 00 0d 2c 0f 2e 0d 2c 0f 2e
x|y|z^ : 00 00 0d 2c 0f 2e 0d 2c 0f 2e
p:2e
0|0|z~ : 00 00 0d 0e 2d 10 2c 2f 0f 2e
hash0 :1b1ca6e0a7a21fa3
expected :a8901b9f7ec76da4
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
origin : da bc 1a 3c 1a 3c 1a 3c 1a 3c
x|y|z' : 00 00 1a 3d 1c 03 1a 3d 1c 3f
x|y|z^ : 00 00 1a 3d 1c 03 1a 3d 1c 3f
p:2e
0|0|z~ : 00 00 1a 1b 3e 1d 3d 04 1c 3f
hash0 :353684c685f83981
expected :357aa8e0979a5b8d
Almost, but the latter ones (testcases without details) are failing for me...
Offline
{csn}: abcdabcdabcdabcd
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
original: ab cd 0d 2f 1a 33 2b 36 3c 2a
x|y|z': ab cd 0d 30 1c 36 2b 37 3e 2d
x|y|z^: ab cd 0d 30 1c 36 2b 37 3e 2d
p|y|z^: 8e cd 0d 30 1c 36 2b 37 3e 2d
p|y|z~: 8e cd 2b 0e 31 1d 37 3e 2d 37
k: a9 1c 9e c6 6f 7d a5 92
hash0: a91c9ec66f7da592
{csn}: bcdabcdabcdabcda
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
original: bc da 1a 33 2b 36 3c 2a 0d 2f
x|y|z': bc da 1a 34 2d 39 3c 2b 0f 32
x|y|z^: bc da 1a 34 2d 39 3c 2b 0f 32
p|y|z^: 3a da 1a 34 2d 39 3c 2b 0f 32
p|y|z~: 3a da 3c 1b 2b 35 2e 3a 0f 32
k: 79 ca 57 96 a4 74 e1 9b
hash0: 79ca5796a474e19b
{csn}: cdabcdabcdabcdab
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
original: cd ab 2b 36 3c 2a 0d 2f 1a 33
x|y|z': cd ab 2b 37 3e 2d 0d 30 1c 36
x|y|z^: cd ab 2b 37 3e 2d 0d 30 1c 36
p|y|z^: 93 ab 2b 37 3e 2d 0d 30 1c 36
p|y|z~: 93 ab 2c 38 0d 30 3f 1c 36 2e
k: a8 90 1b 9f 7e c7 6d a4
hash0: a8901b9f7ec76da4
{csn}: dabcdabcdabcdabc
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
original: da bc 3c 2a 0d 2f 1a 33 2b 36
x|y|z': da bc 3c 2b 0f 32 1a 34 2d 39
x|y|z^: da bc 3c 2b 0f 32 1a 34 2d 39
p|y|z^: 2e bc 3c 2b 0f 32 1a 34 2d 39
p|y|z~: 2e bc 1a 3d 2c 10 34 33 2d 39
k: 35 7a a8 e0 97 9a 5b 8d
hash0: 357aa8e0979a5b8d
{csn}: 21ba6565071f9299
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
original: 21 ba 19 0a 39 07 07 14 16 19
x|y|z': 21 ba 19 0b 3b 0a 07 15 18 1c
x|y|z^: 21 ba 19 0b 3b 0a 07 15 18 1c
p|y|z^: 8b ba 19 0b 3b 0a 07 15 18 1c
p|y|z~: 8b ba 1a 0c 07 3c 15 18 1c 0b
k: 34 e8 0f 88 d5 cf 39 ea
hash0: 34e80f88d5cf39ea
{csn}: 14e2adfc5bb7e134
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
original: 14 e2 34 04 3e 2d 1b 31 1f 2b
x|y|z': 14 e2 34 05 03 30 1b 32 21 2e
x|y|z^: 14 e2 34 05 03 30 1b 32 21 2e
p|y|z^: 55 e2 34 05 03 30 1b 32 21 2e
p|y|z~: 55 e2 35 1b 06 32 04 21 31 2e
k: 6a c9 0c 65 08 bd 9e a3
hash0: 6ac90c6508bd9ea3
Offline
Sweet! I don't have time to test all of them now, but it seems my algorithm implementation works. I had done some mixup with the initial input values, I ran through the top two ones using the correct values, and it matches. More thorough testing later...
Thanks a lot!
Offline
Hm, I see now why I got the values wrong.. When using the value {csn} directly, for example
{csn}: 14e2adfc5bb7e134
If the value was indeed xyz0z1z2z3z4z5z6z7, let's look at e.g. z0:
x = 0x14
y = 0xe2
0xad = 1010 1101 => z0 = 1010 11 => z0 = 0010 1011 => z0 = 0x2b.
So, in the example above, my code gives the following 'original':
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
origin : 14 e2 2b 1f 31 1b 2d 3e 04 34
However, in the example above:
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
original: 14 e2 34 04 3e 2d 1b 31 1f 2b
Looking at it closer, it appears that the values z0-z7 are reversed, as if the {csn} was constructed the following way:
{csn} = xyz7z6z5z4z3z2z1z0
That's not how I interpret the paper(s)... ?
Offline
So, if I take the {csn} value and transform it one step, all these testcases work.
Testing with anohter hash input
{csn} 0102030405060708
{csn-revz} 010221c801150c00
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
origin : 01 02 08 1c 20 01 05 10 30 00
0|0|z' : 00 00 08 1d 22 04 05 11 32 03
0|0|z^ : 00 00 08 1d 22 04 05 11 32 03
p:e8
0|0|z~ : 00 00 05 11 32 09 03 1e 23 05
hash0 :0bdd6512073c460a
expected :0bdd6512073c460a
{csn} 1020304050607080
{csn-revz} 10200021d840110c
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
origin : 10 20 00 02 07 18 10 01 04 0c
0|0|z' : 00 00 00 03 09 1b 10 02 06 0f
0|0|z^ : 00 00 00 03 09 1b 10 02 06 0f
p:4b
0|0|z~ : 00 00 01 04 10 0a 02 06 1c 0f
hash0 :0208211405f3381f
expected :0208211405f3381f
{csn} 1122334455667788
{csn-revz} 112221e9d9551d0c
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
origin : 11 22 08 1e 27 19 15 11 34 0c
0|0|z' : 00 00 08 1f 29 1c 15 12 36 0f
0|0|z^ : 00 00 08 1f 29 1c 15 12 36 0f
p:b2
0|0|z~ : 00 00 15 09 12 36 20 2a 0f 1d
hash0 :2bee256d40ac1f3a
expected :2bee256d40ac1f3a
{csn} abcdabcdabcdabcd
{csn-revz} abcd36f6b3af6f2a
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
origin : ab cd 0d 2f 1a 33 2b 36 3c 2a
0|0|z' : 00 00 0d 30 1c 36 2b 37 3e 2d
0|0|z^ : 00 00 0d 30 1c 36 2b 37 3e 2d
p:8e
0|0|z~ : 00 00 2b 0e 31 1d 37 3e 2d 37
hash0 :a91c9ec66f7da592
expected :a91c9ec66f7da592
{csn} bcdabcdabcdabcda
{csn-revz} bcda6b3af6f2a36f
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
origin : bc da 1a 33 2b 36 3c 2a 0d 2f
0|0|z' : 00 00 1a 34 2d 39 3c 2b 0f 32
0|0|z^ : 00 00 1a 34 2d 39 3c 2b 0f 32
p:3a
0|0|z~ : 00 00 3c 1b 2b 35 2e 3a 0f 32
hash0 :79ca5796a474e19b
expected :79ca5796a474e19b
{csn} cdabcdabcdabcdab
{csn-revz} cdabaf6f2a36f6b3
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
origin : cd ab 2b 36 3c 2a 0d 2f 1a 33
0|0|z' : 00 00 2b 37 3e 2d 0d 30 1c 36
0|0|z^ : 00 00 2b 37 3e 2d 0d 30 1c 36
p:93
0|0|z~ : 00 00 2c 38 0d 30 3f 1c 36 2e
hash0 :a8901b9f7ec76da4
expected :a8901b9f7ec76da4
{csn} dabcdabcdabcdabc
{csn-revz} dabcf2a36f6b3af6
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
origin : da bc 3c 2a 0d 2f 1a 33 2b 36
0|0|z' : 00 00 3c 2b 0f 32 1a 34 2d 39
0|0|z^ : 00 00 3c 2b 0f 32 1a 34 2d 39
p:2e
0|0|z~ : 00 00 1a 3d 2c 10 34 33 2d 39
hash0 :357aa8e0979a5b8d
expected :357aa8e0979a5b8d
{csn} 21ba6565071f9299
{csn-revz} 21ba64ae471d4599
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
origin : 21 ba 19 0a 39 07 07 14 16 19
0|0|z' : 00 00 19 0b 3b 0a 07 15 18 1c
0|0|z^ : 00 00 19 0b 3b 0a 07 15 18 1c
p:8b
0|0|z~ : 00 00 1a 0c 07 3c 15 18 1c 0b
hash0 :34e80f88d5cf39ea
expected :34e80f88d5cf39ea
{csn} 14e2adfc5bb7e134
{csn-revz} 14e2d04fad6f17eb
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
origin : 14 e2 34 04 3e 2d 1b 31 1f 2b
0|0|z' : 00 00 34 05 03 30 1b 32 21 2e
0|0|z^ : 00 00 34 05 03 30 1b 32 21 2e
p:55
0|0|z~ : 00 00 35 1b 06 32 04 21 31 2e
hash0 :6ac90c6508bd9ea3
expected :6ac90c6508bd9ea3
I have yet to see if I can somehow make the algorithm work with the values I have obtained from carl55, which were calculated by the reader.
Offline
clap clap well done!
Using your framework, I can replicate the example in the paper. Spent some time today reversing the encrypted CSN, jump on this forum to post results and discover you fixed the code 2hrs earlier.
DES Key: dc b5 f5 f7 d9 17 06 4f
DivR Key: e0 33 ca 41 9a ee 43 f9
Calculated_MAC 1d49c9da
Offline
Thanks.. All the examples in this thread work, but I also have some testcases from carl55. He let the reader calculate some values, and I fail on 48 out of 65 diversified keys. The temporary keys ({csn}) are calculated correctly, but not the diversified keys.
Example:
Div key != expected result
uint8_t csn [] = {0xc6,0x3a,0x1c,0x25,0x63,0x5a,0x2f,0x0e,};
uint8_t {csn} [] = {0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,};
uint8_t hash0 [] = {0x06,0x04,0x02,0x08,0x01,0x03,0x05,0x07,};
uint8_t Expected[] = {0x02,0x04,0x06,0x08,0x01,0x03,0x05,0x0b,};
Div key != expected result
uint8_t csn [] = {0xd9,0x0e,0xd7,0x30,0xe2,0xad,0xa9,0x87,};
uint8_t {csn} [] = {0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,};
uint8_t hash0 [] = {0x0a,0x04,0x06,0x08,0x01,0x03,0x05,0x07,};
uint8_t Expected[] = {0x02,0x04,0x06,0x08,0x01,0x03,0x05,0x0f,};
Div key != expected result
uint8_t csn [] = {0x6b,0x81,0xc6,0xd1,0x05,0x09,0x87,0x1e,};
uint8_t {csn} [] = {0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,};
uint8_t hash0 [] = {0x12,0x04,0x06,0x08,0x01,0x03,0x05,0x07,};
uint8_t Expected[] = {0x02,0x04,0x06,0x08,0x01,0x03,0x05,0x17,};
Div key != expected result
uint8_t csn [] = {0xb4,0xa7,0x1e,0x02,0x54,0x37,0x43,0x35,};
uint8_t {csn} [] = {0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,};
uint8_t hash0 [] = {0x22,0x04,0x06,0x08,0x01,0x03,0x05,0x07,};
uint8_t Expected[] = {0x02,0x04,0x06,0x08,0x01,0x03,0x05,0x27,};
Last edited by holiman (2014-05-01 20:48:09)
Offline
WHoa!! Finally got it!
Hashing seems to work (65 testcases)
When I did the same trick with reversing z-order as in the examples above, it worked. I tried it three hours ago, but I made an error which I just now discovered. I'll submit some cleaned up code in a moment.
Offline
Alright, the library is now committed in full..
https://github.com/holiman/loclass
It's got MAC and hash0, there are still some hash functions to implement for elite cracking, but that should be fairly simple.. Now, the next step is really getting the pm3 to simulate tags correctly..
Thanks to carl55, penturaprox and proxmarkzzz!
Offline
yey...
CSN Key: bb bb aa aa bb bb ee ee
DES Key: d6 ad 3c a6 19 65 9e 6b
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
origin : d6 ad 2b 39 19 19 19 18 0a 0f
x|y|z' : d6 ad 2b 3a 1b 1c 19 19 0c 12
x|y|z^ : d6 ad 2b 3a 1b 1c 19 19 0c 12
p|y|z^ : 1e ad 2b 3a 1b 1c 19 19 0c 12
p|y|z~ : 1e ad 19 2c 3b 1c 1d 00 0c 12
DivC Key: cd 58 8a c8 3a ff 19 db
Calculated_MAC dfbb211d
Update: Woowho! Sample action from a recent bought card:
CSN Key: 87 4a 11 01 f8 ff 12 e0
DES Key: 7d 32 56 b6 90 61 51 c1
| x| y|z0|z1|z2|z3|z4|z5|z6|z7|
origin : 7d 32 01 07 15 18 10 1a 2b 15
x|y|z' : 7d 32 01 08 17 1b 10 1b 2d 18
x|y|z^ : 7d 32 01 08 17 1b 10 1b 2d 18
p|y|z^ : aa 32 01 08 17 1b 10 1b 2d 18
p|y|z~ : aa 32 10 02 1b 09 2d 18 18 1c
DivC Key: 21 fc 37 12 a5 d0 31 38
Calculated_MAC 5a61a146
proxmark3> hf iclass replay 5A61A146
#db# Selected CSN: 87 4a 11 01 f8 ff 12 e0
#db# Readcheck on Sector 2
#db# CC: fe ff ff ff ff ff ff ff
#db# Authenticate
#db# AA: 5a 61 a1 46
#db# AR: 2e e5 6c b9
#db# Dump Contents
#db# 00: 87 4a 11 01 f8 ff 12 e0
#db# 01: 12 ff ff ff 7f 1f ff 3c
#db# 02: fe ff ff ff ff ff ff ff
#db# 03: ff ff ff ff ff ff ff ff
#db# 04: ff ff ff ff ff ff ff ff
#db# 05: ff ff ff ff ff ff ff ff
#db# 06: 03 03 03 03 00 03 e0 17
#db# 07: 07 4f b8 50 a7 e8 aa 79
#db# 08: 2a d4 c8 21 1f 99 68 71
#db# 09: 2a d4 c8 21 1f 99 68 71
#db# 0a: ff ff ff ff ff ff ff ff
#db# 0b: ff ff ff ff ff ff ff ff
#db# 0c: ff ff ff ff ff ff ff ff
#db# 0d: ff ff ff ff ff ff ff ff
#db# 0e: ff ff ff ff ff ff ff ff
#db# 0f: ff ff ff ff ff ff ff ff
#db# 10: ff ff ff ff ff ff ff ff
#db# 11: ff ff ff ff ff ff ff ff
#db# 12: ff ff ff ff ff ff ff ff
#db# 13: ff ff ff ff ff ff ff ff
#db# 14: ff ff ff ff ff ff ff ff
#db# 15: ff ff ff ff ff ff ff ff
#db# 16: ff ff ff ff ff ff ff ff
#db# 17: ff ff ff ff ff ff ff ff
#db# 18: ff ff ff ff ff ff ff ff
#db# 19: ff ff ff ff ff ff ff ff
#db# 1a: ff ff ff ff ff ff ff ff
#db# 1b: ff ff ff ff ff ff ff ff
#db# 1c: ff ff ff ff ff ff ff ff
#db# 1d: ff ff ff ff ff ff ff ff
#db# 1e: ff ff ff ff ff ff ff ff
#db# 1f: ff ff ff ff ff ff ff ff
and modding Pentura_prox's Code:
proxmark3> hf iclass dump [ADD SECRET KEY HERE] 874A1101F8FF12E0 FEFFFFFFFFFFFFFF
#db# Selected CSN: 87 4a 11 01 f8 ff 12 e0
#db# Readcheck on Sector 2
#db# CC: fe ff ff ff ff ff ff ff
#db# Authenticate
#db# AA: 5a 61 a1 46
#db# AR: 2e e5 6c b9
#db# Dump Contents
#db# 00: 87 4a 11 01 f8 ff 12 e0
#db# 01: 12 ff ff ff 7f 1f ff 3c
#db# 02: fe ff ff ff ff ff ff ff
#db# 03: ff ff ff ff ff ff ff ff
#db# 04: ff ff ff ff ff ff ff ff
#db# 05: ff ff ff ff ff ff ff ff
#db# 06: 03 03 03 03 00 03 e0 17
#db# 07: 07 4f b8 50 a7 e8 aa 79
#db# 08: 2a d4 c8 21 1f 99 68 71
#db# 09: 2a d4 c8 21 1f 99 68 71
#db# 0a: ff ff ff ff ff ff ff ff
#db# 0b: ff ff ff ff ff ff ff ff
#db# 0c: ff ff ff ff ff ff ff ff
#db# 0d: ff ff ff ff ff ff ff ff
#db# 0e: ff ff ff ff ff ff ff ff
#db# 0f: ff ff ff ff ff ff ff ff
#db# 10: ff ff ff ff ff ff ff ff
#db# 11: ff ff ff ff ff ff ff ff
#db# 12: ff ff ff ff ff ff ff ff
#db# 13: ff ff ff ff ff ff ff ff
#db# 14: ff ff ff ff ff ff ff ff
#db# 15: ff ff ff ff ff ff ff ff
#db# 16: ff ff ff ff ff ff ff ff
#db# 17: ff ff ff ff ff ff ff ff
#db# 18: ff ff ff ff ff ff ff ff
#db# 19: ff ff ff ff ff ff ff ff
#db# 1a: ff ff ff ff ff ff ff ff
#db# 1b: ff ff ff ff ff ff ff ff
#db# 1c: ff ff ff ff ff ff ff ff
#db# 1d: ff ff ff ff ff ff ff ff
#db# 1e: ff ff ff ff ff ff ff ff
#db# 1f: ff ff ff ff ff ff ff ff
Last edited by midnitesnake (2014-05-02 11:05:05)
Offline
Great work! Keep hacking the standard cards (I don't have any, I want to do the elite hack).
Another idea:
We could do a reader-fingerprint where the user does not need the master key (because I think we still don't want the master key committed to the source code...).
Basically the idea is to use the reader and check if it expects a standard card or an elite card. Since we have cc and nr is only 4 bytes, that gives an entropy of /edit-wrong/ possible MACs (with the master key and hardcoded cc). So a lookuptable containing basically
NR MAC
0000 1234
0001 A12B
...
Then the client could check the lookuptable for the given NR, see if the MAC corresponds to it: if so, the reader expects a standard card. The size of the lookuptable would be 4b * 4096= 16k. Anyone could do that test without requiring the master key. Even if someone does not have the master key, it could be useful to fingerprint the system and see that it's vulnerable.
Makes sense? Did I miss something?
EDIT: Yes, I did miss something, the entrypy of 4 bytes is more like 4 giga. Ignore this post.
Last edited by holiman (2014-05-06 07:16:52)
Offline
Forgive me if Im wrong, but I thought the cards were the same.
I thought with 'high' or 'elite' cards that the master key is different; along with key diversification; which changes the keys stored/used to access the card. Therefore, they can't be copied/cloned without knowledge of these new-keys.
As for your fingerprint idea, I think something should be possible:
We have the functions to precompute everything for standard cards.
So using a specific (or even user supplied) card id, nr and cc, we can pre-calculate the MACs expected from the reader (using the master key); if the MACs don't match our pre-computed ones we know its high-security or 'elite'.
Hopefully, no need for lookup tables, as this can all be calculated on the fly.
Again, would need to except master-key as an argument, to avoid including it in the source.
Offline
Forgive me if Im wrong, but I thought the cards were the same.
I thought with 'high' or 'elite' cards that the master key is different; along with key diversification; which changes the keys stored/used to access the card. Therefore, they can't be copied/cloned without knowledge of these new-keys.
Exactly, but the most straight-forward way to obtain the key (imho) is to use the proxclone-attack by carl55. (It does the same thing as in "dismantling... " but more straightforward and not as stealthy). Basically, simulate 'malicious' CSNs, the first one leaks 3 bits (and requires a lot of MAC calculations), each one after that leak another bit. 126 simulations and the key has been leaked. So thats why I am now working on pm3 iclass simulation.
As for your fingerprint idea, I think something should be possible:
We have the functions to precompute everything for standard cards.
So using a specific (or even user supplied) card id, nr and cc, we can pre-calculate the MACs expected from the reader (using the master key); if the MACs don't match our pre-computed ones we know its high-security or 'elite'.
Hopefully, no need for lookup tables, as this can all be calculated on the fly.
Again, would need to except master-key as an argument, to avoid including it in the source.
We'll have to choose:
1. Calculate on the fly, and require master key as argument. OR
2. Use precomputed values, and dont require master key.
I thought number 2 would be a nice gift to all keyless pentesters out there
Offline
I like the Fingerprint idea, and would suggest 3:rd alternative,
If the client is online, someone with the masterkey could provide a webservice which calcs the mac per request (or return a value from a lookup table). No need for the masterkey in the client.
Offline
A hosted key store is fine. Then you've only got to worry about the servers integrity.
Also, you might want to store salts, SNMP authentication keys , SNMP private keys, secure channel keys, ATRs,... in addition to the iClass app authentication keys, iClass app encryption keys, etc...
Offline
@midnitesnake: I perhaps misunderstood your question, and only now understood it. What I meant with "no standard cards" was that for the tags and readers I have access to test with, I don't know the key. So I can't test e.g. dumping a card. Not yet.
@iceman: if someone hosts a mac calculator... But I'm hestitant about making the pm3 connect to and fetch data from a remote source...
Oh, and I miscalculated above... the lookuptable really becomes quite large...
Offline
@0xFFFF, do I detect a sense of sacasm here?
@holiman, well, i thought of the pm3 client, not the onboard logic.. but I might have missunderstood your intentions where in the code this lookup function would be needed.
Offline
Yes, i'm also talking about the client. I suspect some users are still running it as root, and I suspect there are exploitable vulnerabilities in that codebase. I would not want to slap on a networking interface which fetches data from remote, with all the headaches about ssl verification etc etc. But if someone wants to put up a web service where the user can paste the NR and get back the 'standard' MAC, then the client could say "You can verify if the system is using standard by going to http://icemanservices.com/maccalc?nr=0123".
Hm, in fact, it does not have to be stored key on the serverside, we could host the lookuptable on there, but split it up on smaller js files, and load the correct file (01XX.js) on the client. That way no secrets would need to be stored on the server, and no active server components.
Last edited by holiman (2014-05-06 09:47:56)
Offline
I like the idea, that would still require some net interface.
How large would a 01xx.js file be? will it contain pure data in json? or just 4bytes?
Offline
00112233.js would contain one mac : e.g AABBCCDD
001122XX.js would contain 255 macs
It would probably be simpler to use text instead of binary, so each mac would be 4 binary-> 8 ascii.
001122XX.js => 8*255 bytes~ 2K.
For simplicity, we could pack them one step more: 0011XXXX.js would be 500K. Sums up to 65 thousand files of 500K each, if I counted correctly.
Offline
@iceman - Yeah, sarcasm.
Personally, I would really like to expose keys / vulnerabilities / exploits like these. It helps with the understanding and progression of the technology.
For the sake of the end user, it is unfair and immoral. What was once regarded as a secure system is now a playground for anyone who can google stuff.
Offline
+1
At least don't make it "easy" for the "common people" to just come here, download some stuff, press Enter and start "harming" the end users or make money out of your work.
Offline
What we're proposing is to make it possible to check if the system is standard or elite. I'm not sure which part of that sparked controversy... Nobody here suggested actually exposing the keys (although, that would make things a lot simpler..)
Offline
Also, I don't have a problem if other people make money out of my work. I make money out of others work every day that I use open source tools in my job...
Offline
I guess there is some people here that feel that they been used. I don't mind that people try to make a living out of my work. I too make money out of others work every day in my job.
It could also be some feeling that some users haven't gotten credit for their work. what do I know?
Offline
Interesting idea.
However, would it not be easier to let the investigator buy a OMNIKEY 5321 CL USB Smart Card Reader from HID. You can send a command to the reader to internally load the (default) HID iClass Standard secret key and try authenticate with it. It will not reveal the secret key, it just loads the key and allows the investigator to use it as specified in OMNIKEY Contactless Developer Guide.
The communication between the host PC and the reader is encrypted with a default publicly available 3DES key. If you look at the source in the iclassified package you can learn how to build a check that finds our what kind of system you are running (Standard or Elite) and identify how vulnerable your system is.
Offline
That is an interesting document. If I understand it correctly, there are 32 mifare keys on the reader, as well as various iclass keys, including the master key. I do have such a reader, I will play a bit with the iclassified code to understand it better.
Perhaps it would be interesting to pick out the defailt mifare keys from it, using the reader-attack. But I suppose those keys are already in the pm3 default-keys for mf.
Offline