diff --git a/module/mifare.cpp b/module/mifare.cpp index c7f3dd0..68edee3 100644 --- a/module/mifare.cpp +++ b/module/mifare.cpp @@ -18,10 +18,31 @@ Mifare::Mifare(Ui::MainWindow *ui, Util *addr, QWidget *parent) : QObject(parent -void Mifare::info() +QString Mifare::info(bool isRequiringOutput) { - util->execCMD("hf 14a info"); - ui->funcTab->setCurrentIndex(1); + if(isRequiringOutput) + { + QString result = util->execCMDWithOutput("hf 14a info", 500); + qDebug() << result << result.indexOf(QRegExp(ui->MF_RW_dataEdit->text()), 0); + result.replace("UID :", "|"); + result.replace("ATQA :", "|"); + result.replace("SAK :", "|"); + result.replace("TYPE :", "|"); + QStringList lis = result.split("|"); + if(lis.length() > 4) + { + qDebug() << lis[1] + lis[2] + lis[3]; + return lis[1] + lis[2] + lis[3]; + } + else + return ""; + } + else + { + util->execCMD("hf 14a info"); + ui->funcTab->setCurrentIndex(1); + return ""; + } } void Mifare::chk() @@ -399,9 +420,31 @@ void Mifare::wipeC() void Mifare::setParameterC() { - + QString result = info(true); + if(result == "") + QMessageBox::information(parent, tr("Info"), tr("Failed to read card.")); + else + { + QStringList lis = result.split("\r\n"); + lis[0].replace(" ", ""); + lis[1].replace(" ", ""); + lis[2].replace(" ", ""); + MF_UID_parameterDialog dialog(lis[0].toUpper(), lis[1].toUpper(), lis[2].mid(0, 2).toUpper()); + connect(&dialog, &MF_UID_parameterDialog::sendCMD, util, &Util::execCMD); + if(dialog.exec() == QDialog::Accepted) + ui->funcTab->setCurrentIndex(1); + } } +void Mifare::lockC() +{ + util->execCMD("hf 14a raw -pa -b7 40"); + util->execCMD("hf 14a raw -pa 43"); + util->execCMD("hf 14a raw -pa E0 00 39 F7"); + util->execCMD("hf 14a raw -pa E1 00 E1 EE"); + util->execCMD("hf 14a raw -pa 85 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 18 47"); + util->execCMD("hf 14a raw 52"); +} void Mifare::dump() { diff --git a/module/mifare.h b/module/mifare.h index c05f0fe..0205a84 100644 --- a/module/mifare.h +++ b/module/mifare.h @@ -4,6 +4,7 @@ #include "common/util.h" #include "ui_mainwindow.h" #include "ui/mf_attack_hardnesteddialog.h" +#include "ui/mf_uid_parameterdialog.h" #include #include #include @@ -15,7 +16,7 @@ class Mifare : public QObject public: explicit Mifare(Ui::MainWindow *ui, Util *addr, QWidget *parent = nullptr); - void info(); + QString info(bool isRequiringOutput = false); void chk(); void nested(); void hardnested(); @@ -103,6 +104,7 @@ public: void data_setData(int block, const QString &data); void data_setKey(int sector, bool isKeyA, const QString &key); + void lockC(); public slots: signals: @@ -117,6 +119,7 @@ private: QRegExp* dataPattern; QRegExp* chkKeyPattern; QRegExp* nestedKeyPattern; + QRegExp* UIDPattern; }; #endif // MIFARE_H diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp index 76f89e8..4cee8e0 100644 --- a/ui/mainwindow.cpp +++ b/ui/mainwindow.cpp @@ -6,6 +6,8 @@ MainWindow::MainWindow(QWidget *parent) , ui(new Ui::MainWindow) { ui->setupUi(this); + ui->MF_simGroupBox->setVisible(false); // developing... + ui->MF_sniffGroupBox->setVisible(false); // developing... pm3Thread = new QThread(this); pm3 = new PM3Process(pm3Thread); @@ -192,6 +194,18 @@ void MainWindow::on_MF_key2DataBotton_clicked() mifare->data_key2Data(); } +void MainWindow::on_MF_fontButton_clicked() +{ + bool isOK = false; + QFont font = QFontDialog::getFont(&isOK, ui->MF_keyWidget->font(), this, tr("Plz select the font of data widget and key widget")); + + if(isOK) + { + ui->MF_keyWidget->setFont(font); + ui->MF_dataWidget->setFont(font); + } +} + void MainWindow::on_MF_dataWidget_itemChanged(QTableWidgetItem *item) { @@ -393,6 +407,42 @@ void MainWindow::on_MF_UID_writeBlockButton_clicked() mifare->writeC(); } +void MainWindow::on_MF_UID_wipeButton_clicked() +{ + mifare->wipeC(); +} + +void MainWindow::on_MF_UID_aboutUIDButton_clicked() +{ + QString msg; + msg += tr(" Normally, the Block 0 of a typical Mifare card, which contains the UID, is locked during the manufacture. Users cannot write anything to Block 0 or set a new UID to a normal Mifare card.\n"); + msg += tr(" Chinese Magic Cards(aka UID Cards) are some special cards whose Block 0 are writeable. And you can change UID by writing to it.\n"); + msg += "\n"; + msg += tr("There are two versions of Chinese Magic Cards, the Gen1 and the Gen2.\n"); + msg += tr(" Gen1:\n also called UID card in China. It responses to some backdoor commands so you can access any blocks without password. The Proxmark3 has a bunch of related commands(csetblk, cgetblk, ...) to deal with this type of card, and my GUI also support these commands.\n"); + msg += tr(" Gen2:\n doesn't response to the backdoor commands, which means that a reader cannot detect whether it is a Chinese Magic Card or not by sending backdoor commands.\n"); + msg += "\n"; + msg += tr("There are some types of Chinese Magic Card Gen2.\n"); + msg += tr(" CUID Card:\n the Block 0 is writeable, you can write to this block repeatedly by normal wrbl command.\n"); + msg += tr(" (hf mf wrbl 0 A FFFFFFFFFFFF )\n"); + msg += tr(" FUID Card:\n you can only write to Block 0 once. After that, it seems like a typical Mifare card(Block 0 cannot be written to).\n"); + msg += tr(" (some readers might try changing the Block 0, which could detect the CUID Card. In that case, you should use FUID card.)\n"); + msg += tr(" UFUID Card:\n It behaves like a CUID card(or UID card? I'm not sure) before you send some special command to lock it. Once it is locked, you cannot change its Block 0(just like a typical Mifare card).\n"); + msg += "\n"; + msg += tr(" Seemingly, these Chinese Magic Cards are more easily to be compromised by Nested Attack(it takes little time to get an unknown key).\n"); + QMessageBox::information(this, tr("About UID Card"), msg); +} + +void MainWindow::on_MF_UID_setParaButton_clicked() +{ + mifare->setParameterC(); +} + +void MainWindow::on_MF_UID_lockButton_clicked() +{ + mifare->lockC(); +} + void MainWindow::on_MF_Sniff_sniffButton_clicked() { mifare->sniff(); @@ -453,7 +503,7 @@ void MainWindow::uiInit() ui->MF_dataWidget->verticalHeader()->setVisible(false); ui->MF_dataWidget->setColumnWidth(0, 35); ui->MF_dataWidget->setColumnWidth(1, 35); - ui->MF_dataWidget->setColumnWidth(2, 400); + ui->MF_dataWidget->setColumnWidth(2, 430); ui->MF_keyWidget->setColumnCount(3); ui->MF_keyWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Sec"))); @@ -461,8 +511,8 @@ void MainWindow::uiInit() ui->MF_keyWidget->setHorizontalHeaderItem(2, new QTableWidgetItem(tr("KeyB"))); ui->MF_keyWidget->verticalHeader()->setVisible(false); ui->MF_keyWidget->setColumnWidth(0, 35); - ui->MF_keyWidget->setColumnWidth(1, 110); - ui->MF_keyWidget->setColumnWidth(2, 110); + ui->MF_keyWidget->setColumnWidth(1, 115); + ui->MF_keyWidget->setColumnWidth(2, 115); MF_widgetReset(); typeBtnGroup = new QButtonGroup(this); diff --git a/ui/mainwindow.h b/ui/mainwindow.h index e4d00f3..39968b1 100644 --- a/ui/mainwindow.h +++ b/ui/mainwindow.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -104,6 +105,16 @@ private slots: void on_MF_keyWidget_itemChanged(QTableWidgetItem *item); + void on_MF_fontButton_clicked(); + + void on_MF_UID_wipeButton_clicked(); + + void on_MF_UID_aboutUIDButton_clicked(); + + void on_MF_UID_setParaButton_clicked(); + + void on_MF_UID_lockButton_clicked(); + private: Ui::MainWindow* ui; QButtonGroup* typeBtnGroup; diff --git a/ui/mainwindow.ui b/ui/mainwindow.ui index c3b88bb..b4c85b1 100644 --- a/ui/mainwindow.ui +++ b/ui/mainwindow.ui @@ -6,13 +6,13 @@ 0 0 - 859 + 870 770 - 820 + 870 770 @@ -27,6 +27,21 @@ + + 5 + + + 5 + + + 5 + + + 5 + + + 5 + @@ -95,6 +110,21 @@ Mifare + + 5 + + + 5 + + + 5 + + + 5 + + + 5 + @@ -110,7 +140,8 @@ - Courier + Consolas + 12 @@ -152,14 +183,14 @@ - 25 - 25 + 20 + 20 - 25 - 25 + 20 + 20 @@ -177,14 +208,14 @@ - 25 - 25 + 20 + 20 - 25 - 25 + 20 + 20 @@ -192,6 +223,38 @@ + + + + + 20 + 20 + + + + + 20 + 20 + + + + + 20 + 20 + + + + + Courier + 75 + true + + + + F + + + @@ -217,7 +280,8 @@ - Courier + Consolas + 12 @@ -638,7 +702,7 @@ 5 - + Lock UFUID Card @@ -904,6 +968,21 @@ RawCommand + + 5 + + + 5 + + + 5 + + + 5 + + + 5 + diff --git a/ui/mf_uid_parameterdialog.cpp b/ui/mf_uid_parameterdialog.cpp index 6f22472..e30705d 100644 --- a/ui/mf_uid_parameterdialog.cpp +++ b/ui/mf_uid_parameterdialog.cpp @@ -1,14 +1,27 @@ -#include "mf_uid_parameterdialog.h" +#include "mf_uid_parameterdialog.h" #include "ui_mf_uid_parameterdialog.h" -MF_UID_parameterDialog::MF_UID_parameterDialog(QWidget *parent) : +MF_UID_parameterDialog::MF_UID_parameterDialog(const QString& uid, const QString& atqa, const QString& sak, QWidget *parent) : QDialog(parent), ui(new Ui::MF_UID_parameterDialog) { ui->setupUi(this); + ui->UIDLineEdit->setText(uid); + ui->ATQALineEdit->setText(atqa); + ui->SAKLineEdit->setText(sak); } MF_UID_parameterDialog::~MF_UID_parameterDialog() { delete ui; } + +void MF_UID_parameterDialog::on_buttonBox_accepted() +{ + emit sendCMD("hf mf csetuid " + + ui->UIDLineEdit->text() + + " " + + ui->ATQALineEdit->text() + + " " + + ui->SAKLineEdit->text()); +} diff --git a/ui/mf_uid_parameterdialog.h b/ui/mf_uid_parameterdialog.h index 047b647..ec580cb 100644 --- a/ui/mf_uid_parameterdialog.h +++ b/ui/mf_uid_parameterdialog.h @@ -1,4 +1,4 @@ -#ifndef MF_UID_PARAMETERDIALOG_H +#ifndef MF_UID_PARAMETERDIALOG_H #define MF_UID_PARAMETERDIALOG_H #include @@ -12,11 +12,15 @@ class MF_UID_parameterDialog : public QDialog Q_OBJECT public: - explicit MF_UID_parameterDialog(QWidget *parent = nullptr); + explicit MF_UID_parameterDialog(const QString& uid, const QString& atqa, const QString& sak, QWidget *parent = nullptr); ~MF_UID_parameterDialog(); private: Ui::MF_UID_parameterDialog *ui; +signals: + void sendCMD(QString cmd); +private slots: + void on_buttonBox_accepted(); }; #endif // MF_UID_PARAMETERDIALOG_H diff --git a/ui/mf_uid_parameterdialog.ui b/ui/mf_uid_parameterdialog.ui index 6cee732..15d5129 100644 --- a/ui/mf_uid_parameterdialog.ui +++ b/ui/mf_uid_parameterdialog.ui @@ -11,7 +11,7 @@ - Dialog + Set Parameter @@ -48,16 +48,6 @@ - - - - The parameter will not change if you leave it empty. - - - true - - -