From dcab7a01c06f150ae8d4ff8dbf8b84ba58bcccf7 Mon Sep 17 00:00:00 2001 From: Dobrica Pavlinusic Date: Mon, 31 Jan 2011 22:49:41 +0100 Subject: [PATCH] easily dump unique mifare cards, remembering keys --- nfc-card-dumper.pl | 87 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100755 nfc-card-dumper.pl diff --git a/nfc-card-dumper.pl b/nfc-card-dumper.pl new file mode 100755 index 0000000..5403ada --- /dev/null +++ b/nfc-card-dumper.pl @@ -0,0 +1,87 @@ +#!/usr/bin/perl +use warnings; +use strict; + +use RFID::Libnfc::Reader; +use RFID::Libnfc::Constants; +use File::Slurp; +use Digest::MD5 qw(md5_hex); + +use Data::Dump qw(dump); + +my $keyfile = shift @ARGV; + +my $r = RFID::Libnfc::Reader->new(debug => 1); +if ($r->init()) { + printf ("Reader: %s\n", $r->name); + my $tag = $r->connect(IM_ISO14443A_106); + + if ($tag) { + $tag->dump_info; + } else { + warn "No TAG"; + exit -1; + } + + my $uid = sprintf "%02x%02x%02x%02x", unpack('C4', $tag->{_nai}->abtUid); + # @{ $tag->uid }; # FIXME this doesn't work with tags which have 00 in UID! + + warn "UID: $uid\n"; + + $keyfile ||= "cards/$uid.key"; + + if ( -e $keyfile ) { + warn "# loading keys from $keyfile"; + $tag->load_keys($keyfile); + warn "## _keys = ", dump($tag->{_keys}); + } + + $tag->select if ($tag->can("select")); + + my $card; + + print STDERR "reading"; + for (my $i = 0; $i < $tag->blocks; $i++) { + if (my $data = $tag->read_block($i)) { + # if we are dumping an ultralight token, + # we receive 16 bytes (while a block is 4bytes long) + # so we can skip next 3 blocks + $i += 3 if ($tag->type eq "ULTRA"); + $card .= $data; + print STDERR "$i "; + } else { + die $tag->error."\n"; + } + } + print STDERR "done\n"; + + # re-insert keys into dump + my $keys = $tag->{_keys} || die "can't find _keys"; + foreach my $i ( 0 .. $#$keys ) { + my $o = $i * 0x40 + 0x30; + last if $o > length($card); + $card + = substr($card, 0, $o) . $keys->[$i]->[0] + . substr($card, $o+6, 4) . $keys->[$i]->[1] + . substr($card, $o+16) + ; + warn "sector $i keys re-inserted at $o\n"; + } + + my $md5 = md5_hex($card); + if ( glob "cards/$uid.md5.*" ) { + warn "SKIPPING, same dump allready exits\n"; + } else { + + my $out_file = "cards/$uid.$md5"; + write_file $out_file, $card; + print "$out_file ", -s $out_file, " bytes\n"; + if ( ! -e "cards/$uid.key" ) { + symlink $out_file, "cards/$uid.key" || die "cards/$uid.key: $!"; + warn "using keys as default for card $uid\n"; + } + system "./mifare-mad.pl $out_file | vi -R -"; + } + +} + -- 2.20.1