Store keys and data into class Mifare

pull/2/head
wh201906 4 years ago
parent 0be1eb5041
commit b2fa97ff18

@ -95,7 +95,7 @@ void PM3Process::onReadyRead()
requiredOutput->append(out); requiredOutput->append(out);
if(out != "") if(out != "")
{ {
qDebug() << "PM3Process::onReadyRead:" << out; // qDebug() << "PM3Process::onReadyRead:" << out;
emit newOutput(out); emit newOutput(out);
} }

@ -9,7 +9,7 @@ Util::Util(QObject *parent) : QObject(parent)
void Util::processOutput(QString output) void Util::processOutput(QString output)
{ {
qDebug() << "Util::processOutput:" << output; // qDebug() << "Util::processOutput:" << output;
if(isRequiringOutput) if(isRequiringOutput)
{ {
requiredOutput->append(output); requiredOutput->append(output);

@ -4,20 +4,14 @@ Mifare::Mifare(Ui::MainWindow *ui, Util *addr, QObject *parent) : QObject(parent
{ {
util = addr; util = addr;
this->ui = ui; this->ui = ui;
keyAList = new QStringList();
keyBList = new QStringList();
dataList = new QStringList();
data_clearKey(); // fill with blank Qstring
data_clearData(); // fill with blank Qstring
} }
bool Mifare::isKeyValid(const QString key)
{
if(key.length() != 12)
return false;
for(int i = 0; i < 12; i++)
{
if(!((key[i] >= '0' && key[i] <= '9') || (key[i] >= 'A' && key[i] <= 'F')))
return false;
}
return true;
}
void Mifare::info() void Mifare::info()
{ {
@ -32,9 +26,14 @@ void Mifare::chk()
QStringList keys = result.split("\r\n"); QStringList keys = result.split("\r\n");
for(int i = 0; i < 16; i++) for(int i = 0; i < 16; i++)
{ {
ui->MF_keyWidget->setItem(i, 1, new QTableWidgetItem(keys[i + 3].mid(7, 12).trimmed().toUpper())); keyAList->replace(i, keys[i + 3].mid(7, 12).trimmed().toUpper());
ui->MF_keyWidget->setItem(i, 2, new QTableWidgetItem(keys[i + 3].mid(24, 12).trimmed().toUpper())); if(keyAList->at(i) == "?")
keyAList->replace(i, "");
keyBList->replace(i, keys[i + 3].mid(24, 12).trimmed().toUpper());
if(keyBList->at(i) == "?")
keyBList->replace(i, "");
} }
data_syncWithKeyWidget();
qDebug() << "***********\n" << keys << "***********\n"; qDebug() << "***********\n" << keys << "***********\n";
} }
@ -46,10 +45,11 @@ void Mifare::nested()
for(int i = 0; i < 16; i++) for(int i = 0; i < 16; i++)
{ {
if(keys[i + 3].at(23) == '1') if(keys[i + 3].at(23) == '1')
ui->MF_keyWidget->setItem(i, 1, new QTableWidgetItem(keys[i + 3].mid(7, 12).trimmed().toUpper())); keyAList->replace(i, keys[i + 3].mid(7, 12).trimmed().toUpper());
if(keys[i + 3].at(44) == '1') if(keys[i + 3].at(44) == '1')
ui->MF_keyWidget->setItem(i, 2, new QTableWidgetItem(keys[i + 3].mid(28, 12).trimmed().toUpper())); keyBList->replace(i, keys[i + 3].mid(28, 12).trimmed().toUpper());
} }
data_syncWithKeyWidget();
qDebug() << "***********\n" << keys << "***********\n"; qDebug() << "***********\n" << keys << "***********\n";
} }
@ -128,57 +128,59 @@ void Mifare::readAll()
bool isKeyAValid; bool isKeyAValid;
bool isKeyBValid; bool isKeyBValid;
const int waitTime = 300; const int waitTime = 300;
for(int i = 0; i < 16; i++) for(int i = 0; i < sectors; i++)
{ {
QApplication::processEvents();
result = ""; result = "";
isKeyAValid = false; isKeyAValid = false;
isKeyBValid = false; isKeyBValid = false;
// check keys and read the first block of each sector // check keys and read the first block of each sector
if(ui->MF_keyWidget->item(i, 1) != nullptr && isKeyValid(ui->MF_keyWidget->item(i, 1)->text())) if(data_isKeyValid(keyAList->at(i)))
{ {
result = util->execCMDWithOutput("hf mf rdbl " result = util->execCMDWithOutput("hf mf rdbl "
+ QString::number(4 * i) + QString::number(4 * i)
+ " A " + " A "
+ ui->MF_keyWidget->item(i, 1)->text(), waitTime); + keyAList->at(i), waitTime);
if(result.indexOf("isOk:01") != -1) if(result.indexOf("isOk:01") != -1)
{ {
isKeyAValid = true; isKeyAValid = true;
ui->MF_dataWidget->setItem(4 * i, 2, new QTableWidgetItem(result.mid(result.indexOf("isOk:01") + 13, 47).toUpper())); result = result.mid(result.indexOf("isOk:01") + 13, 47).toUpper();
result.replace(" ", "");
dataList->replace(4 * i, result);
} }
} }
QApplication::processEvents(); if(data_isKeyValid(keyBList->at(i)))
if(ui->MF_keyWidget->item(i, 2) != nullptr && isKeyValid(ui->MF_keyWidget->item(i, 2)->text()))
{ {
result = util->execCMDWithOutput("hf mf rdbl " result = util->execCMDWithOutput("hf mf rdbl "
+ QString::number(4 * i) + QString::number(4 * i)
+ " B " + " B "
+ ui->MF_keyWidget->item(i, 2)->text(), waitTime); + keyBList->at(i), waitTime);
if(result.indexOf("isOk:01") != -1) if(result.indexOf("isOk:01") != -1)
{ {
isKeyBValid = true; isKeyBValid = true;
ui->MF_dataWidget->setItem(4 * i, 2, new QTableWidgetItem(result.mid(result.indexOf("isOk:01") + 13, 47).toUpper())); result = result.mid(result.indexOf("isOk:01") + 13, 47).toUpper();
result.replace(" ", "");
dataList->replace(4 * i, result);
} }
} }
data_syncWithDataWidget(false, 4 * i);
// read the rest blocks of a sector // read the rest blocks of a sector
if(isKeyAValid || isKeyBValid) if(isKeyAValid || isKeyBValid)
{ {
for(int j = 1; j < 4; j++) for(int j = 1; j < 4; j++)
{ {
QApplication::processEvents();
result = util->execCMDWithOutput("hf mf rdbl " result = util->execCMDWithOutput("hf mf rdbl "
+ QString::number(4 * i + j) + QString::number(4 * i + j)
+ " " + " "
+ (isKeyAValid ? "A" : "B") + (isKeyAValid ? "A" : "B")
+ " " + " "
+ ui->MF_keyWidget->item(i, (isKeyAValid ? 1 : 2))->text(), waitTime); + (isKeyAValid ? keyAList : keyBList)->at(i), waitTime);
result = result.mid(result.indexOf("isOk:01") + 13, 47).toUpper(); result = result.mid(result.indexOf("isOk:01") + 13, 47).toUpper();
ui->MF_dataWidget->setItem(4 * i + j, 2, new QTableWidgetItem(result)); result.replace(" ", "");
dataList->replace(4 * i + j, result);
data_syncWithDataWidget(false, 4 * i + j);
} }
QApplication::processEvents();
// fill the MF_dataWidget with the known valid key // fill the MF_dataWidget with the known valid key
// //
// check whether the MF_dataWidget contains the valid key, // check whether the MF_dataWidget contains the valid key,
@ -186,46 +188,44 @@ void Mifare::readAll()
// //
// the structure is not symmetric, since you cannot get KeyA from output // the structure is not symmetric, since you cannot get KeyA from output
// this program will only process the provided KeyA(in MF_keyWidget) // this program will only process the provided KeyA(in MF_keyWidget)
result = ui->MF_dataWidget->item(4 * i + 3, 2)->text(); result = dataList->at(4 * i + 3);
if(isKeyAValid) if(isKeyAValid)
{ {
for(int j = 0; j < 6; j++) result.replace(0, 12, keyAList->at(i));
{
result = result.replace(j * 3, 2, ui->MF_keyWidget->item(i, 1)->text().mid(j * 2, 2));
}
} }
else else
{ {
result = result.replace(0, 18, "?? ?? ?? ?? ?? ?? "); result = result.replace(0, 12, "????????????");
} }
ui->MF_dataWidget->setItem(4 * i + 3, 2, new QTableWidgetItem(result)); dataList->replace(4 * i + 3, result);
if(isKeyBValid) if(isKeyBValid)
{ {
for(int j = 0; j < 6; j++) result.replace(20, 12, keyBList->at(i));
{ dataList->replace(4 * i + 3, result);
result = result.replace(30 + j * 3, 2, ui->MF_keyWidget->item(i, 2)->text().mid(j * 2, 2)); data_syncWithDataWidget(false, 4 * i + 3);
ui->MF_dataWidget->setItem(4 * i + 3, 2, new QTableWidgetItem(result));
}
} }
else else // now isKeyAValid == true, the output might contains the KeyB
{ {
QString tmpKey = result.right(18).replace(" ", ""); QString tmpKey = dataList->at(4 * i + 3).right(12);
result = util->execCMDWithOutput("hf mf rdbl " result = util->execCMDWithOutput("hf mf rdbl "
+ QString::number(4 * i + 3) + QString::number(4 * i + 3)
+ " B " + " B "
+ tmpKey, waitTime); + tmpKey, waitTime);
if(result.indexOf("isOk:01") != -1) if(result.indexOf("isOk:01") != -1)
{ {
ui->MF_keyWidget->setItem(i, 2, new QTableWidgetItem(tmpKey)); keyBList->replace(i, tmpKey);
data_syncWithKeyWidget(false, i, false);
} }
else else
{ {
result = ui->MF_dataWidget->item(4 * i + 3, 2)->text(); result = dataList->at(4 * i + 3);
result = result.replace(30, 17, "?? ?? ?? ?? ?? ??"); result = result.replace(20, 12, "????????????");
ui->MF_dataWidget->setItem(4 * i + 3, 2, new QTableWidgetItem(result)); dataList->replace(4 * i + 3, result);
} }
} }
data_syncWithDataWidget(false, 4 * i + 3);
} }
} }
} }
@ -248,25 +248,33 @@ void Mifare::write()
void Mifare::writeAll() void Mifare::writeAll()
{ {
const int waitTime = 300;
QString result; QString result;
for(int i = 0; i < 16; i++) for(int i = 0; i < 16; i++)
{ {
for(int j = 0; j < 4; j++) for(int j = 0; j < 4; j++)
{ {
result = util->execCMDWithOutput("hf mf wrbl " result = ""; // if the KeyA is invalid and the result is not empty, the KeyB will not be tested.
+ QString::number(i * 4 + j) if(data_isDataValid(dataList->at(i * 4 + j)) != DATA_NOSPACE || dataList->at(i * 4 + j).contains('?'))
+ " A " continue;
+ ui->MF_keyWidget->item(i, 1)->text() if(data_isKeyValid(keyAList->at(i)))
+ " " {
+ ui->MF_dataWidget->item(2, i * 4 + j)->text().replace(" ", "")); result = util->execCMDWithOutput("hf mf wrbl "
if(result.indexOf("isOk:01") == -1) + QString::number(i * 4 + j)
+ " A "
+ keyAList->at(i)
+ " "
+ dataList->at(i * 4 + j), waitTime);
}
qDebug() << i << j << result.indexOf("isOk:01") << data_isKeyValid(keyBList->at(i));
if(result.indexOf("isOk:01") == -1 && data_isKeyValid(keyBList->at(i)))
{ {
result = util->execCMDWithOutput("hf mf wrbl " result = util->execCMDWithOutput("hf mf wrbl "
+ QString::number(i * 4 + j) + QString::number(i * 4 + j)
+ " B " + " B "
+ ui->MF_keyWidget->item(i, 2)->text() + keyBList->at(i)
+ " " + " "
+ ui->MF_dataWidget->item(2, i * 4 + j)->text().replace(" ", "")); + dataList->at(i * 4 + j), waitTime);
} }
} }
} }
@ -283,3 +291,112 @@ void Mifare::restore()
util->execCMD("hf mf restore"); util->execCMD("hf mf restore");
ui->funcTab->setCurrentIndex(1); ui->funcTab->setCurrentIndex(1);
} }
void Mifare::data_syncWithDataWidget(bool syncAll, int block)
{
QString tmp = "";
if(syncAll)
{
for(int i = 0; i < blocks; i++)
{
tmp += dataList->at(i).mid(0, 2);
for(int j = 1; j < 16; j++)
{
tmp += " ";
tmp += dataList->at(i).mid(j * 2, 2);
}
ui->MF_dataWidget->item(i, 2)->setText(tmp);
}
}
else
{
tmp += dataList->at(block).mid(0, 2);
for(int j = 1; j < 16; j++)
{
tmp += " ";
tmp += dataList->at(block).mid(j * 2, 2);
}
ui->MF_dataWidget->item(block, 2)->setText(tmp);
}
}
void Mifare::data_syncWithKeyWidget(bool syncAll, int sector, bool isKeyA)
{
if(syncAll)
{
for(int i = 0; i < sectors; i++)
{
ui->MF_keyWidget->item(i, 1)->setText(keyAList->at(i));
ui->MF_keyWidget->item(i, 2)->setText(keyBList->at(i));
}
}
else
{
if(isKeyA)
ui->MF_keyWidget->item(sector, 1)->setText(keyAList->at(sector));
else
ui->MF_keyWidget->item(sector, 2)->setText(keyBList->at(sector));
}
}
void Mifare::data_clearData()
{
dataList->clear();
for(int i = 0; i < blocks; i++)
dataList->append("");
}
void Mifare::data_clearKey()
{
keyAList->clear();
keyBList->clear();
for(int i = 0; i < sectors; i++)
{
keyAList->append("");
keyBList->append("");
}
}
bool Mifare::data_isKeyValid(const QString& key)
{
if(key.length() != 12)
return false;
for(int i = 0; i < 12; i++)
{
if(!((key[i] >= '0' && key[i] <= '9') || (key[i] >= 'A' && key[i] <= 'F')))
return false;
}
return true;
}
Mifare::DataType Mifare::data_isDataValid(QString data) // "?" will not been processd there
{
if(data.length() == 47)
{
for(int i = 0; i < 47; i++)
{
if(i % 3 != 0)
{
if(!((data[i] >= '0' && data[i] <= '9') || (data[i] >= 'A' && data[i] <= 'F') || data[i] == '?'))
return DATA_INVALID;
}
else
{
if(data[i] != ' ')
return DATA_INVALID;
}
return DATA_WITHSPACE;
}
}
else if(data.length() == 32)
{
for(int i = 0; i < 32; i++)
{
if(!((data[i] >= '0' && data[i] <= '9') || (data[i] >= 'A' && data[i] <= 'F') || data[i] == '?'))
return DATA_INVALID;
}
return DATA_NOSPACE;
}
else
return DATA_INVALID;
}

@ -6,14 +6,13 @@
#include "ui/mf_attack_hardnesteddialog.h" #include "ui/mf_attack_hardnesteddialog.h"
#include <QObject> #include <QObject>
#include <QString> #include <QString>
#include <QStringList>
class Mifare : public QObject class Mifare : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit Mifare(Ui::MainWindow *ui, Util *addr, QObject *parent = nullptr); explicit Mifare(Ui::MainWindow *ui, Util *addr, QObject *parent = nullptr);
bool isKeyValid(const QString key);
void info(); void info();
void chk(); void chk();
void nested(); void nested();
@ -26,12 +25,33 @@ public:
void writeAll(); void writeAll();
void dump(); void dump();
void restore(); void restore();
enum DataType
{
DATA_INVALID,
DATA_WITHSPACE,
DATA_NOSPACE,
};
void data_clearData();
void data_clearKey();
bool data_isKeyValid(const QString &key);
Mifare::DataType data_isDataValid(QString data);
void data_syncWithDataWidget(bool syncAll = true, int block = 0);
void data_syncWithKeyWidget(bool syncAll = true, int sector = 0, bool isKeyA = true);
public slots: public slots:
signals: signals:
private: private:
Ui::MainWindow *ui; Ui::MainWindow *ui;
Util* util; Util* util;
QStringList* keyAList;
QStringList* keyBList;
QStringList* dataList;
int sectors = 16;
int blocks = 64;
}; };
#endif // MIFARE_H #endif // MIFARE_H

