Proxmark3 developers 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.

#1 2019-10-14 13:45:25

electron
Contributor
From: Leipzig/Germany
Registered: 2019-10-11
Posts: 2

Identify data on Legic Prime

Hello Everyone!

First, I want to thank Iceman, mosci, jason, and ikarus, for all the time and work they've invested in Proxmark firmware and scripts.
I've learned so much new in the last few weeks and months.

I've got some LegicPrime-Tags used for a car park and try to understand all data stored on this tags.

After much research I know almost all bytes, CRC calculations and how they are used, but not all.
(Sources: http://sar.informatik.hu-berlin.de/rese … 11-03_.pdf, https://fahrplan.events.ccc.de/congress … slides.pdf, Mosci's Legic-Lua-Scripts and legic-threads of this forum)

Here's a Dump of a Tag:

[usb] pm3 --> hf legic info
[+] Reading full tag memory of 256 bytes...          

          
CDF: System Area           
------------------------------------------------------          
MCD: 79, MSN: 03 ee 7e, MCC: df OK           
DCF: 60000 (60 ea), Token Type = IM-S (OLE = 0)          
WRP = 15, WRC = 1, RD = 1, SSC = FF          
Remaining Header Area          
00 00 00 11 01 06 80 00 00 4C 50 00 00           
------------------------------------------------------          

ADF: User Area           
------------------------------------------------------          
Segment     | 01           
raw header  | 0x74 0xC0 0x07 0x40          
Segment len | 116,  Flag: 0xC (valid:1, last:1)          
            | WRP: 07, WRC: 04, RD: 0, CRC: 0x85 (OK )          

WRC protected area:   (I 27 | K 0| WRC 4)          

row  | data          
-----+------------------------------------------------          
[00] | 50 38 0B 00 
-----+------------------------------------------------
          
Remaining write protected area:  (I 31 | K 31 | WRC 4 | WRP 7  WRP_LEN 3)          

row  | data          
-----+------------------------------------------------          
[00] | 03 B3 22 
-----+------------------------------------------------
          
Remaining segment payload:  (I 34 | K 34 | Remain LEN 104)          

row  | data          
-----+------------------------------------------------          
[00] | FF 92 00 00 03 B3 22 00 00 00 00 00 00 00 00 00 
[01] | 00 00 00 FF FF FF FF FF FF FF 57 02 85 26 FC 01 
[02] | 01 00 00 64 00 00 00 00 00 85 26 3C 04 F4 01 00 
[03] | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
[04] | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
[05] | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
[06] | FF FF FF FF FF FF FF FF 
-----+------------------------------------------------

...and Raw-Data, I like more smile

ADR  |0x0|0x1|0x2|0x3|0x4|0x5|0x6|0x7|0x8|0x9|0xA|0xB|0xC|0xD|0xE|0xF
-----+---------------------------------------------------------------
0x00 | 79  03  EE  7E  DF  60  EA  9F  FF  00  00  00  11  01  06  80
0x10 | 00  00  4C  50  00  00  74  C0  07  40  85  50  38  0B  00  03
0x20 | B3  22  FF  92  00  00  03  B3  22  00  00  00  00  00  00  00
0x30 | 00  00  00  00  00  FF  FF  FF  FF  FF  FF  FF  57  02  85  26
0x40 | FC  01  01  00  00  64  00  00  00  00  00  85  26  3C  04  F4
0x50 | 01  00  FF  FF  FF  FF  FF  FF  FF  FF  FF  FF  FF  FF  FF  FF
0x60 | ...

What I know atm:

UID:
  MCD:    Byte 0x00        => 79
  MSN:    Byte 0x01..0x03      => 03 EE 7E
  UID-CRC: Byte 0x04 = CRC8 over Byte 0x00..0x03  => DF

DecrementalField DCF:
  OLE (Organization Level Enabled-Flag): DCF-Lo-Byte 0x05 Bit 7 => binary 0
  TokenType: DCF-Lo-Byte 0x05 Bits 0..6  => binary 1000000 = 0x60
    (0x00-0x2f = IAM, 0x30-0x6f = SAM, 0x70-0x7f = GAM)
  Organization Level: DCF-Hi-Byte = Byte 0x06  => EA
  0xEA 0x60 => so it's a SAM-Token

Byte 0x07:
  "FlagByte":
    WRP (WriteProtection): Bit 0..3    => binary 1111 = decimal 15 = 0xF
    WRC (WriteControll): Bit 4..6     => binary 001  = decimal 1  = 0x1
    RD (Read Disabled): Bit 7      => binary 0    = decimal 1  = 0x1

Bytes 0x08..0x0C are unkown, but important???

Bytes 0x0D..0x13:
  Segment-Header-Backup:
    According to http://sar.informatik.hu-berlin.de/rese … 11-03_.pdf i was able to identify how to calculate the CRC on Byte 0x13. The CRC-Calculation must be done with DIRT-Flag-Set:
    So CRC-Calcutlation is done over:
    [MCD][MSN0][MSN1][MSN2][MSN3] + Byte 0x0D but BIT7 (=DIRT-Bit) MUST SET FOR CALCULATION = 8, BIT 0-6 is Seg-Nr  (max Seg = 127) + Bytes 0x0E..0x12

			[offline] pm3 --> hf legic crc d 7903ee7e81068000004c
			[+] Legic crc8: 50  <=== Byte 0x13

Bytes 0x14..0x15:
  Timestamp (Week/Year) for Token but not used on SAM-Tokens


Bytes 0x16..0x1A:
  Segment Header with CRC:
  CRC calculated over [MCD][MSN0][MSN1][MSN2][MSN3]+0x16..0x19

		[offline] pm3 --> hf legic crc d 7903ee7e74c00740
		[+] Legic crc8: 85  <=== Byte 0x1A

  Segment Header contains following informations:
    Segment-length (including Header):
      Byte 0x16 = Lower Byte of SegLength => 0x74
      Byte 0x17 Bits 0..3 = High Nibble of SegLenght => 0x0
      so SegmentLeght = 0x074 = 116 Byte
    Valid-Flag (if not set, segment has been deleted):
      Byte 0x17 Bit 6 => 1
    Last-Segment-Flag (if bit is set, no more segments are following):
      Byte 0x17 Bit 7 => 1   
    WRP (WriteProtection, amount of bytes of WriteProtected Area???):
      Byte 0x18 => 0x07
    WRC (WriteControl, amount of Bytes of WriteControlled Area???):
      Byte 0x19 Bits 4..6 => Byte 0x19 => 0x40 = binary 010000000 so WRC = 100 = 4
    RD (ReadDisabled):
      Byte 0x19 Bit 7 => 0

So far, all these bytes are known and have been discussed several times in the forum.
Now the fun-stuff:

Bytes 0x1B..0x1E:
  WRC-controled area = Stamp

Bytes 0x1F..0x21:
  Remaining Bytes of WRP-protected area.
  I figured out that byte 0x21 is the LowerByte and 0x20 is HigherByte of cardnumber printend on this tag.
  0x22B3 = decimal 8883 
  Printed Number on Tag: 8883 
  Byte 0x1F may could also belong to this cardnumber...

  I'm sure that these bytes contain the card number, since on another card the bytes contains exactly the printed number.

So i think it isn't a default Kaba-Header, cause there's no more space left in WRP-Area for the khCRC.


And now the really interesting stuff, the payload:

Byte 0x22    0xFF on all tags
Byte 0x23    different on other tags, maybe a CRC, but i can't figure out which bytes are included in calculation
Bytes 0x24..0x25  0x00 on all Ttags
Bytes 0x26..0x28  are the same value as bytes 0x1F..0x21 on every tag. It's the card number again.
Bytes 0x29..0x34  0x00 on all tags
Bytes 0x35..0x3B  0xFF on all tags

All Bytes before 0x3A are never changed when tag was used.

Byte 0x3C    unknown, changed every time the tag is used randomly(?)
Byte 0x3D    unknown, but i think it's the number/type of reader, last used to change data on tag. If I used the Cash-Upload-Terminal, this Byte is set to 0x03, if I entered the car park, it was set to 0x01 and when i've leaved, it was set to 0x02.
Byte 0x3E    unknown, but it's icremented every day. On 2019-10-04 it was 0x7e, on 2019-10-09 => 0x83, 2019-10-10 => 0x84, 2019-10-11 => 0x85
Byte 0x3F    unknown, maybe it belongs to byte 0x3F and is a part of the "timestamp"

I think these are the number of days since 1992-10-11. It's calculated by byte 0x3F as hiByte and 0x3E as lobyte. (Why the 1992-10-11? Legic introduced the Legic Prime Standard in 1992)

Bytes 0x40..0x41  Minutes of Day, HiByte = 0x41, LoByte = 0x40 => 0x01FC = 508/60 = 8.46 => 0.46*60 ~ 27.99 => entering car park at 08:28 , maybe this Bytes are part of the "timestamp"
Byte 0x42      unknown, think it would set if the tag is used the first time entring the car park, because it's 0x00 after initial money-upload and set to 0x01 after first time the car park was entered
Byte 0x43      is set to 0x08 after entering the parking lot, after leaving it is 0x00
Byte 0x44      unkown , maybe it's the HiByte of cash?
Bytes 0x45..0x46  Balance of the cash, HiByte = 0x45 , LoByte = 0x44 => 0x0064 = 100 = 1.00€
Bytes 0x47..0x4A  0x00 on all tags
Bytes 0x4B..0x51  0x00 after initial cash-upload and after entring the car park, so there is NO CRC to check the cash-balance. Beat me if I am wrong, but a checksum must always be behind the values to be tested, right???
          After leaving car park bytes are set to:
          Bytes 0x4B..0x4C:  same structure like bytes 0x3E..0x3F, days since 1992-10-11
          Bytes 0x4D..0x4E:   Minutes of day, same like Bytes 0x40..0x41, but for leaving car park => 0x043c = 1084/60 = 18.0667 => 0.0667*60 ~ 4 => leaving car park at 18:04
          Byte 0x4F:  unknown, 0xF4 on all tags
          Byte 0x50:  unknown, 0x01 on all tags
          Byte 0x51:  0x00 on all tags
         
...and that's it...

Some Questions about this Tags:
- They do not contain a typical Kaba header, or am I wrong?
- Are these tags a kind of Legic Cash? I do not think so. I suspect it is more of a proprietary development of the provider.
- I have absolutely no idea what byte 0x3C might mean, maybe bytes 0x3C and 0x3D belong together?

Thomas

Offline

#2 2019-10-14 15:58:25

iceman
Administrator
Registered: 2013-04-25
Posts: 5,845
Website

Re: Identify data on Legic Prime

Nice research. 
The user segments on a Legic is multiple and most implementations uses their own. Some was documented in the awesome legic.lua script.


If you feel the love,  https://www.patreon.com/iceman1001

modhex(hkhehghthbhudcfcdchkigiehgduiehg)

Offline

Board footer

Powered by FluxBB