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.
Pages: 1
I am investigating epassport raw commands but I am not able to send them with ISO14443A raw command feature;
The select command:
00 A4 04 0C 07 A0 00 00 02 47 10 01
should give a 90 00 answer but sending it I am receiving no answer.
Sending a select command the answer is a random UID (the UID remain fixed if you select the option to not to turn off field after sending acommand, this is quite obvious).
Can someone please tell me the correct command sequence to obtain an answer from my epassport ?
If useful this is the answer to the pm3 already implemented epa command:
proxmark3> hf epa cnonces 10 16 0
Collecting 16 10-byte nonces
Start: 1397463446
Error in step 2, Return code: 0
Error in step 2, Return code: 0
Error in step 2, Return code: 0
Error in step 2, Return code: 0
Error in step 2, Return code: 0
Error in step 2, Return code: 0
Error in step 2, Return code: 0
Error in step 2, Return code: 0
Error in step 2, Return code: 0
Error in step 2, Return code: 0
Error in step 2, Return code: 0
Error in step 2, Return code: 0
Error in step 2, Return code: 0
Error in step 2, Return code: 0
Error in step 2, Return code: 0
Error in step 2, Return code: 0
End: 1397463448
Offline
I think I found a way to correctly communicate with those devices. Who is interested can reply to this post, it should be easy to add reading of an ePassport in the client (if you want to decode the image contained you will need a jp2 decoder).
Offline
Ok I found the problem; 14a raw command seems to have a bug: if I try to send more than 12 bytes the tag doesn't answer so I mean that from byte 13 (starting from 1) and on bytes are someway "lost": can someone have a look at the code ? I found in the code that there seems to be a limit in received bytes (only 16) but nothing about sent bytes. The patch was added in r784.
If we can overcome those limits ePassport support will be really easy to add.
Last edited by asper (2014-04-16 09:23:57)
Offline
I can take a look. What is the exact command you are using?
Offline
I sent you an email.
Offline
There's no problem on the PC-side, I'll take a look on the ARM-side within the next few days..
Offline
Thank you man!
Offline
I think I fixed it. https://github.com/Proxmark/proxmark3/c … 7e38334f57. It's in my iclass-fixes branch (yeah, I was clumsy/lazy), could you verify that the fix works? You'd have to switch to that branch and check out the code. If you verify, I'll push it into master instead.
Offline
OR, just patch it manually (just noticed that my iclass branch does not compile) armsrc/iso14443a.c:
if(param & ISO14A_RAW) {
if(param & ISO14A_APPEND_CRC) {
AppendCrc14443a(cmd,len);
len += 2;
lenbits += 16; ; <-- THIS IS THE FIX
}
if(lenbits>0) {
ReaderTransmitBitsPar(cmd,lenbits,GetParity(cmd,lenbits/8), NULL);
} else {
ReaderTransmit(cmd,len, NULL);
}
arg0 = ReaderReceive(buf);
cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf));
}
Offline
No, it still doesn't work, but it is getting better !
The command is something like 0200a4040007d27600008501010035c0 (this example has the same bytes number (16) i need to send including 35c0 that is the CRC); I receive 6700 (that means wrong lenght) until byte "35", If I add the last byte (c0 in the example) the tag doesn't answer at all and I must start the select+ats sequence from the beginning otherwise the tag won't answer anymore. I think that the last byte is not sent at all; so before actual "fix" the limit was 12 bytes, now, after the "fix" we have a 15 bytes limit.
Presuming that we will put this stuff in a working state, are you able to determine how many bytes pm3 is able to handle as answers ? I mean how many bytes can the pm3 handle in his memory buffer ? Because some answers can be quite long (more than 32 bytes).
Last edited by asper (2014-04-27 18:18:55)
Offline
Its a matter of the code, fpga aswell as arm has more then enough space to buffer incoming data. Arm more than 40kb fpga probably more then 4kb.
Offline
Well, regarding sending, I traced the data all the way to the sendbuffer:
proxmark3> hf 14a raw -p -a 0200a4040c07a000000247100198b8deadbeefdeadbeef
[...]
#db# ReaderIso14443a (23 len)
#db# CodeIso14443aBitsAsReaderPar (cmd, 184 bits, dwParity)
#db# Number of bits in alles : 210
received 0 octets
So, 23 bytes was encoded into 184 bits, then 210 bits with modulation. This wound up in the ToSend buffer. As far as I can see, all data is sent out.. I'm not good when it comes to fpga-business, it's not my domain...
Offline
Thank you holiman, for now I will suspend my work on this until further "bug-hunting".
Offline
Actualy, I think my fix was bad. Should be this,
if(lenbits > 0 ) lenbits += 16;
Not that it will make a difference for you, but will otherwise cause errors in other scenarios.
Offline
the code for RAW in client side not use the param ISO14A_APPEND_CRC because I prefer calculate the CRC in client side and send it as simple bytes.
OT
Proxmark3 is not client less so I think is better move the not low level code as CRC calculation in client side. Is just my opinion.
you can see it in client/cmdhf14a.c
if(crc && datalen>0)
{
uint8_t first, second;
ComputeCrc14443(CRC_14443_A, data, datalen, &first, &second);
data[datalen++] = first;
data[datalen++] = second;
}
EDIT
Also the param -a or -s is important send it only on first command, because in arm side the function iso14443a_setup is executed everytime you send -a or -s
So the first time
hf 14a raw -p -a -c XXXXXX
the second command
hf 14a raw -p -c XXXXXX
the third command
hf 14a raw -p -c XXXXXX
the last command we can remove -p power off the field.
hf 14a raw -c XXXXXX
Last edited by jonor (2014-04-28 09:28:53)
Offline
I tried tag emulation with libnfc and my SCL3711-NFC&RW
this is the result with nfc-emulate-uid
PM3 => hf 14a raw -p -s -c 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e
[+] Received initiator command: e0 (2 bits)
[+] Configuring communication
[+] Done, the emulated tag is initialized with UID: DEADBEEF
R: 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 5e 05
---------------------------------
PM3 => hf 14a raw -p -a -c 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e
R: 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 5e 05
---------------------------------
PM3 => hf 14a raw -p 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e
R: 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e
---------------------------------
After inititor nfc-emulate-uid print also byte of activation
PM3 => hf 14a raw -p -s 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e
R: 52 (7 bits)
T: 04 00
R: 93 20
T: de ad be ef 22
R: 93 70 de ad be ef 22 b9 9c
T: 08 b6 dd
R: 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e
---------------------------------
PM3 => hf 14a raw -p -c 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e
R: 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 5e 05
Send buffer is not limited to 16 byte, maybe the problem is time based, the card after select if not receive data after an unknow time return in unselect state.
Maybe a script lua or a new function in client/arm can remove the doubt.
Offline
Actualy, I think my fix was bad. Should be this,
if(lenbits > 0 ) lenbits += 16;
Not that it will make a difference for you, but will otherwise cause errors in other scenarios.
Sorry holiman, I don't understand; should I try to flash your new fix or not ?
@jonr: i am perfectly aware of the raw parameters because you explained them perfectly !
Well you can be right man ! (about "timing"); I can send you original (working) sniffed traces so we can find a way out ! The strange thing is that the card answer if I send 15 bytes now (before the fix only 12 were accepted).
EDIT:
Script must send with timings:
26 (7 bits)
93 20 (read the 9320 5 bytes answer and use them in the following 9370 command adding 2 crc bytes at the end)
93 70 08 b5 f5 46 0e 36 c2
e0 80 31 73 (ATS)
02 00 a4 04 00 07 d2 76 00 00 85 01 01 00 35 c0 (this is the non-working command)
This is the sniffed trace (with timing):
Start | End | Src | Data
-----------|-----------|-----|--------
0 | 1056 | Rdr | 26
2228 | 4596 | Tag | 08 00
11984 | 14448 | Rdr | 93 20
15636 | 21524 | Tag | 08 b5 f5 46 0e
25312 | 35840 | Rdr | 93 70 08 b5 f5 46 0e 36 c2
37012 | 40596 | Tag | 20 fc 70
514432 | 519200 | Rdr | e0 80 31 73
523956 | 532084 | Tag | 05 78 33 d1 02 a4 95
657744 | 676272 | Rdr | 02 00 a4 04 00 07 d2 76 00 00 85 01 01 00 35 c0
842436 | 848324 | Tag | 02 6a 82 93 2f
I need to get the 02 6a 82 93 2f error code. Now I am receiving nothing.
Holiman can you provide a simple script to test with ?
Last edited by asper (2014-04-28 17:52:30)
Offline
I tried a little patch to nfc-emulate-uid so the default behaviour is send data
and I can send and receive data from emulated tag
PM3 => hf 14a raw -p -a -c 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19
R: 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 aa 4f
T: 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23
PM3 <= 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23
Script removed because was TOO BAD
Last edited by jonor (2014-04-28 19:35:10)
Offline
The results:
proxmark3> script run epa.lua
--- Executing: ./scripts/epa.lua, args''
This is a script to allow raw 1444a commands to be sent and received.
Arguments:
-o do not connect - use this only if you previously used -p to stay connected
-r do not read response
-c calculate and append CRC
-p stay connected - dont inactivate the field
-x <payload> Data to send (NO SPACES!)
-d Debug flag
Examples :
# 1. Connect and don't disconnect
script run 14araw -p
# 2. Send mf auth, read response (nonce)
script run 14araw -o -x 6000F57b -p
# 3. disconnect
script run 14araw -o
# All three steps in one go:
script run 14araw -x 6000F57b
Example usage
script run 14araw -x 6000F57b
-----Finished
proxmark3>
Last edited by asper (2014-04-28 18:24:22)
Offline
sorry I forgot to tell you to add --test as parameter
proxmark3> script run epa.lua --test
Offline
proxmark3> script run epa.lua --test
--- Executing: ./scripts/epa.lua, args'--test'
### EPA test
This is a script to allow raw 1444a commands to be sent and received.
Arguments:
-o do not connect - use this only if you previously used -p to stay connected
-r do not read response
-c calculate and append CRC
-p stay connected - dont inactivate the field
-x <payload> Data to send (NO SPACES!)
-d Debug flag
Examples :
# 1. Connect and don't disconnect
script run 14araw -p
# 2. Send mf auth, read response (nonce)
script run 14araw -o -x 6000F57b -p
# 3. disconnect
script run 14araw -o
# All three steps in one go:
script run 14araw -x 6000F57b
Example usage
script run 14araw -x 6000F57b
### doconnect
Connected to card, uid = 08FE42C9
### doconnect
ERROR: iso14443a card select failed
### Tests done
-----Finished
proxmark3>
Last edited by asper (2014-04-28 18:44:04)
Offline
This is a new version of lua script. (Sorry I'm very newbie with lua)
These are the actions of scripts:
connect
do the select TAG
send your bytes
disconnect
run it without args
local cmds = require('commands')
local lib14a = require('read14a')
desc =
[[
Just a test
]]
--[[
This script communicates with
/armsrc/iso14443a.c, specifically ReaderIso14443a() at around line 1779 and onwards.
Check there for details about data format and how commands are interpreted on the
device-side.
]]
-- Some globals
local DEBUG = false -- the debug flag
-------------------------------
-- Some utilities
-------------------------------
---
-- A debug printout-function
function dbg(args)
if DEBUG then
print("###", args)
end
end
---
-- This is only meant to be used when errors occur
function oops(err)
print("ERROR: ",err)
end
---
-- Usage help
function help()
print(desc)
print("Example usage")
print(example)
end
function read14443a(dont_disconnect)
local command, result, info, err, data
command = Command:new{cmd = cmds.CMD_READER_ISO_14443a, arg1 = lib14a.ISO14A_COMMAND.ISO14A_CONNECT}
-- no disconnect and no select
command.arg1 = command.arg1 + lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + 0x80
local result,err = lib14a.sendToDevice(command)
end
--- Picks out and displays the data read from a tag
-- Specifically, takes a usb packet, converts to a Command
-- (as in commands.lua), takes the data-array and
-- reads the number of bytes specified in arg1 (arg0 in c-struct)
-- and displays the data
-- @param usbpacket the data received from the device
function showdata(usbpacket)
local cmd_response = Command.parse(usbpacket)
local len = tonumber(cmd_response.arg1) *2
--print("data length:",len)
local data = string.sub(tostring(cmd_response.data), 0, len);
print("<< ",data)
--print("----------------")
return cmd_response
end
local function isempty(s)
return s == nil or s == ''
end
function sendRaw(rawdata, options)
print(">> ", rawdata)
local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + lib14a.ISO14A_COMMAND.ISO14A_RAW
local command = Command:new{cmd = cmds.CMD_READER_ISO_14443a,
arg1 = flags, -- Send raw
-- arg2 contains the length, which is half the length
-- of the ASCII-string rawdata
arg2 = string.len(rawdata)/2,
data = rawdata}
if not isempty(options.bits) then
command.arg3 = options.bits
end
if not isempty(options.crc) then
command.arg1 = command.arg1 + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC
end
return lib14a.sendToDevice(command, options.ignore_response)
end
-- Sends an instruction to do nothing, only disconnect
function disconnect()
local command = Command:new{cmd = cmds.CMD_READER_ISO_14443a,
arg1 = 0, -- Nothing
}
-- We can ignore the response here, no ACK is returned for this command
-- Check /armsrc/iso14443a.c, ReaderIso14443a() for details
return lib14a.sendToDevice(command,true)
end
-- connect and select byte
read14443a(true)
res,err = sendRaw("26",{ignore_response = false, bits = 7})
if err then return oops(err) end
showdata(res)
res,err = sendRaw("9320",{ignore_response = false})
if err then return oops(err) end
local cmd_response = showdata(res)
res,err = sendRaw("9370"..string.sub(tostring(cmd_response.data),0,10),{ignore_response = false, crc = true})
if err then return oops(err) end
showdata(res)
res,err = sendRaw("e0803173",{ignore_response = false})
if err then return oops(err) end
showdata(res)
res,err = sendRaw("0200a4040007d27600008501010035c0",{ignore_response = false})
if err then return oops(err) end
showdata(res)
disconnect()
Last edited by jonor (2014-04-28 21:06:01)
Offline
Answer:
proxmark3> script run epa.lua
--- Executing: ./scripts/epa.lua, args''
>> 26
<< 0800
>> 9320
<< 08464A3D39
>> 937008464A3D39
<<
>> e0803173
<<
>> 0200a4040007d27600008501010035c0
<<
-----Finished
proxmark3>
proxmark3> hf 14a list
Recorded Activity
Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer
All times are in carrier periods (1/13.56Mhz)
Start | End | Src | Data
-----------|-----------|-----|--------
0 | 1056 | Rdr | 26
2228 | 4596 | Tag | 08 00
542464 | 544928 | Rdr | 93 20
546116 | 551940 | Tag | 08 46 4a 3d 39
1084928 | 1087392 | Rdr | 93 70
1763072 | 1767840 | Rdr | e0 80 31 73
2442624 | 2461152 | Rdr | 02 00 a4 04 00 07 d2 76 00 00 85 01 01 00 35 c0
proxmark3>
Offline
The reader does not send out the select correct (93 70 .. ).
I think the problem *might* be this:
res,err = sendRaw("9370"..string.sub(tostring(cmd_response.data),0,10),{ignore_response = false, crc = true})
The data in cmd_response is (probably) the raw data. However, the sendRaw, for simplicity, takes ascii hex as input. So there are two ways to fix this :
1. Use binlib to change the read data into ascii format
2. Modify sendraw, or make an alternate, where you insert the raw data into cmd.data after the ascii->data conversion has been performed. This happens inside the constructor of the Command, iirc commands.lua.
I think the first one is simplest. It should be something like
bin = require('bin')
..
local pos, asciidata = bin.unpack('H5', cmd_response.data)
I'm not 100% on 'H5', but that means unpack 5 ascii-hex digits from data. The first return variable (pos) tells where we are now; i.e, the position of the first unparsed data, which should be 4.
Check out http://nmap.org/nsedoc/lib/bin.html for details on how the bin library works.
EDIT: Changed 4 to 5
EDIT2 : changed cmd.data to cmd_response.data
Last edited by holiman (2014-04-30 08:47:09)
Offline
So, after that, you'd do
res,err = sendRaw("9370"..asciidata,{ crc = true})
I don't think ignore_response is needed, it'll be false unless explicitly set to true.
Offline
Using 2 pm3s me and jonor (mainly jonor!) managed to find out the problem: response waiting time.
By default it is 10msec; for simple tag answers (ex. error answers) this value is enough but for more "computing-consuming-power" commands this is too fast.
Offline
I've had the same issue - solved it by increasing the iso14a_timeout variable in the arm code.
it's a bit of a kludge for now.
iso14443a.c:
void iso14443a_setup(uint8_t fpga_minor_mode) {
<stuff>
//increase for more time
iso14a_set_timeout(10000); // increased from 1050 to 10000
}
Offline
Pages: 1