summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorU-Thinking\Karsten <Karsten@Thinking.(none)>2010-08-17 14:15:09 +0200
committerU-Thinking\Karsten <Karsten@Thinking.(none)>2010-08-17 14:15:09 +0200
commite71463e716bc2e527a5960966bcfcdc9f9fccfa8 (patch)
tree633357d1cd63fef061149fac07b9a54f6bcd44a2
parentf75fb90134eb1b45c8a91d82b75e4f78681062d5 (diff)
parentd72bcdb8f9630ece273978d4979ea25a63e15997 (diff)
Merge branch 'master' of git.gnumonks.org:easyhack
Conflicts: paper/easycard.tex
-rw-r--r--easycard.2/201008142200-recharge500ntd-increased.mfdbin0 -> 4096 bytes
-rw-r--r--easycard.2/201008171045-after_174_ntd_purchase.mfdbin0 -> 4096 bytes
-rw-r--r--easycard.2/log.hex14
-rw-r--r--easytool/data.c1
-rw-r--r--easytool/easycard.c2
-rw-r--r--easytool/easycard.h1
-rw-r--r--easytool/easytool.c81
-rw-r--r--paper/easycard.tex73
8 files changed, 122 insertions, 50 deletions
diff --git a/easycard.2/201008142200-recharge500ntd-increased.mfd b/easycard.2/201008142200-recharge500ntd-increased.mfd
new file mode 100644
index 0000000..4374a49
--- /dev/null
+++ b/easycard.2/201008142200-recharge500ntd-increased.mfd
Binary files differ
diff --git a/easycard.2/201008171045-after_174_ntd_purchase.mfd b/easycard.2/201008171045-after_174_ntd_purchase.mfd
new file mode 100644
index 0000000..313e5fb
--- /dev/null
+++ b/easycard.2/201008171045-after_174_ntd_purchase.mfd
Binary files differ
diff --git a/easycard.2/log.hex b/easycard.2/log.hex
index af7cf84..cc944e8 100644
--- a/easycard.2/log.hex
+++ b/easycard.2/log.hex
@@ -6,11 +6,11 @@
0000050 0000 1000 1027 0027 64de 0001 0000 bb00
0000060 f1d6 b4e8 0012 0000 0000 6400 0064 6900
0000070 2e64 f724 bd57 7708 008f 8917 3d48 5dcd
-0000080 0089 0000 ff76 ffff 0089 0000 ff00 ff00
-0000090 0089 0000 ff76 ffff 0089 0000 ff00 ff00
-00000a0 c408 6708 304c 0064 0089 5b42 c50b 0031
+0000080 035f 0000 fca0 ffff 035f 0000 ff00 ff00
+0000090 035f 0000 fca0 ffff 035f 0000 ff00 ff00
+00000a0 c408 6708 304c 03e8 040d 5b42 c50b 0031
00000b0 0d3d 782b 33cd 7708 008f 2411 4ce7 ea3f
-00000c0 0007 0003 0000 0000 0000 0000 0000 0000
+00000c0 0009 0004 0000 0000 0000 0000 0000 0000
00000d0 6b07 6593 114c 0012 0025 0811 6cf9 0002
00000e0 9f06 658b 004c 0000 0037 2911 6c06 0002
00000f0 2fb1 511f 85b4 7708 008f 8dc8 eef5 2850
@@ -19,11 +19,11 @@
0000120 9f06 658b 004c 0000 0037 2902 6c06 0002
0000130 4587 96bd 1f22 7708 008f 47ce 7619 1558
0000140 6b07 6593 114c 0012 0025 0802 6cf9 0002
-0000150 f004 6417 004c 0000 0061 2402 6a1c 0002
+0000150 5e09 6a64 204c 00ae 035f 0150 d092 0050
0000160 a605 6418 114c 0010 0051 2402 6d2c 0002
0000170 5583 7616 749e 7708 008f 9bf3 c129 8eb6
0000180 0a00 0200 0022 0000 0000 0000 1800 3200
-0000190 0200 2200 0022 0000 0000 0000 1600 1400
+0000190 0200 2200 0022 0000 0000 0000 1a00 1800
00001a0 0008 0003 0000 0000 0000 0000 0000 0000
00001b0 af5f 6aeb 3a2c 7708 008f c039 7a1d d248
00001c0 0000 0000 0000 0000 0000 0000 0000 0000
@@ -60,7 +60,7 @@
00003b0 3320 9074 e84c 7708 008f 0094 85d5 7aaa
00003c0 8000 c926 0071 0000 0000 0000 0064 0064
00003d0 0000 0000 0000 0000 0000 0000 0000 0000
-00003e0 0000 0000 0000 0000 0000 0c00 233d 0001
+00003e0 0000 0000 0000 0000 0000 1100 ae3d 0000
00003f0 ea02 0bda b62a 7708 008f 0000 0000 0000
0000400 0000 0000 0000 0000 0000 0000 0000 0000
0000410 0000 0000 0000 0000 0000 0000 0000 0000
diff --git a/easytool/data.c b/easytool/data.c
index 9b20930..425f0f2 100644
--- a/easytool/data.c
+++ b/easytool/data.c
@@ -118,6 +118,7 @@ const struct value_string taipei_mrt_stn_id[] = {
/* Easycard Transaction Type names */
const struct value_string easy_tt_names[] = {
{ EASY_TT_MRT_ENTER, "Enter MRT" },
+ { EASY_TT_BUS, "Bus ride" },
{ EASY_TT_MRT_REENTER, "ReEnter MRT" },
{ EASY_TT_MRT_EXIT, "Leave MRT" },
{ EASY_TT_PURCHASE, "Shop Purchase" },
diff --git a/easytool/easycard.c b/easytool/easycard.c
index 980735d..a98c280 100644
--- a/easytool/easycard.c
+++ b/easytool/easycard.c
@@ -52,7 +52,7 @@ time_t easy_timestamp2time(const uint8_t *easy_ts)
int easy_update_log_rec(struct easy_log_rec *elr, int16_t delta)
{
int32_t sum = elr->amount + delta;
- int32_t remaining = elr->remaining = delta;
+ int32_t remaining = elr->remaining + delta;
if ((sum < 0 || sum > 0xffff) ||
(remaining < 0 || remaining > 0xffff))
diff --git a/easytool/easycard.h b/easytool/easycard.h
index 8979524..1631c60 100644
--- a/easytool/easycard.h
+++ b/easytool/easycard.h
@@ -6,6 +6,7 @@
#include "utils.h"
#define EASY_TT_MRT_ENTER 0x00
+#define EASY_TT_BUS 0x01
#define EASY_TT_MRT_REENTER 0x80
#define EASY_TT_MRT_EXIT 0x11
#define EASY_TT_PURCHASE 0x20
diff --git a/easytool/easytool.c b/easytool/easytool.c
index 67157c8..c504003 100644
--- a/easytool/easytool.c
+++ b/easytool/easytool.c
@@ -27,6 +27,7 @@
#include <fcntl.h>
#include <string.h>
#include <time.h>
+#include <getopt.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
@@ -41,16 +42,24 @@
/* Easycard specific includes */
#include "easycard.h"
-#define VERSION "0.03"
+#define VERSION "0.04"
#define COPYRIGHT \
"EasyTool "VERSION" (C) 2010 by Harald Welte <laforge@gnumonks.org>\n" \
"This is FREE SOFTWARE with ABSOLUTELY NO WARRANTY\n\n" \
"Use of this software is authorized for RESEARCH PURPOSE ONLY!\n\n"
+enum mode {
+ MODE_DUMP_MFACC,
+ MODE_DUMP,
+ MODE_RECHARGE,
+ MODE_PURCHASE,
+};
+
struct {
int fd;
unsigned long size;
mifare_tag *mft;
+ enum mode mode;
} global;
static void dump_acc_bits(const struct acc_bits_parsed *abp)
@@ -128,17 +137,59 @@ static void print_help(void)
int main(int argc, char **argv)
{
struct stat st;
+ int delta = 0;
+ int option_index = 0;
+ int rc;
+ int prot, flags = O_RDONLY;
+
+ global.mode = MODE_DUMP;
printf(COPYRIGHT);
- if (argc < 2) {
+ while (1) {
+ int c;
+ static struct option long_options[] = {
+ { "dump-access-bits", 0, 0, 'a' },
+ { "alter-recharge", 1, 0, 'r' },
+ { "alter-purchase", 1, 0, 'p' },
+ { "help", 0, 0, 'h' },
+ { 0, 0, 0, 0 }
+ };
+
+ c = getopt_long(argc, argv, "r:p:ha",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'a':
+ global.mode = MODE_DUMP_MFACC;
+ break;
+ case 'r':
+ global.mode = MODE_RECHARGE;
+ flags = O_RDWR;
+ delta = atoi(optarg);
+ break;
+ case 'p':
+ global.mode = MODE_PURCHASE;
+ flags = O_RDWR;
+ delta = atoi(optarg);
+ break;
+ case 'h':
+ print_help();
+ exit(0);
+ break;
+ }
+ };
+
+ if (argc <= optind) {
fprintf(stderr, "ERROR: You must specify the file name of "
"a mifare dump file (.mfd)\n");
print_help();
exit(2);
}
- global.fd = open(argv[1], O_RDONLY);
+ global.fd = open(argv[optind], flags);
if (global.fd < 0) {
perror("Error opening the MFD file");
exit(1);
@@ -148,15 +199,31 @@ int main(int argc, char **argv)
exit(1);
}
global.size = st.st_size;
- global.mft = mmap(NULL, global.size, PROT_READ, MAP_SHARED,
- global.fd, 0);
+
+ prot = PROT_READ;
+ if (flags == O_RDWR)
+ prot |= PROT_WRITE;
+
+ global.mft = mmap(NULL, global.size, prot, MAP_SHARED, global.fd, 0);
if (!global.mft) {
perror("Error mmap()ing the MFD file");
exit(1);
}
- //dump_mfcl(global.mft);
- dump_easycard(global.mft);
+ switch (global.mode) {
+ case MODE_DUMP_MFACC:
+ dump_mfcl(global.mft);
+ break;
+ case MODE_DUMP:
+ dump_easycard(global.mft);
+ break;
+ case MODE_RECHARGE:
+ rc = easy_alter_last_recharge(global.mft, delta);
+ break;
+ case MODE_PURCHASE:
+ rc = easy_alter_last_purchase(global.mft, delta);
+ break;
+ }
munmap(global.mft, global.size);
close(global.fd);
diff --git a/paper/easycard.tex b/paper/easycard.tex
index 248b2ec..ebaaf83 100644
--- a/paper/easycard.tex
+++ b/paper/easycard.tex
@@ -4,7 +4,7 @@
\usepackage{subfigure}
\pagestyle{plain}
-%\usepackage{url}
+\usepackage{url}
\setlength{\oddsidemargin}{0in}
\setlength{\evensidemargin}{0in}
@@ -20,7 +20,7 @@
\title{Security analysis of the EasyCard payment card in Taiwan}
\author{Harald Welte $<$laforge@gnumonks.org$>$}
-\date{UNRELEASED (September XX, 2010}
+\date{UNRELEASED (September XX, 2010)}
\maketitle
%%%%%%%%%%%%%%%%%%%
@@ -115,12 +115,12 @@ they key of at least one different sectors.
\subsection{Recovering the MIFARE CRYPTO1 keys}
Since none of the sector keys was known, the publicly available MFCUK (MiFare
-Classic Universal toolKit) implementation of the "Dark Side" attack (Nicolas T.
+Classic Universal toolKit) implementation of the ``Dark Side'' attack (Nicolas T.
Courtois) was used as a card-only attack.
All that was required was the MFCUK Free Software, as well as a RFID
reader as supported by libnfc. Compatible readers are widely available,
-among them one for EUR 30 from http://www.touchatag.com/e-store.
+among them one for EUR 30 from \url{http://www.touchatag.com/e-store}.
Using the MFCUK key recovery tool, the A and B keys for all sectors have
been recovered within FIXME. This attack can definitely be optimized
@@ -140,6 +140,7 @@ with the nfc-mfclassic program (part of libnfc).
A full dump of the newly-purchased, unused EasyCard revealed the following
content:
+\begin{verbatim}
0000000 a193 c031 88c3 0004 ba46 1214 1051 1004
0000010 140e 0100 0207 0308 0409 1008 0000 0000
0000020 0000 0000 0000 0000 0000 0000 0000 0000
@@ -204,6 +205,7 @@ content:
00003d0 0000 0000 0000 0000 0000 0000 0000 0000
00003e0 0000 0000 0000 0000 0000 0000 0000 0000
00003f0 ea02 0bda b62a 7708 008f 0000 0000 0000
+\end{verbatim}
\subsection{Re-engineering the on-card data format}
@@ -234,7 +236,7 @@ any of the tested transactions.
The result of this analysis can be found in the next section:
-%%%%%%%%%%%%%%%%%%%
+
\section{Re-engineered EasyCard Data Format}
\subsubsection{Sector 0 and 1: The header}
@@ -254,7 +256,7 @@ transportation as well as stores use key A for this sector, as key A is
sufficient to read and decrement the VALUE block.
Re-charging the card must happen using authentication with key B, as only
-Key B has permissions to increment and/or write to this sector.
+key B has permissions to increment and/or write to this sector.
\subsubsection{Sector 3 through 5: The transaction log}
@@ -308,7 +310,7 @@ FIXME: Transaction log pointer
\subsubsection{Sector 7: The last MRT entry/exit record}
-Block 2 (Offset 0x1e0) contains a record dscribing the last MRT station
+Block 2 (Offset 0x1e0) contains a record describing the last MRT station
that was entered using this EasyCard.
\begin{itemize}
\item Bytes 0...3 are unknown
@@ -328,7 +330,7 @@ applicable discount in case a connection is made from MRT into a bus.
\subsubsection{Sector 15: Maximum daily spending}
-Sector 2 (Offset 0x3e0) contains a record used for keeping track of
+Block 2 (Offset 0x3e0) contains a record used for keeping track of
the amount of money spent on a single day. This is needed in order
to impose a daily spending limit of (currently) NTD 3,000.
@@ -345,7 +347,7 @@ sum is incremented with every purchase. If an EasyCard terminal in the store
detects that the current day-of-the-month is different from that stored on the
card, the sum is re-set and starts new for that day.
-%%%%%%%%%%%%%%%%%%%
+
\section{Manipulating the EasyCard}
\subsection{Decreasing the Value of the card}
@@ -367,16 +369,16 @@ balance.
Re-reading the card after the purchase indicates the full success of the
operation. The purchase has left exactly the same changes in the card like
it would have with a card that has a genuine lower value. None of the
-erroneosly increased (or decreased) numbers had been updated.
+erroneously increased (or decreased) numbers had been updated.
This specifically confirms that the vending terminal did not have an online
connection to a centralized database. In that case, the erroneous values
on the card would have been corrected and the original value restored.
-\subsection{Increaing the value of the card}
+\subsection{Increasing the value of the card}
The approach works similar to the previous one. First, a purchase in a store
-is being made, preferably with relatively high value. Later, the transaction
+is being made, preferrably with relatively high value. Later, the transaction
log record, card balance and amount spent per day fields are modified to make
this purchase appear cheaper than it actually was. So after purchasing an item
with 1000 NTD, the card will look like only 100 NTD were spent for the purchase,
@@ -395,7 +397,7 @@ with the transaction log. So it would be wise for an attacker to also modify
all purchases in the transaction log to appear as if they were made on a
previous day.
-%%%%%%%%%%%%%%%%%%%
+
\section{Mistakes of the EasyCard Corporation}
Based on this research as well as publicly known information on the
@@ -411,8 +413,8 @@ system.
The underlying Mifare Classic product was launched in 1994, and thus already
relatively old and outdated technology at that time.
-It was publicly documented by NXP that the security of the system is baesd on a
-{\em prorprietary, symmetric, 48bit cipher}. Symmetric 48-bit encryption
+It was publicly documented by NXP that the security of the system is based on a
+{\em proprietary, symmetric, 48bit cipher}. Symmetric 48-bit encryption
was definitely no longer state-of-the-art in the year 2000. At that time,
the popular web-browser Netscape Navigator (used e.g. for web-based online
banking) had already introduced support for symmetric 128bit ciphers.
@@ -424,11 +426,11 @@ design} and {\em Security by obscurity}.
In the former systems, security is achieved by using well-designed systems
that have undergone public peer review and have been subject to cryptanalysis.
-As a result, the system is secure because it has undergond the review and
+As a result, the system is secure because it has undergone the review and
scrutiny of the international community of cryptographers and security experts.
So, despite making all details of the system, particularly the cryptographic
-algorithms open, an attacker is not able to circumvent the systems security.
+algorithms open, an attacker is not able to circumvent the system's security.
A system relying on {\em Security by obscurity} is only secure because
nobody knows the details of how it works. As soon as this information
@@ -480,18 +482,18 @@ technically, cards can be re-charged without making actual payment for it.
As far as cards are only used for public transportation, the incentive
for fraudulent use is relatively small and contained. Also, the amount
-of money for each transaction is realtively small.
+of money for each transaction is relatively small.
Thus, while the author would still disagree, it might be the case that
the business risk analysis inside EasyCard Corporation would have deemed the
risk of fraud in the public transport sector as acceptable.
When such a card is used as an electronic payment system in stores where
-goods of much higher value can be purcased, the threat model is quite
+goods of much higher value can be purchased, the threat model is quite
different, though.
The 2010 introduction of the EasyCard as means of payment in retail
-stores - while still relying on known-broken, 16 year old technology -
+stores -- while still relying on known-broken, 16 year old technology --
can thus only be seen as ignorant and incompetent.
It does not help that EasyCard corporation has to provide a full refund
@@ -504,7 +506,7 @@ only reflect themselves in increased transaction fees for retail stores, in the
end it will be the consumer who pays them indirectly due to higher prices
including such fees.
-%%%%%%%%%%%%%%%%%%%
+
\section{Proposed Changes / Improvements}
The author of this paper argues that use of the current EasyCard system
@@ -536,31 +538,32 @@ EasyCard corporation should be liable for the complete system
upgrade/transition cost, as the fault of the system can only be blamed
on them.
-%%%%%%%%%%%%%%%%%%%
+
\section{Credits}
The author of this paper expresses his gratitude to the many people
involved in trying to uncover the weaknesses of proprietary and ultimately
insecure RFID systems worldwide.
-Milosch and Brita Meriac
+\begin{description}
+\item[Milosch and Brita Meriac]
for their great work on OpenPCD and OpenPICC
-Henryk Ploetz, Karsten Nohl, starbug
+\item[Henryk Ploetz, Karsten Nohl, starbug]
for their work on MIFARE, Crypto1 and tiresome research into all kinds of proprietary snake-oil
-Jonathan Westhues
+\item[Jonathan Westhues]
for designing and openly publishing the Proxmark
-Mate Soos and Karsten Nohl
+\item[Mate Soos and Karsten Nohl]
for their results on exploiting CRYPTO1's statistical wekanesses using SAT solvers
-Nethemba
+\item[Nethemba]
for the Open Source implementation of the nested key attack in MFOC
-Roel Verdult
- for his research on RFID security at Radbound University and libnfc
-Nicolas T. Courtois
+\item[Roel Verdult]
+ for his research on RFID security at Radboud University and libnfc
+\item[Nicolas T. Courtois]
for his {\em darkside} paper
-Andrei Costin
- for his Open Sourc implementation of the darkside paper (MFCUK)
- http://andreicostin.com/
-
+\item[Andrei Costin]
+ for his Open Source implementation of the darkside paper (MFCUK)
+ \url{http://andreicostin.com/}
+\end{description}
%%%%%%%%%%%%%%%%%%%
\bibliographystyle{unsrt}
%\bibliographystyle{splncs}
@@ -585,4 +588,4 @@ Andrei Costin
%13. [ROSSSASG] - "SASG35_Peter_v_Rossum_Mifare.pdf"
%14. [DARK2009] - "THE DARK SIDE OF SECURITY BY OBSCURITY and Cloning MiFare Classic Rail and Building Passes, Anywhere, Anytime"
-\end{document}
+\end{document} \ No newline at end of file
personal git repositories of Harald Welte. Your mileage may vary