This is the major changes made to the HITAG2 commands. Its heavly based on RFIDLers implementation and its been converted to work with Proxmark3. Special thanks to @kevsecurity for his amazing implementations of the Gone in 360 Seconds paper by Roel, Flavio & Balasch. Thanks to @adamlaurie for his RFIDler project. It wouldnt been doable without it.

This commit is contained in:
iceman1001 2024-04-22 16:20:24 +02:00
commit c8849af5e0
20 changed files with 2703 additions and 708 deletions

View file

@ -67,9 +67,9 @@ def hitag2_init(key, uid, nonce):
#print '%012x' % state
#print '%012x' % (int("{0:048b}".format(state)[::-1],2))
for i in range(0, 32):
nonce_bit = (f20(state) ^ ((nonce >> (31-i)) & 1))
nonce_bit = (f20(state) ^ ((nonce >> (31 - i)) & 1))
#print nonce_bit
state = (state >> 1) | (((nonce_bit ^ (key >> (31-i))) & 1) << 47)
state = (state >> 1) | (((nonce_bit ^ (key >> (31 - i))) & 1) << 47)
#print '%012x' % state
#print '%012x' % (int("{0:048b}".format(state)[::-1],2))
return state
@ -81,6 +81,7 @@ def lfsr_feedback(state):
^ (state >> 26) ^ (state >> 30) ^ (state >> 41)
^ (state >> 42) ^ (state >> 43) ^ (state >> 46)
^ (state >> 47)) & 1)
def lfsr(state):
return (state >> 1) + (lfsr_feedback(state) << 47)
@ -93,15 +94,17 @@ def lfsr_feedback_inv(state):
^ (state >> 46)) & 1)
def lfsr_inv(state):
return ((state << 1) + (lfsr_feedback_inv(state))) & ((1<<48)-1)
return ((state << 1) + (lfsr_feedback_inv(state))) & ((1 << 48) - 1)
def hitag2(state, length=48):
c = 0
for i in range(0, length):
c = (c << 1) | f20(state)
#print '%012x' % state
#print '%012x' % (int("{0:048b}".format(state)[::-1],2))
#print ('%012x' % state)
state = lfsr(state)
#print ('%012x' % (int("{0:048b}".format(state)[::-1],2)))
#print('%08X %08X' % (c, state))
#print('final: %08X %08X' % (c, state))
return c
if __name__ == "__main__":
@ -111,8 +114,15 @@ if __name__ == "__main__":
uid = int(sys.argv[2], 16)
n = int(sys.argv[3])
for i in range(n):
nonce = random.randrange(2**32)
state = hitag2_init(key, uid, nonce)
print('%08X %08X' % (nonce, hitag2(state, 32)^0xffffffff))
nonceA = random.randrange(2**32)
stateA = hitag2_init(key, uid, nonceA)
csA = hitag2(stateA, 32) ^ 0xffffffff
# print('%08X %08X' % (nonceA, csA))
nonceB = random.randrange(2**32)
stateB = hitag2_init(key, uid, nonceB)
csB = hitag2(stateB, 32) ^ 0xffffffff
print('./ht2crack5opencl %08X %08X %08X %08X %08X' % (uid, nonceA, csA, nonceB, csB))
print('lf hitag lookup --uid %08X --nr %08X --ar %08X --key %012X' % (uid, nonceA, csA, key))
else:
print("Usage: python %s <key> <uid> <nr of nRaR to generate>" % sys.argv[0])

View file

@ -414,6 +414,7 @@ while true; do
if ! CheckExecute "nfc decode test - signature" "$CLIENTBIN -c 'nfc decode -d 03FF010194113870696C65742E65653A656B616172743A3266195F26063132303832325904202020205F28033233335F2701316E1B5A13333038363439303039303030323636343030355304EBF2CE704103000000AC536967010200803A2448FCA7D354A654A81BD021150D1A152D1DF4D7A55D2B771F12F094EAB6E5E10F2617A2F8DAD4FD38AFF8EA39B71C19BD42618CDA86EE7E144636C8E0E7CFC4096E19C3680E09C78A0CDBC05DA2D698E551D5D709717655E56FE3676880B897D2C70DF5F06ECE07C71435255144F8EE41AF110E7B180DA0E6C22FB8FDEF61800025687474703A2F2F70696C65742E65652F6372742F33303836343930302D303030312E637274FE'" "30864900-0001.crt"; then break; fi
echo -e "\n${C_BLUE}Testing LF:${C_NC}"
if ! CheckExecute "lf hitag2 test" "$CLIENTBIN -c 'lf hitag selftest'" "Tests \( ok"; then break; fi
if ! CheckExecute "lf cotag demod test" "$CLIENTBIN -c 'data load -f traces/lf_cotag_220_8331.pm3; data norm; data cthreshold -u 50 -d -20; data envelope; data raw --ar -c 272; lf cotag demod'" \
"COTAG Found: FC 220, CN: 8331 Raw: FFB841170363FFFE00001E7F00000000"; then break; fi
if ! CheckExecute "lf AWID test" "$CLIENTBIN -c 'data load -f traces/lf_AWID-15-259.pm3;lf search -1'" "AWID ID found"; then break; fi