FIX: added some tnp3xxx identification i formatMifare.lua

FIX: tnp3.lua is more or less finished. Needs testing.
This commit is contained in:
iceman1001 2014-11-03 21:59:31 +01:00
commit 8aa79dee20
3 changed files with 58 additions and 53 deletions

View file

@ -452,7 +452,7 @@ void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc)
void SimulateTagLowFrequency(int period, int gap, int ledcontrol) void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
{ {
int i = 0; int i = 0;
uint8_t *buff = (uint8_t *)BigBuf; uint8_t *buf = (uint8_t *)BigBuf;
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
@ -493,7 +493,7 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
//#define LOW(x) AT91C_BASE_PIOA->PIO_CODR = (x) //#define LOW(x) AT91C_BASE_PIOA->PIO_CODR = (x)
//#define HIGH(x) AT91C_BASE_PIOA->PIO_SODR = (x) //#define HIGH(x) AT91C_BASE_PIOA->PIO_SODR = (x)
if ( buff[i] > 0 ){ if ( buf[i] > 0 ){
HIGH(GPIO_SSC_DOUT); HIGH(GPIO_SSC_DOUT);
//FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz //FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
//FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); //FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU);

View file

@ -80,18 +80,20 @@ function GetCardInfo()
core.clearCommandBuffer() core.clearCommandBuffer()
if 0x18 == result.sak then --NXP MIFARE Classic 4k | Plus 4k if 0x18 == result.sak then -- NXP MIFARE Classic 4k | Plus 4k
-- IFARE Classic 4K offers 4096 bytes split into forty sectors, -- IFARE Classic 4K offers 4096 bytes split into forty sectors,
-- of which 32 are same size as in the 1K with eight more that are quadruple size sectors. -- of which 32 are same size as in the 1K with eight more that are quadruple size sectors.
numSectors = 40 numSectors = 40
elseif 0x08 == result.sak then -- NXP MIFARE CLASSIC 1k | Plus 2k elseif 0x08 == result.sak then -- NXP MIFARE CLASSIC 1k | Plus 2k
-- 1K offers 1024 bytes of data storage, split into 16 sector -- 1K offers 1024 bytes of data storage, split into 16 sector
numSectors = 16 numSectors = 16
elseif 0x09 == result.sak then -- NXP MIFARE Mini 0.3k elseif 0x09 == result.sak then -- NXP MIFARE Mini 0.3k
-- MIFARE Classic mini offers 320 bytes split into five sectors. -- MIFARE Classic mini offers 320 bytes split into five sectors.
numSectors = 5 numSectors = 5
elseif 0x10 == result.sak then-- "NXP MIFARE Plus 2k" elseif 0x10 == result.sak then -- NXP MIFARE Plus 2k
numSectors = 32 numSectors = 32
elseif 0x01 == sak then -- NXP MIFARE TNP3xxx 1K
numSectors = 16
else else
print("I don't know how many sectors there are on this type of card, defaulting to 16") print("I don't know how many sectors there are on this type of card, defaulting to 16")
end end

View file

@ -7,18 +7,23 @@ local md5 = require('md5')
example =[[ example =[[
1. script run tnp3 1. script run tnp3
2. script run tnp3 -k aabbccddeeff 2. script run tnp3 -n
3. script run tnp3 -k aabbccddeeff
4. script run tnp3 -k aabbccddeeff -n
]] ]]
author = "Iceman" author = "Iceman"
usage = "script run tnp3 -k <key>" usage = "script run tnp3 -k <key> -n"
desc =[[ desc =[[
This script will try to dump the contents of a Mifare TNP3xxx card. This script will try to dump the contents of a Mifare TNP3xxx card.
It will need a valid KeyA in order to find the other keys and decode the card. It will need a valid KeyA in order to find the other keys and decode the card.
Arguments: Arguments:
-h - this help -h : this help
-k <key> - Sector 0 Key A. -k <key> : Sector 0 Key A.
-n : Use the nested cmd to find all keys
]] ]]
-- AES konstant? LEN 0x24 36,
-- I dekompilen är det för internal static array = 0x36 54
local hashconstant = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20' local hashconstant = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
@ -63,19 +68,10 @@ function ExitMsg(msg)
print() print()
end end
local function show(data)
if DEBUG then
local formatString = ("H%d"):format(string.len(data))
local _,hexdata = bin.unpack(formatString, data)
dbg("Hexdata" , hexdata)
end
end
local function readdumpkeys(infile) local function readdumpkeys(infile)
t = infile:read("*all") t = infile:read("*all")
len = string.len(t) len = string.len(t)
local len,hex = bin.unpack(("H%d"):format(len),t) local len,hex = bin.unpack(("H%d"):format(len),t)
--print(len,hex)
return hex return hex
end end
@ -102,13 +98,15 @@ local function main(args)
local keyA local keyA
local cmd local cmd
local err local err
local useNested = false
local cmdReadBlockString = 'hf mf rdbl %d A %s' local cmdReadBlockString = 'hf mf rdbl %d A %s'
local input = "dumpkeys.bin" local input = "dumpkeys.bin"
-- Arguments for the script -- Arguments for the script
for o, a in getopt.getopt(args, 'hk:') do for o, a in getopt.getopt(args, 'hk:n') do
if o == "h" then return help() end if o == "h" then return help() end
if o == "k" then keyA = a end if o == "k" then keyA = a end
if o == "n" then useNested = true end
end end
-- validate input args. -- validate input args.
@ -119,36 +117,33 @@ local function main(args)
result, err = lib14a.read1443a(false) result, err = lib14a.read1443a(false)
if not result then if not result then
print(err) return oops(err)
return
end end
print((' Found tag : %s'):format(result.name)) print((' Found tag : %s'):format(result.name))
core.clearCommandBuffer() core.clearCommandBuffer()
if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
print('This is not a TNP3xxx tag. aborting.') return oops('This is not a TNP3xxx tag. aborting.')
return
end end
-- Show info -- Show info
print(('Using keyA : %s'):format(keyA)) print(('Using keyA : %s'):format(keyA))
print( string.rep('--',20) ) print( string.rep('--',20) )
print('Trying to find other keys. ') print('Trying to find other keys.')
--core.console( ('hf mf nested 1 0 A %s d'):format(keyA) ) if useNested then
core.console( ('hf mf nested 1 0 A %s d'):format(keyA) )
end
-- Reading found keys file -- Loading keyfile
local infile = io.open(input, "rb") local infile = io.open(input, "rb")
if infile == nil then if infile == nil then
return oops('Could not read file ', input) return oops('Could not read file ', input)
end end
local akeys = readdumpkeys(infile):sub(0,12*16) local akeys = readdumpkeys(infile):sub(0,12*16)
--print( ('KEYS: %s'):format(akeys))
print('Reading data need to dump data')
-- Read block 0 -- Read block 0
cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 0,arg2 = 0,arg3 = 0, data = keyA} cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 0,arg2 = 0,arg3 = 0, data = keyA}
err = core.SendCommand(cmd:getBytes()) err = core.SendCommand(cmd:getBytes())
@ -158,45 +153,46 @@ local function main(args)
-- Read block 1 -- Read block 1
cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 1,arg2 = 0,arg3 = 0, data = keyA} cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 1,arg2 = 0,arg3 = 0, data = keyA}
local err = core.SendCommand(cmd:getBytes()) err = core.SendCommand(cmd:getBytes())
if err then return oops(err) end if err then return oops(err) end
local block1, err = waitCmd() local block1, err = waitCmd()
if err then return oops(err) end if err then return oops(err) end
print('Dumping data') local key
local pos = 0
local blockNo
local blocks = {}
-- main loop -- main loop
print('BLOCK MD5 DECRYPTED ASCII' ) for blockNo = 8, numBlocks-1, 1 do
local b = blockNo%4
local key if b ~= 3 then
local keyPosStart = 0 pos = (math.floor( blockNo / 4 ) * 12)+1
local block key = akeys:sub(pos, pos + 12 )
for block = 0, numBlocks-1, 1 do cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = blockNo ,arg2 = 0,arg3 = 0, data = key}
local b = (block+1)%4
if b ~= 0 then
keyPosStart = (math.floor( block / 4 ) * 12)+1
key = akeys:sub(keyPosStart, keyPosStart + 12 )
--print( ('%02d %s'):format(block, key))
cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = block ,arg2 = 0,arg3 = 0, data = key}
local err = core.SendCommand(cmd:getBytes()) local err = core.SendCommand(cmd:getBytes())
if err then return oops(err) end if err then return oops(err) end
local blockdata, err = waitCmd() local blockdata, err = waitCmd()
if err then return oops(err) end if err then return oops(err) end
local base = ('%s%s%02d%s'):format(block0, block1, block, hashconstant) local base = ('%s%s%d%s'):format(block0, block1, blockNo, hashconstant)
local md5hash = md5.sumhexa(base) local md5hash = md5.sumhexa(base)
local aestest = core.aes(md5hash, blockdata) local aestest = core.aes(md5hash, blockdata)
local _,hex = bin.unpack(("H%d"):format(16),aestest) local _,hex = bin.unpack(("H%d"):format(16),aestest)
local hexascii = string.gsub(hex, '(%x%x)', -- local hexascii = string.gsub(hex, '(%x%x)',
function(value) -- function(value)
return string.char(tonumber(value, 16)) -- return string.char(tonumber(value, 16))
end -- end
) -- )
print( ('%02d :: %s :: %s :: %s :: %s'):format(block,key,md5hash,hex,hexascii) ) if string.find(blockdata, '^0+$') then
blocks[blockNo] = ('%02d :: %s :: %s'):format(blockNo,blockdata,blockdata)
else
--blocks[blockNo] = ('%02d :: %s :: %s :: %s '):format(blockNo,key,md5hash,hex)
blocks[blockNo] = ('%02d :: %s :: %s'):format(blockNo,blockdata,blockdata)
end
if core.ukbhit() then if core.ukbhit() then
print("aborted by user") print("aborted by user")
@ -204,6 +200,13 @@ local function main(args)
end end
end end
end end
-- Print results
print('BLK :: DATA DECRYPTED' )
print( string.rep('--',36) )
for _,s in pairs(blocks) do
print( s )
end
end end
main(args) main(args)