@ -93,7 +93,7 @@ void MainWindow::on_PM3_disconnectButton_clicked()
void MainWindow::refreshOutput(const QString& output) void MainWindow::refreshOutput(const QString& output)
{ {
qDebug() << "MainWindow::refresh:" << output; // qDebug() << "MainWindow::refresh:" << output;
ui->Raw_outputEdit->insertPlainText(output); ui->Raw_outputEdit->insertPlainText(output);
ui->Raw_outputEdit->moveCursor(QTextCursor::End); ui->Raw_outputEdit->moveCursor(QTextCursor::End);
} }
@ -242,7 +242,10 @@ void MainWindow::uiInit()
ui->MF_dataWidget->setHorizontalHeaderItem(1, new QTableWidgetItem("Blk")); ui->MF_dataWidget->setHorizontalHeaderItem(1, new QTableWidgetItem("Blk"));
ui->MF_dataWidget->setHorizontalHeaderItem(2, new QTableWidgetItem("Data")); ui->MF_dataWidget->setHorizontalHeaderItem(2, new QTableWidgetItem("Data"));
for(int i = 0; i < 64; i++) for(int i = 0; i < 64; i++)
{
ui->MF_dataWidget->setItem(i, 1, new QTableWidgetItem(QString::number(i))); ui->MF_dataWidget->setItem(i, 1, new QTableWidgetItem(QString::number(i)));
ui->MF_dataWidget->setItem(i, 2, new QTableWidgetItem(""));
}
for(int i = 0; i < 16; i++) for(int i = 0; i < 16; i++)
ui->MF_dataWidget->setItem(i * 4, 0, new QTableWidgetItem(QString::number(i))); ui->MF_dataWidget->setItem(i * 4, 0, new QTableWidgetItem(QString::number(i)));
ui->MF_dataWidget->verticalHeader()->setVisible(false); ui->MF_dataWidget->verticalHeader()->setVisible(false);
@ -256,7 +259,11 @@ void MainWindow::uiInit()
ui->MF_keyWidget->setHorizontalHeaderItem(1, new QTableWidgetItem("KeyA")); ui->MF_keyWidget->setHorizontalHeaderItem(1, new QTableWidgetItem("KeyA"));
ui->MF_keyWidget->setHorizontalHeaderItem(2, new QTableWidgetItem("KeyB")); ui->MF_keyWidget->setHorizontalHeaderItem(2, new QTableWidgetItem("KeyB"));
for(int i = 0; i < 16; i++) for(int i = 0; i < 16; i++)
{
ui->MF_keyWidget->setItem(i, 0, new QTableWidgetItem(QString::number(i))); ui->MF_keyWidget->setItem(i, 0, new QTableWidgetItem(QString::number(i)));
ui->MF_keyWidget->setItem(i, 1, new QTableWidgetItem(""));
ui->MF_keyWidget->setItem(i, 2, new QTableWidgetItem(""));
}
ui->MF_keyWidget->verticalHeader()->setVisible(false); ui->MF_keyWidget->verticalHeader()->setVisible(false);
ui->MF_keyWidget->setColumnWidth(0, 35); ui->MF_keyWidget->setColumnWidth(0, 35);
ui->MF_keyWidget->setColumnWidth(1, 110); ui->MF_keyWidget->setColumnWidth(1, 110);

Loading…
Cancel
Save