mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 18:48:13 -07:00
legic.lua: updated to work again
Fixed/changed things: * added info that virtual tag is always MIM1024 * changed reading files to read binary files (as written by 'hf legic dump') * changed extension for writing files (*.bin and *.eml) to be on par with 'hf legic dump' * CRC was calculated wrong when data was not padded with 0 for one char hex strings * readTag (rt) can now be called multiple times without using the wrong filename * tag length was calculated wrong as segment header length field includes the header itself * bytes are XORed before writing them to a tag * default name for file contains now the tag id
This commit is contained in:
parent
a356952919
commit
43b5ee5918
2 changed files with 87 additions and 75 deletions
|
@ -91,14 +91,20 @@ CRC1 = crc8 over addr 0x00..0x03+0x07..0x0E (special 'gantner crc8')
|
|||
CRC2 = MCD + MSB0..2+ addr 0x06 + addr 0x05 + addr 0x07 + Stamp (regular Master-Token-CRC)
|
||||
--]]
|
||||
|
||||
--[[
|
||||
Known issues; needs to be fixed:
|
||||
* last byte in last segment is handled incorrectly when it is the last bytes on the card itself (MIM256: => byte 256)
|
||||
--]]
|
||||
|
||||
example = "script run legic"
|
||||
author = "Mosci"
|
||||
version = "1.0.3"
|
||||
author = "Mosci, uhei"
|
||||
version = "1.0.4"
|
||||
|
||||
desc =
|
||||
[[
|
||||
|
||||
This script helps you to read, create and modify Legic Prime Tags (MIM22, MIM256, MIM1024)
|
||||
The virtual tag (and therefore the file to be saved) is always a MIM1024 tag.
|
||||
it's kinda interactive with following commands in three categories:
|
||||
|
||||
Data I/O Segment Manipulation Token-Data
|
||||
|
@ -108,8 +114,8 @@ it's kinda interactive with following commands in three categories:
|
|||
ed => edit Segment Data tk => toggle KGH-Flag
|
||||
File I/O rs => remove Segment
|
||||
----------------- cc => check Segment-CRC
|
||||
lf => load File ck => check KGH
|
||||
sf => save File ds => dump Segments
|
||||
lf => load bin File ck => check KGH
|
||||
sf => save eml/bin File ds => dump Segments
|
||||
xf => xor to File
|
||||
|
||||
|
||||
|
@ -128,8 +134,8 @@ it's kinda interactive with following commands in three categories:
|
|||
without the need of changing anything - MCD,MSN,MCC will be read from the tag
|
||||
before and applied to the output.
|
||||
|
||||
lf: 'load file' - load a (xored) file from the local Filesystem into the 'virtual inTag'
|
||||
sf: 'save file' - saves the 'virtual inTag' to the local Filesystem (xored with Tag-MCC)
|
||||
lf: 'load file' - load a (xored) binary file (*.bin) from the local Filesystem into the 'virtual inTag'
|
||||
sf: 'save file' - saves the 'virtual inTag' to the local Filesystem as eml and bin (xored with Tag-MCC)
|
||||
xf: 'xor file' - saves the 'virtual inTag' to the local Filesystem (xored with choosen MCC - use '00' for plain values)
|
||||
|
||||
ct: 'copy tag' - copy the 'virtual Tag' to a second 'virtual TAG' - not usefull yet, but inernally needed
|
||||
|
@ -242,6 +248,16 @@ function istable(t)
|
|||
return type(t) == 'table'
|
||||
end
|
||||
|
||||
---
|
||||
-- To have two char string for a byte
|
||||
local function padString(str)
|
||||
if (#str == 1) then
|
||||
return '0'..str
|
||||
end
|
||||
|
||||
return str
|
||||
end
|
||||
|
||||
---
|
||||
-- creates a 'deep copy' of a table (a=b only references)
|
||||
function deepCopy(object)
|
||||
|
@ -387,15 +403,15 @@ end
|
|||
function bytesToTag(bytes, tag)
|
||||
if istable(tag) == false then return oops("tag is no table in: bytesToTag ("..type(tag)..")") end
|
||||
|
||||
tag.MCD =bytes[1];
|
||||
tag.MSN0=bytes[2];
|
||||
tag.MSN1=bytes[3];
|
||||
tag.MSN2=bytes[4];
|
||||
tag.MCC =bytes[5];
|
||||
tag.DCFl=bytes[6];
|
||||
tag.DCFh=bytes[7];
|
||||
tag.raw =bytes[8];
|
||||
tag.SSC =bytes[9];
|
||||
tag.MCD =padString(bytes[1]);
|
||||
tag.MSN0=padString(bytes[2]);
|
||||
tag.MSN1=padString(bytes[3]);
|
||||
tag.MSN2=padString(bytes[4]);
|
||||
tag.MCC =padString(bytes[5]);
|
||||
tag.DCFl=padString(bytes[6]);
|
||||
tag.DCFh=padString(bytes[7]);
|
||||
tag.raw =padString(bytes[8]);
|
||||
tag.SSC =padString(bytes[9]);
|
||||
tag.Type=getTokenType(tag.DCFl);
|
||||
tag.OLE=bbit("0x"..tag.DCFl,7,1)
|
||||
tag.WRP=("%d"):format(bbit("0x"..bytes[8],0,4))
|
||||
|
@ -500,42 +516,26 @@ function tagToBytes(tag)
|
|||
return bytes
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
--- PM3 I/O ---
|
||||
---
|
||||
-- read from pm3 into virtual-tag
|
||||
function readFromPM3()
|
||||
local tag, bytes, infile
|
||||
infile="legic.temp"
|
||||
-- core.console("hf legic reader")
|
||||
-- core.console("hf legic esave "..infile)
|
||||
core.console("hf legic dump o "..infile)
|
||||
tag=readFile(infile..".bin")
|
||||
return tag
|
||||
end
|
||||
|
||||
local function padString(str)
|
||||
if (#str == 1) then
|
||||
return '0'..str
|
||||
end
|
||||
|
||||
return str
|
||||
end
|
||||
|
||||
---
|
||||
-- write virtual Tag to real Tag
|
||||
function writeToTag(tag)
|
||||
local bytes
|
||||
local filename = 'MylegicClone.hex'
|
||||
local taglen = 22
|
||||
if(utils.confirm(acred.."\nplace the (empty) Tag onto the PM3\nand confirm writing to this Tag: "..acoff) == false) then
|
||||
local writeDCF = false
|
||||
if(utils.confirm(acred.."\nPlace the (empty) Tag onto the PM3\nand confirm writing to this Tag: "..acoff) == false) then
|
||||
return
|
||||
end
|
||||
if(utils.confirm(acred.."\nShould the decremental field (DCF) be written?: "..acoff) == true) then
|
||||
writeDCF = true
|
||||
end
|
||||
|
||||
-- get used bytes / tag-len
|
||||
if (istable(tag.SEG)) then
|
||||
if (istable(tag.Bck)) then
|
||||
for i=0, #tag.SEG do
|
||||
taglen = taglen + tag.SEG[i] . len + 5
|
||||
taglen = taglen + tag.SEG[i] . len
|
||||
end
|
||||
end
|
||||
local uid_old = tag.MCD..tag.MSN0..tag.MSN1..tag.MSN2
|
||||
|
@ -571,37 +571,32 @@ function writeToTag(tag)
|
|||
bytes[22] = calcMtCrc(bytes)
|
||||
end
|
||||
if (bytes) then
|
||||
print("write temp-file '"..filename.."'")
|
||||
print(accyan)
|
||||
writeFile(bytes, filename..".bin")
|
||||
print(acoff)
|
||||
bytes = xorBytes(bytes,tag.MCC)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- write data to file
|
||||
if (taglen > 0) then
|
||||
WriteBytes = input(acyellow.."enter number of bytes to write?"..acoff, taglen)
|
||||
-- load file into pm3-buffer
|
||||
if (type(filename) ~= "string") then
|
||||
filename = input(acyellow.."filename to load to pm3-buffer?"..acoff, "legic.temp")
|
||||
end
|
||||
|
||||
cmd = 'hf legic eload 2 '..filename
|
||||
core.console(cmd)
|
||||
-- write pm3-buffer to Tag
|
||||
for i=0, WriteBytes do
|
||||
if (i > 6) then
|
||||
cmd = ("hf legic write o %x d %s "):format(i, padString(bytes[i]))
|
||||
for i=1, WriteBytes do
|
||||
if (i > 7) then
|
||||
cmd = ("hf legic wrbl o %02x d %s "):format(i-1, padString(bytes[i]))
|
||||
print(acgreen..cmd..acoff)
|
||||
core.console(cmd)
|
||||
core.clearCommandBuffer()
|
||||
elseif (i == 7) then
|
||||
if (writeDCF) then
|
||||
-- write DCF in reverse order (requires 'mosci-patch')
|
||||
cmd = ('hf legic wrbl o 05 d %s%s'):format(padString(bytes[i-1]), padString(bytes[i]))
|
||||
print(acgreen..cmd..acoff)
|
||||
core.console(cmd)
|
||||
core.clearCommandBuffer()
|
||||
else
|
||||
print(acgreen.."skip byte 0x05-0x06 - DCF"..acoff)
|
||||
end
|
||||
elseif (i == 6) then
|
||||
-- write DCF in reverse order (requires 'mosci-patch')
|
||||
cmd = ('hf legic write o 05 d %s%s'):format(padString(bytes[i-1]), padString(bytes[i]))
|
||||
print(acgreen..cmd..acoff)
|
||||
core.console(cmd)
|
||||
core.clearCommandBuffer()
|
||||
elseif (i == 5) then
|
||||
print(acgreen.."skip byte 0x05 - will be written next step"..acoff)
|
||||
else
|
||||
print(acgreen.."skip byte 0x00-0x04 - unwritable area"..acoff)
|
||||
|
@ -641,12 +636,12 @@ end
|
|||
local function save_BIN(data, filename)
|
||||
local outfile
|
||||
local counter = 1
|
||||
local ext = filename:match("^.+(%..+)$") or ''
|
||||
local fn = filename
|
||||
local ext = ".bin"
|
||||
local fn = filename..ext
|
||||
|
||||
-- Make sure we don't overwrite a file
|
||||
while file_check(fn) do
|
||||
fn = filename:gsub(ext, tostring(counter)..ext)
|
||||
fn = filename..ext:gsub(ext, "-"..tostring(counter)..ext)
|
||||
counter = counter + 1
|
||||
end
|
||||
|
||||
|
@ -664,26 +659,27 @@ end
|
|||
---
|
||||
-- write bytes to file
|
||||
function writeFile(bytes, filename)
|
||||
if (filename ~= 'MylegicClone.hex') then
|
||||
if (file_check(filename)) then
|
||||
local answer = confirm("\nthe output-file "..filename.." already exists!\nthis will delete the previous content!\ncontinue?")
|
||||
local emlext = ".eml"
|
||||
if (filename ~= 'MyLegicClone') then
|
||||
if (file_check(filename..emlext)) then
|
||||
local answer = confirm("\nthe output-file "..filename..emlext.." already exists!\nthis will delete the previous content!\ncontinue?")
|
||||
if not answer then return print("user abort") end
|
||||
end
|
||||
end
|
||||
local line
|
||||
local bcnt = 0
|
||||
local fho, err = io.open(filename, "w")
|
||||
local fho, err = io.open(filename..emlext, "w")
|
||||
if err then
|
||||
return oops("OOps ... failed to open output-file ".. filename)
|
||||
return oops("OOps ... failed to open output-file ".. filename..emlext)
|
||||
end
|
||||
|
||||
bytes = xorBytes(bytes, bytes[5])
|
||||
|
||||
for i = 1, #bytes do
|
||||
if (bcnt == 0) then
|
||||
line = bytes[i]
|
||||
line = padString(bytes[i])
|
||||
elseif (bcnt <= 7) then
|
||||
line = line.." "..bytes[i]
|
||||
line = line.." "..padString(bytes[i])
|
||||
end
|
||||
if (bcnt == 7) then
|
||||
-- write line to new file
|
||||
|
@ -699,7 +695,7 @@ function writeFile(bytes, filename)
|
|||
-- save binary
|
||||
local fn_bin, fn_bin_num = save_BIN(bytes, filename)
|
||||
|
||||
print("\nwrote "..acyellow..(#bytes * 3)..acoff.." bytes to " ..acyellow..filename..acoff)
|
||||
print("\nwrote "..acyellow..(#bytes * 3)..acoff.." bytes to " ..acyellow..filename..emlext..acoff)
|
||||
|
||||
if fn_bin and fn_bin_num then
|
||||
print("\nwrote "..acyellow..fn_bin_num..acoff.." bytes to BINARY file "..acyellow..fn_bin..acoff)
|
||||
|
@ -708,6 +704,21 @@ function writeFile(bytes, filename)
|
|||
return true
|
||||
end
|
||||
|
||||
---
|
||||
-- read from pm3 into virtual-tag
|
||||
function readFromPM3()
|
||||
local tag, bytes, infile
|
||||
--infile="legic.temp"
|
||||
infile=os.tmpname()
|
||||
core.console("hf legic dump f "..infile)
|
||||
tag=readFile(infile..".bin")
|
||||
os.remove(infile)
|
||||
os.remove(infile..".bin")
|
||||
os.remove(infile..".eml")
|
||||
os.remove(infile..".json")
|
||||
return tag
|
||||
end
|
||||
|
||||
--- Map related ---
|
||||
---
|
||||
-- make tagMap
|
||||
|
@ -2265,8 +2276,8 @@ function modifyHelp()
|
|||
ed => edit Segment Data tk => toggle KGH-Flag
|
||||
File I/O rs => remove Segment
|
||||
----------------- cc => check Segment-CRC
|
||||
lf => load File ck => check KGH
|
||||
sf => save File ds => dump Segments
|
||||
lf => load bin File ck => check KGH
|
||||
sf => save eml/bin File ds => dump Segments
|
||||
xf => xor to File
|
||||
|
||||
|
||||
|
@ -2352,10 +2363,10 @@ function modifyMode()
|
|||
-- save values of mainTAG to a file (xored with MCC of mainTAG)
|
||||
["sf"] = function(x)
|
||||
if istable(inTAG) then
|
||||
outfile = input("enter filename:", "legic.temp")
|
||||
outfile = input("enter filename:", "hf-legic-"..inTAG.MCD..inTAG.MSN0..inTAG.MSN1..inTAG.MSN2)
|
||||
bytes = tagToBytes(inTAG)
|
||||
--bytes=xorBytes(bytes, inTAG.MCC)
|
||||
if bytes then
|
||||
if (bytes) then
|
||||
writeFile(bytes, outfile)
|
||||
end
|
||||
end
|
||||
|
@ -2364,7 +2375,7 @@ function modifyMode()
|
|||
-- save values of mainTAG to a file (xored with 'specific' MCC)
|
||||
["xf"] = function(x)
|
||||
if istable(inTAG) then
|
||||
outfile = input("enter filename:", "legic.temp")
|
||||
outfile = input("enter filename:", "hf-legic-"..inTAG.MCD..inTAG.MSN0..inTAG.MSN1..inTAG.MSN2)
|
||||
crc = input("enter new crc: ('00' for a plain dump)", inTAG.MCC)
|
||||
print("obfuscate with: "..crc)
|
||||
bytes=tagToBytes(inTAG)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue