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 pretty new to proxmark and rfid, and have a combined question / request.
1. Is it possible to, somehow, issue something like "hf scan", and let the reader check all possible cards to determine what type it is? Or even better, set it to 'scan mode' and it will keep doing this and reporting about each unique card that comes into contact? I would like to be able to go from zero knowledge, swipe some tags and know my options about what to do next with the tag.
2. If this is currently not implemented, does anyone think it would be a valuable addition? I wouldn't mind taking a stab at implementing it.
Also, if anyone has any pointers about what would be a reasonable scan order, that would be valuable input.
Offline
Me and gaucho are working on a macro for our PM3 Client GUI (only for Windows) that will be able to do exactly what you are asking for: put the tag, press the button and the program will tell you what kind of tag you have in the field ! We are having problems using the reader funciton for ISO14443B; if someone is able to correct the soruce code and make that function available again (makes PM3 act as an ISO14443B reader) we will implement it soon in our software (also the ISO14443B sniff function is still unfortunately not working); for now we have the code to correctly identify lot of ISO14443B and ISO15693 in our RFID identifier software (only for SL500F hardware and Windows OS), soon we will add ISO14443A (just a question of days), so it will be easy to add this function as a macro for the PM3 Client GUI !
Last edited by asper (2013-05-13 11:17:11)
Offline
Just as a side info: The TWN4 implements such a function. Within less then a second it scans all known tags (LF and HF) and displays tag type and tag UID.
This shows, it can be done. Would be a very nice function. Probably not very easy to do, I guess, though.
It would also double as a nice kind of a database, too, with all supported tag types of Proxmark :-)
Offline
@asper :
What parts of that makes it windows-only? Is is the fact that you're scripting commands into the pm3 client? That should be pretty simple to port into the client instead. However, I'm more interested in putting this functionality in the reader. That would enable a pretty cool feature, the ability to put it in standalone sniffing-mode. That would enable some really stealth operations. What I would want is something like this:
* recon-mode (sniffs and logs (or transmits to client)) all info it can gather easily: card type, uid etc.
* agressive-mode, same as above but also cracks and dumps cards if it can and has the time to do so
@Neuer_user
What parts would be "not very easy"? I'm pretty new to rfid and probably does not have a very good grasp of the problem. As I (naively?) imagine it, wouldn't it just be to start interacting in each possible mode, check if we get something - if not, move to the next? Just replace the guy behind the keyboard with some on-device logic?
Last edited by holiman (2013-05-13 19:22:06)
Offline
recon-mode will be easy to do if ISO14443B-act-as-a-reader command will work properly because PM3 already has commands to retrieve useful bytes for correct identification; without ISO14443B-act-as-a-reader only ISO14443A and ISO15693 will be supported by our (evetually) future PM3 macro command.
PM3 already decode correctly most of the ISO14443A with the ISO14443A-act-as-a-reader command but has a limited database in ISO15693 identification.
So if you are able to provide a fix for the ISO14443B-act-as-a-reader command this can be done in few days/weeks.
aggressive-mode is something that will probably waste coding time because "cracking" features in PM3 are very few and the most used (mifare) can be a long procedure that, in my opinion, won't need an automatic process.
Windows-only is our rfid identification software. "Scripting" will use PM3 commands and read/decode output data automatically so I don't think there is the necessity to implement a new function in the PM3 firmware, I will prefere bug-fixes for now-broken features instead of those kind of things.
Last edited by asper (2013-05-13 20:42:27)
Offline
What parts would be "not very easy"? I'm pretty new to rfid and probably does not have a very good grasp of the problem. As I (naively?) imagine it, wouldn't it just be to start interacting in each possible mode, check if we get something - if not, move to the next? Just replace the guy behind the keyboard with some on-device logic?
Well, I can only say that I tried to read and understand the code, but I for one did not succeed. That's probably due to several reasons:
* My c programming skills have been neglected over the last years (true!)
* I don't know much about the deeper working of RFID technology
* Quite a lot of programmers have worked on the code, independently. Every code for every tag looks very specific for this tag. It seems to me there are no generic commands like "detect ASK on 125kHz", etc.
My feeling is, that this might need some starting and redesigning at very low levels in the code. That's why my thought was, that it might not be very easy.
But I may be wrong here. See the first two points :-)
Offline
Well, I think that ISO1443B "act as a reader" command is working, probably it doesn't work with ST Microelectronics chips that seems not to support the standard request command; I am looking for some standard-complient tags, if they works we will add auto-identification function really soon !
@holiman: holiman are you able to write a piece of code for PM3 to send raw data to ISO14443A (es. mifare) ? Lot of people are requesting that feature in order to directly communicate with ISO14443A cards; this should not be difficult because all of the needed functions are already there, we only need a command that works like that:
hf mf raw data-bytes-to-send CRC-on-or-off
data-bytes-to-send = byte/bytes to send to the tag/card according to tag/card specifications (users need to know them)
CRC-on-or-off = ability to disable automatic calculation and appendig of CRC
and then read card answer
the option to disable the automatic calculation of crc is important because some mifare commands do not want CRC !
Please answer as soon as you can if you are able to add such a feature.
Last edited by asper (2013-05-19 08:40:37)
Offline
Interesting points, it's pretty close to something I've been contemplating and already started on. When you guys were talking about scripting *outside* of PM3, I thought that it would be cooler if you could do scripting inside PM3. I have done some programming on the Nmap project, specifically NSE (nmap scripting engine) - where Lua (www.lua.org) have been embedded. So my thought was to embed Lua, and be able to run scripts from within PM3.
The lua interface would, to begin with, have access to all already defined commands. For example, something like this could be used to crack and dump a mifare card in one go:
local hf = require("hf")
local error, result = hf.mf.mifare()
if not error then
local nt,key = unpack(result)
local error, foo, bar = hf.mf.nested(key,...)
-- iterate all sectors, perhaps display all data like the android tool does
end
In order for this to be a little more worthwhile, though, another feature would be needed : the ability to send 'raw' data and read responses. That way, ppl who are good at RFID but not necessarily at home with low-level programming could do quite a lot. Basically, whole protocols could be built within Lua. At least, it would make it simpler to experiment with stuff that it is now.
I have started adding lua, and thought that once I make some progress I will commit it to a branch.
Adding 'raw' command could be done in paralell, and probably within the trunk, since it should be a small addition (by comparison).
No guarantees about when or even if anything comes out of this
Oh, and another thing, if Lua was embedded, the PM3 console could become just a Lua REPL...but that's just a random thought.
Offline
Your idea is really good and from what I read from you I think you are as good as your ideas
That way, ppl who are good at RFID but not necessarily at home with low-level programming could do quite a lot. Basically, whole protocols could be built within Lua. At least, it would make it simpler to experiment with stuff that it is now.
Exactly what I think ! I studied and now know lot of RFID protocols but my programming skills are really "ground-level" so I am bind to someone else skill to be able to solve some of my problems...
I hope that ISO14443A "raw" function will see the light soon together with the lua implementation !
Offline
hf mf raw data-bytes-to-send CRC-on-or-off
Hey asper, take a look at armsrc/iso14443a.c functions TransmitFor14443a() and ReaderTransmitShort(). If you want to add CRC, use AppendCrc14443a(). Hope that helps, my friend.
Offline
Thank you vivat for the answer and for your support in the forum.
Unfortunately I am not good at programming but I really would like to learn at least to do basic things like the one I am requesting... do you have time to write a little source code with comments (like a tutorial) in order for me to learn ? I know this is a big request but maybe can be useful to many others mainly to add support for new tags that uses ISO standards because it is only a matter of "correct commands to send" (and read the answer form tags).
Last edited by asper (2013-05-20 19:33:06)
Offline
I've added Lua now. So far, I've 'hooked up' the hf mf commands, meaning that scripts can do e.g.
hf.mf.mifare("")
However, it's still not super useful. I need to make a few changes, specifically two things:
Right now, each 'operation' seems to parse it's own parameters. From Lua, I don't want to do :
hf.mf.foobar("param1 foo gazonk 0xFFF")
I want to do
hf.mf.foobar(param1, "foo", "gazonk", 0xFFF)
This means that some refactoring is needed, so console can keep calling CmdFoobar(argstring) which parses the params and calls CmdFoobar_Intenrnal(param, foo, bazonk, num). This would enable me to let Lua can call CmdFoobar_Intenrnal directly.
Also, I want the commands not just to display the results, but to return them to the caller. So CmdFoobarInternal would return results, and the CmdFoobar would display it, while Lua scripts would be free to do what they wish.
I will create a branch soon, so anyone interested can check it out. And asper, I'll put those TransmitFor14443a, ReaderTransmitShort() and AppendCrc14443a on top of the priority
Offline
My warmest thanks man !
Offline
I took a quick peek at returning read data to the script...
Question to those who know better (vivat?):
When the device reads 'stuff', such as e.g. ReaderReceive() - will the read data always be available in the samples-buffer? Or is that a 'sometimes, not always' kind of thing?
If always, that would be pretty neat.
[Edit] - Hm, I guess the samples is a bit too low-level, and not quite what the script wants.. oh well.
Last edited by holiman (2013-05-21 13:10:43)
Offline
Ok, new branch created.
svn checkout http://proxmark3.googlecode.com/svn/branches/scripting proxmark3-scripting
When I test on my ubuntu, make works. Probably does not on wndows, but if anyone wants to give it a go there, edit hte client/Makefile
lua_build:
@echo Compiling liblua;
cd ../liblua && make linux
and change into "&& make windows" or perhaps "&& make generic".
After that, you can create scripts and place in the scripts-directory. I think all hf.mf-functions should be callable (arguments goes in as a string), but you'll get no return values.
$ ./proxmark3 /dev/ttyACM1
proxmark3> script
help This help
list <name> -- List available scripts
run Execute a script
proxmark3> script list
helloworld.lua A script file
proxmark3> script run helloworld.lua
Executing file 'helloworld.lua'
---------------------------
Helleo world!
hf: table: 0x7fb884015d00
hf.mf: table: 0x7fb884015d50
and now...
hf.mf.mifare function: 0x425c80
-------------------------------------------------------------------------
Executing command. It may take up to 30 min.
Press the key on the proxmark3 device to abort both proxmark3 and client.
-------------------------------------------------------------------------
..^C
martin@lenovox2:~/workspace/proxmark3-scripting/client
$ cat scripts/helloworld.lua
print("Helleo world!");
print("hf:", hf);
print("hf.mf:",hf.mf);
print("and now... ");
print("hf.mf.mifare",hf.mf.mifare);
hf.mf.mifare("");
function foo()
print("Hi I am the foo function!");
end
Anyway, still very early, changes will happen etc etc : YMMV.
Offline
Can you explain me those values: 7fb884015d00, 7fb884015d50 and 425c80
Are them offsets ?
Offline
Those are nothing to see, really, I just used it to test that I created the lua structure correctly. Lua is dictionary-based, meaning that objects are really dictionaries (/associative arrays/hashmaps/arrays/tables - different names are often used). So, the API is built to look like the structure in the commandline, so
"hf mf mifare" would become "hf.mf.mifare()" , where "hf" is a table (the 0x7fb884015d00 is an address), containing "mf" (another table), containing "mifare" (a function). As you can see, I invoke the function using hf.mf.mifare(""), otherwise hf.mf.mifare - without parenthesis just becomes the mf function (which is an object - functions are first class objects in Lua).
Hope it made some sense...
So, the script just does some printouts and then invokes mifare hack.
Last edited by holiman (2013-05-22 07:59:37)
Offline
Thank you for the explanation ! Now it's a bit clearer... maybe you can make a future tutorial on "how to add commands to support specific ISO standard tags" so anyone can contribute ! Probably I will be the 1st
Last edited by asper (2013-05-22 10:17:59)
Offline
Hold your horses
As I said, it's still very early. Currently more of a PoC than an actual working framework.
Offline
Well I tryed to compile under windows and I can say this:
- in client/Makefile, "generic" is correct, "windows" is not accepted:
lua_build:
@echo Compiling liblua;
cd ../liblua && make generic
- some .dlls are missing but using the ones provided in the compiled "normal" windows release make the .exe to execute (in my actual Windows environement only those 3 were missing)
- the .exe client, providing the correct COM port, opens up but always gives error on com port (PM3 hardware still works [no com port error] with normal proxmark3.exe client) !
Last edited by asper (2013-05-22 10:50:05)
Offline
This is a screenshot of the last compiler lines:
Offline
I committed some fixes and added another example script. Next up will be getting return values from calls. After that, it'll be those send-raw-capabilities.
Offline
Great to hear from you! Is it possible to also have ISO14443B raw commands? (ISO15693 already supports raw!)
Last edited by asper (2013-05-22 19:11:20)
Offline
PS.
I can confirm that the client now compiles and works under windows environement (tested under 7 64bit)
In our GUI there already is an .xml file (settings.xml) that contains ALL PM3 Client supported commands, maybe it can be useful for your lua scripting... parameter explanations can be found inside the GUI pressing the Info button on the top-right:
EDIT:
I jsut added the script commands to the GUI and as you can see it seems to work (I don't know if helloworld.lua is suppose to do something but I don't think):
I will release the new .xml file when this function will be further tested (obviously this will only works with "scripting" branch).
Last edited by asper (2013-05-23 12:07:55)
Offline
That looks so good, with the new GUI and the simplistic of just adding a xml-node and voila, We got scripting capacity!
Great work Gaucho, Asper & Holiman!
Online
Thanks!
Asper, where do those dll's come from ? it would feel better to include sources instead of dlls, from an open-source point of view.
Some updates;
My original idea was to make cmd-line command accessible from scripts, but with better return values, so caling hf.mf.mifare would return keys, nt, etc. However, after having looked into that, I concluded the following:
- Doing so means structurally modifying *every* such command.
- I don't want to mess with things that already work, and that I am unable to test in an automated way to make sure I don't break it.
- It does not give that much more 'win'.
Instead, I have opted for a different route:
- Check what low-level operations are needed to perform fun things. I started wiht "hf mf mifare", and saw that it was only three things (at least two) that are needed in order to build the whole thing in lua instead:
- SendCommand, WaitForResponseTimeout (and nonce2key).
- By implementing lua-bindings for these three, the whole mifare hack could be written in a short lua script. And I suspect that by implementing a handful of lua-bindings for low-level functionality, everything can be done from Lua.
What's currently todo:
- Import a binlib, I will go for http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/#lpack (which is the same that Nmap NSE uses)
- Define UsbCommands in a Lua-library, for easy usbcommand creation/parsing
I also added a PoC lua script which implements a naive lua command line.
Oh, and some more robust error handling has been added, so you can see why a script failed to load or failed to compile/exeute.
Still not production ready, mind you.
[Edit:]
It will still be possible to call any command-line operation using arguments within call-string, but you get no return values : hf.mf.foobar("gax bar zox"), that kind of binding does not require re-wiring of the current command implementation.
Last edited by holiman (2013-05-25 20:04:01)
Offline
I think they are mingw/cygwin dlls, they are needed in running the compiled pm3 client under Windows. If they are not present an error requesting for them appears.
EDIT:
Do you still plan to add "raw command" feature ?
Last edited by asper (2013-05-26 10:28:33)
Offline
Yes, it'll be there, but that's something that needs to be implemented on the device-side first. Once it's there, you will be able to use SendCommand with whatever you like, for example use a new 'raw command' feature.
Offline
Good to hear from you !
Thanks for your efforts !!
Offline
Holiman I think I can help adding some scripts.
Add me on skype : conan_1
Offline
I don't do much skypeing, but you can mail me at martin at the domain swende.se
Offline
I just made a bunch of commits on the scripting-branch. I have now implemented 'lua-glue' to the basic things needed to communicate wth the device. An example script which implements mf check can be found here : https://code.google.com/p/proxmark3/source/browse/branches/scripting/client/scripts/mfkeys.lua .
There is a library which helps creating commands, and another library containing default keys. While implementing this, I noticed that the current implementation puts a cap on the number of keys to test to eight at a time. The usb packet however, can contain over 80 keys, so this script uses 71 default keys that I found on the interwebz. It's very easy to just paste in more keys if you want to test something. Also, perhaps I don't have to mention it, but when doing things in lua-space, you never need to recompile or even restart the app in order for the changes to take effect.
Offline
Sounds amazing. Gonna be time to learn lua then :-)
Offline
Nice holiman !!! Time to learn lua : )
Offline
@asper - regarding sending raw bits and bytes....
I took a look at what's already in the device.
void ReaderTransmitBitsPar(uint8_t* frame, int bits, uint32_t par)
this calls CodeIso14443aBitsAsReaderPar(frame,bits,par); which generates a ToSend array, and then calls
TransmitFor14443a(ToSend, ToSendMax, &samples, &wait); to actually send the data.
The call to CodeIso14443aBitsAsReaderPar does a lot of stuff, I haven't looked too closely at it, but it shifts bits and appears to add parity bits.
( see http://proxmark3.googlecode.com/svn/trunk/armsrc/iso14443a.c )
Now, where would you like to 'hook in'? Would it make sense to hook into ReaderTransmitBitsPar (and ReaderTransmitBits) or would you like to do the bit-shuffling excercise within a script on the host-side, and hook directly into TransmitFor1443a ?
Edit : I suspect CodeIso14443aBitsAsReaderPar mainly deals with formatting for communication with the FPGA, and should remain internal, and that it makes sense to expose ReaderTransmit* functions.
Last edited by holiman (2013-06-28 13:06:35)
Offline
Yeah, what I need is the possibility to send the command bytes using the ISO modulation with the possibility to select the automatic CRC calculation+appending (append or not append CRC).
Those are standard mifare commands:
Using custom raw commands I think it will be possible to add support for non-standard ISO14443A (for example Sony Felica) because the protocol seems to be the same, the only things that changes are commands.
Offline
Hm. I started implementing this, but after a while I saw the method
void ReaderIso14443a(UsbCommand * c)
in https://code.google.com/p/proxmark3/source/browse/trunk/armsrc/iso14443a.c at line 1755. It seems to do pretty much exactly what I was implementing, e.g. line 1791 :
if(param & ISO14A_RAW) {
if(param & ISO14A_APPEND_CRC) {
AppendCrc14443a(cmd,len);
len += 2;
}
ReaderTransmit(cmd,len);
arg0 = ReaderReceive(buf);
// UsbSendPacket((void *)ack, sizeof(UsbCommand));
cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf));
}
There just seems to be lacking support on the console-mode in the host to actually send arbitrary payload. That means that you can already use this from the scripting-engine. Could you try it out? Here's some code to get you started, I haven't tested it, yet, but something along these lines should do it:
local cmds = require('commands')
-- Some raw data
local rawdata = bin.pack("H","DEADBEEF")
-- Want to do both connect and send raw, so we should AND the two commands
-- ISO14A_COMMAND.ISO14A_RAW and ISO14A_CONNECT. However, we don't have a
-- bitlib yet, so we'll do it manually, 1 & 8 == 9
local command = Command:new{cmd = cmds.CMD_READER_ISO_14443a,
arg1 = 9,
arg2 = string:len(rawdata),
data = rawdata}
local err = core.SendCommand(command:getBytes())
if err then
print(err)
return nil, err
end
local result = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
if result then
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result)
-- The result is returned in arg0
print("Got an answer ", arg0)
end
Offline
Hi holiman, how is it going with "send raw commands" function ?
Offline
Well, sorry, I missed your previous post ! Is it possible to add a console command to this function ? I am going to test your script as soon as I get home ! I only have to change the code:
local rawdata = bin.pack("H","DEADBEEF")
i suppose, right ?
Offline
Not really, there were a few errors with that one (it should have waited for two responses instead of one, it double-encoded the payload etc). Check out what's in the SVN instead, I added a script for this which does not work yet. I don't really know why it does not work, I have done a PoC to see if I can get a nonce from a mifare using raw writes and reads. I haven't looked into it enough though, but put it up there for anyone to play with.
To see what's happening behind-the-scenes, check out https://code.google.com/p/proxmark3/source/browse/trunk/armsrc/iso14443a.c around line 1755.
A strange thing I've been seing is that the 14443a-implementation on the device-side does not seem to know how many bytes it has read when a read is performed. I don't understand how it can not know such a vital thing.
Offline
Ok thanks for the explanation. I am not an arm guru so I will wait a working script to test raw commands with some iso14443A tags not recognized by pm3 (yet)! Please post any improvement here and thank you again and again for your hard work!!
Last edited by asper (2013-07-12 22:47:43)
Offline
Sorry for this double post but I would like to know how the "raw command stuff" is going on... any improvement ?
Offline
No, I have not been active at all during the summer, so I have barely touched a computer. I'll be back at work next week, and will probably ramp up my activity a bit from then on.
Offline
Good to hear from you !!!
Offline
Pages: 1