- #include "airodump.h"
- #include "ui_airodump.h"
-
- Airodump::Airodump(QWidget *parent) :
- QWidget(parent),
- ui(new Ui::Airodump)
- {
- ui->setupUi(this);
- process = new QProcess(this);
- //initializing
- //this->ui->pushButtonStop->hide();
- //connecting buttons
- connect(this->ui->pushButtonStart, SIGNAL(clicked()), this, SLOT(start()));
- connect(this->ui->pushButtonStop, SIGNAL(clicked()), this, SLOT(stop()));
- //connect button to sort
- connect(this->ui->pushButtonSort, SIGNAL(clicked()), this, SLOT(sort()));
- //connect things to trigger associated stations
- connect(this->ui->tableWidgetAirodumpGeneral, SIGNAL(itemSelectionChanged()), this, SLOT(selectStationsAssociated()));
- //below table, signal when new station appear
- connect(this, SIGNAL(stationAppear(infoConnectionBssid)), this, SLOT(newStationAppear(infoConnectionBssid)));
- //attack deauth
- connect(this->ui->pushButtonDeauth, SIGNAL(clicked()), this, SLOT(attackDeauth()));
- //attack auth
- connect(this->ui->pushButtonAuth, SIGNAL(clicked()), this, SLOT(attackAuth()));
- //attack broadcast
- connect(this->ui->pushButtonBroadcast, SIGNAL(clicked()), this, SLOT(attackBroadcast()));
- //aircrack
- connect(this->ui->pushButtonCrack, SIGNAL(clicked()), this, SLOT(aircrack()));
- //capture
- connect(this->ui->pushButtonCapture, SIGNAL(clicked()), this, SLOT(capture()));
- //status
- connect(this, SIGNAL(statusChanged(QString)), this->ui->lineEditStatus, SLOT(setText(QString)));
- connect(this, SIGNAL(statusChanged(QString)), this, SLOT(enableCorrectOptions(QString)));
- //time elapsed
- connect(&this->time, SIGNAL(timeout()), this, SLOT(uploadTime()));
-
-
- //not implemented
- connect(this->ui->pushButtonARP, SIGNAL(clicked()), this, SLOT(notImplemented()));
- connect(this->ui->pushButtonChop, SIGNAL(clicked()), this, SLOT(notImplemented()));
- connect(this->ui->pushButtonChop, SIGNAL(clicked()), this, SLOT(notImplemented()));
-
- process->setProcessChannelMode(QProcess::MergedChannels);
-
- }
-
- Airodump::~Airodump()
- {
- delete ui;
- if (process->state() == QProcess::Running) {
- utils::killProcess(process->pid());
- process->waitForFinished(WAIT_FOR_PROCESS);
- }
- }
-
- void Airodump::test(){
- }
-
- void Airodump::start(){
- this->startMonitor(false);
- }
-
- void Airodump::capture(){
- this->startMonitor(true);
- }
-
- void Airodump::setStatus(QString s){
- GLOBALS::STATUS = s; //ESTO NO TIENE QUE SER GLOBAL AL PUTO PROGRAMA, HAY QUE HACERLO LOCAL AL OBJETO airodump
- emit statusChanged(s);
- }
-
- void Airodump::attackBroadcast(){
- infoConnectionBssid infoC = this->getSelectedInfoConnectionBssid();
- infoESSID infoE = this->getSelectedInfoESSID();
-
- if (infoE.getBSSID().isEmpty()){
- utils::mostrarMensaje("Please, select a BSSID in the up table");
- return;
- }
-
- if (!utils::validMAC(infoC.getBSSID())) { //can be (not associated)
- if (QMessageBox::question(this, "Message", "We need any station associated to do the attack.\nWould you want to do a Fake Auth Attack?",
- QMessageBox::Yes, QMessageBox::No)
- == QMessageBox::Yes)
- this->doAttackAuth(infoE.getBSSID(), 30, "");
-
- return;
- }
-
- emit doAttackBroadcast(infoE.getBSSID(), infoC.getStation());
- }
-
- //depends of the STATE and the tables (if there are selected rows)
- void Airodump::enableCorrectOptions(QString status){
- if (status == "STOPPED") {
- utils::setBackgroundColor(this->ui->lineEditStatus, utils::RED);
- this->ui->groupBoxAttackOptions->setEnabled(false);
- this->ui->pushButtonCapture->setEnabled(false);
- this->ui->pushButtonCrack->setEnabled(false);
- }
-
- else if (status == "MONITORING") {
- utils::setBackgroundColor(this->ui->lineEditStatus, utils::YELLOW);
- this->ui->groupBoxAttackOptions->setEnabled(false);// maybe we can set to true
- //row selected?, then active capture and crack
- if (!this->ui->tableWidgetAirodumpGeneral->selectedItems().isEmpty()) {
- this->ui->pushButtonCapture->setEnabled(true);
- this->ui->pushButtonCrack->setEnabled(true);
- }
-
- else
- this->ui->pushButtonCapture->setEnabled(false);
- }
-
-
- else if (status == "CAPTURING") {
- utils::setBackgroundColor(this->ui->lineEditStatus, utils::GREEN);
- //select the unique row
- if (this->ui->tableWidgetAirodumpGeneral->selectedItems().isEmpty()) //to avoid infinite bucle between selectStationsAssociated and this
- this->ui->tableWidgetAirodumpGeneral->selectRow(0);
-
- this->ui->pushButtonCrack->setEnabled(true);
- this->ui->groupBoxAttackOptions->setEnabled(true);
- this->ui->pushButtonCapture->setEnabled(false);
- }
- }
-
- void Airodump::attackDeauth(){
- infoConnectionBssid infoC = this->getSelectedInfoConnectionBssid();
- infoESSID infoE = this->getSelectedInfoESSID();
-
- //if there are a row of below selected, we already have BSSID + MAC ASSOCIATED
- if (!infoC.getBSSID().isEmpty())
- emit doAttackDeauth(infoC.getBSSID(), 10, infoC.getStation());
-
- //if there are a row of up table selected, we have the BSSID, we can do deauth to all
- else if (!infoE.getBSSID().isEmpty())
- emit doAttackDeauth(infoE.getBSSID(), 10, "");
-
- else //nothing selected
- utils::mostrarMensaje("Please, select a row of tables to attack. Below table to do Deauth to One Mac Station connected (RECOMMENDED).\n" \
- "Up table to do a massive deauthentication to all stations connected to that BSSID.");
- }
-
- void Airodump::attackAuth(){
- infoESSID infoE = this->getSelectedInfoESSID();
-
- //if there are a row of up table selected
- if (!infoE.getBSSID().isEmpty())
- emit doAttackAuth(infoE.getBSSID(), 30, "");
-
- else //nothing selected
- utils::mostrarMensaje("Please, select a row of table to attack (BSSID)");
- }
-
- void Airodump::aircrack(){
- infoESSID infoE = this->getSelectedInfoESSID();
-
- //if there are a row of up table selected
- if (!infoE.getBSSID().isEmpty())
- emit doAircrack(infoE.getBSSID());
-
- else //nothing selected
- utils::mostrarMensaje("Please, select a row of table to attack (BSSID)");
- }
-
- void Airodump::selectStationsAssociated(){
- if (this->ui->tableWidgetAirodumpGeneral->selectedItems().isEmpty()) //FIX: to avoid crash when start with any selected row
- return;
-
- //since here, there are any selected row
-
-
- //updating enabled options
- this->enableCorrectOptions(GLOBALS::STATUS);
-
- //taking BSSID to see if he have any station associated
- const QString BSSID = this->ui->tableWidgetAirodumpGeneral->selectedItems().at(0)->data(Qt::DisplayRole).toString();
- //stations associated
- QList<QString> stations;
-
- for (int i=0; i<this->ui->tableWidgetAirodumpAux->rowCount(); ++i) {
- //if BSSID is in the bottom table, then he has any station associated
- if (this->ui->tableWidgetAirodumpAux->item(i, 0)->data(Qt::DisplayRole).toString() == BSSID) {
- //if the row in the bottom table is not selected
- if (!this->ui->tableWidgetAirodumpAux->selectedItems().contains(this->ui->tableWidgetAirodumpAux->item(i, 0))) {
- //select row [ONLY CAN SELECT ONE!!!!!!!!!] //log aki
- this->ui->tableWidgetAirodumpAux->selectRow(i);
- return;
- }
-
- //append station associated
- // stations.append(this->ui->tableWidgetAirodumpAux->item(i, 1)->data(Qt::DisplayRole).toString());
- }
- }
- //if there are any station associated, then show them
- /*
- if (stations.size() != 0)
- emit toLog(QString::number(stations.size()) + " station/s associated to BSSID " + BSSID +
- "\n" + utils::listToString(stations));
- */
-
- //nothing MAC associated
- this->ui->tableWidgetAirodumpAux->clearSelection();
-
-
- }
-
- void Airodump::newStationAppear(infoConnectionBssid infoC){
-
- if (GLOBALS::STATUS == "CAPTURING"){
- //select the latest row entered
- for (int i=0; i<this->ui->tableWidgetAirodumpAux->rowCount(); ++i)
- if (this->ui->tableWidgetAirodumpAux->item(i, 1)->data(Qt::DisplayRole).toString() == infoC.getStation()) {
- this->ui->tableWidgetAirodumpAux->selectRow(i);
- break;
- }
- }
- }
-
- void Airodump::startMonitor(bool capture){
-
- //init
- QString args;
-
- //taking arguments
- if (this->ui->checkBoxFilterB->isChecked()) {
- if (utils::validMAC(this->ui->lineEditBSSID->text()))
- args += (QString)" --bssid " += this->ui->lineEditBSSID->text();
- else
- utils::mostrarWarning("BSSID " + this->ui->lineEditBSSID->text() + " invalid.");
- }
-
- if (this->ui->checkBoxFilterC->isChecked())
- args += (QString)" -c " += QString::number(this->ui->spinBoxChannel->value());
-
- if (this->ui->checkBoxFilterE->isChecked())
- args += (QString)" --enc " += this->ui->comboBoxE->currentText();
-
-
- QString command;
-
- if (capture) {
- const infoESSID infoE = this->getSelectedInfoESSID();
- if (infoE.getBSSID().isEmpty()) {
- utils::mostrarError("You must specify a BSSID selecting a row of the up table");
- return;
- }
-
- command = (SUDO_AUX + " " + AIRODUMP_COM + " -c " + QString::number(infoE.getChannel()) + " --bssid " +
- infoE.getBSSID() + " -w " + CAPTURE_FOLDER + infoE.getBSSID() + " " + GLOBALS::INTERFACE);
- }
-
- else
- command = (SUDO_AUX + " " + AIRODUMP_COM + " " + args + " " + GLOBALS::INTERFACE);
-
- //stopping previus process
- stop();
- //REMOVE ANY PREVIOUS BUFFER
- if (QFile::exists(BUFFER_AIRODUMP_FILENAME))
- if (!fileM4.remove(BUFFER_AIRODUMP_FILENAME))
- utils::mostrarError("Error trying to remove previus .M4 file buffer");
-
-
-
- //START!
- process->start(command);
- emit toLog(command);
- if (!process->waitForStarted(WAIT_FOR_PROCESS))
- utils::mostrarError("Error al intentar ejecutar " + command);
- //checking errors. //Wait for reading enough information
-
- //esto hay que arreglarlo, kizas un usleep?
- process->waitForReadyRead(WAIT_FOR_PROCESS);
- process->waitForReadyRead(WAIT_FOR_PROCESS);
- process->waitForReadyRead(WAIT_FOR_PROCESS);
- process->waitForReadyRead(WAIT_FOR_PROCESS);
- process->waitForReadyRead(WAIT_FOR_PROCESS);
- process->waitForReadyRead(WAIT_FOR_PROCESS);
- const QString info = process->readAllStandardOutput();
- if (!info.contains("Elapsed")) { //maybe we can fix - se tiene que mejorar la deteccion de errores
- toLog(utils::htmlRojo(info));
- utils::mostrarError(info);
- utils::mostrarError("Are you sure that you have executed Airmon-ng in options\nto put interface into Monitor Mode and select correct\
- interface?\nSEE LOG");
- //stopping
- this->ui->pushButtonStop->click();
- }
-
- else if (!this->openFileM4()){
- utils::mostrarError("Error trying to open .M4 file");
- //stopping
- this->ui->pushButtonStop->click();
- }
-
- else {
-
- //starting
- //init vectors
- this->clearInfoVectors();
- //clear tables
- this->clearTables();
- update();
- //restore time elapsed
- this->ui->spinBoxTime->setValue(0);
- //init time elapsed
- time.start(1000);
-
- //setStatus is the latest to do (to avoid problems associated a enableCorrectOptions)
- if (capture)
- this->setStatus("CAPTURING");
- else
- this->setStatus("MONITORING");
- }
-
-
- }
-
-
- bool Airodump::openFileM4(){
- fileM4.setFileName(BUFFER_AIRODUMP_FILENAME);
- return fileM4.open(QIODevice::ReadOnly);
- }
-
- void Airodump::stop(){
- //terminating process
- if (process->state() == QProcess::Running) {
- utils::killProcess(process->pid());
- if (!process->waitForFinished(WAIT_FOR_PROCESS))
- utils::mostrarError("Critical. Error trying to finalize the process airodump");
- }
- //closing buffer
- this->fileM4.close();
- //de-selecting tables
- this->ui->tableWidgetAirodumpAux->clearSelection();
- this->ui->tableWidgetAirodumpGeneral->clearSelection();
- //status
- this->setStatus("STOPPED");
- //time elapsed
- time.stop();
-
- }
-
- void Airodump::update(){
-
- //fprintf(stderr, "%s\n", process->readAllStandardOutput().data());
- //taking BSSIDS
- convertInfo();
- //inserting values
- for (int i=0; !infoE[i].getBSSID().isEmpty(); ++i)
- insertRow(infoE[i], this->ui->tableWidgetAirodumpGeneral);
- for (int i=0; !infoC[i].getBSSID().isEmpty(); ++i)
- insertRow(infoC[i], this->ui->tableWidgetAirodumpAux);
-
- if (process->state() == QProcess::Running)
- QTimer::singleShot(TIME_UPDATE_AIRODUMP, this, SLOT(update()));
- }
-
-
- void Airodump::sort(){
- //activate sorting
- this->ui->tableWidgetAirodumpGeneral->setSortingEnabled(true);
-
- //0 = POWER
- //1 = Beacons
- //2 = data
- //3 = data/s
- this->ui->tableWidgetAirodumpGeneral->sortByColumn(this->ui->comboBoxSort->currentIndex() + 1, Qt::DescendingOrder);
-
-
- //disabling sorting
- this->ui->tableWidgetAirodumpGeneral->setSortingEnabled(false);
-
- }
-
- //CRITICAL FUNCTION. Convert info from buffer.
- int Airodump::convertInfo(){
-
- static int nInfoE, nInfoC;
- static QStringList fields;
- //close the buffer to re-read it (because it is updated all time)
- fileM4.close();
- if (!this->fileM4.open(QIODevice::ReadOnly))
- utils::mostrarError("Error trying to re-open .M4 to be read");
-
- //init index of vectors
- nInfoE = nInfoC = 0;
-
- //nothing to read?
- if (fileM4.readLine().isEmpty())
- return -1;
-
- //reading trash
- fileM4.readLine();
-
- //filling first table
- while (1) {
- fields = QString(fileM4.readLine()).split(',');
- fields.replaceInStrings(" ", "");
- if (fields.size() != 16)
- break;
-
- this->infoE[nInfoE].setAuth(fields.at(7));
- this->infoE[nInfoE].setBeacons(fields.at(9));
- this->infoE[nInfoE].setBSSID(fields.at(0));
- this->infoE[nInfoE].setChannel(fields.at(3));
- this->infoE[nInfoE].setCipher(fields.at(6));
- this->infoE[nInfoE].setData(fields.at(10));
- this->infoE[nInfoE].setDataS(fields.at(14));
- this->infoE[nInfoE].setEnc(fields.at(5));
- this->infoE[nInfoE].setMb(fields.at(4));
- this->infoE[nInfoE].setName(fields.at(13));
- this->infoE[nInfoE].setPower(fields.at(8));
-
- nInfoE++;
- }
-
- //reading trash
- fileM4.readLine();
-
- //filling second table
- while (1){
- fields = QString(fileM4.readLine()).split(',');
- fields.replaceInStrings(" ", "");
- if (fields.size() != 9)
- break;
-
- this->infoC[nInfoC].setBSSID(fields.at(5));
- this->infoC[nInfoC].setLost(fields.at(6));
- this->infoC[nInfoC].setPackets(fields.at(4));
- this->infoC[nInfoC].setPower(fields.at(3));
- this->infoC[nInfoC].setProbes(((QString)fields.at(8))); //aki hay caracteres erroneos
- this->infoC[nInfoC].setRate(fields.at(7));
- this->infoC[nInfoC].setStation(fields.at(0));
-
- nInfoC++;
-
- }
- return 1;
-
-
- }
-
- bool Airodump::insertRow(const infoConnectionBssid &infoC, QTableWidget *table){
- //infoC empty?
- if (infoC.getBSSID().isEmpty())
- return false;
-
- //init
- int index = 0;
- bool newStation = false;
-
- //is the infoC ALREADY in the table?
- for (index=0; index<table->rowCount(); ++index)
- if (table->item(index,0)->text() == infoC.getBSSID()) //yes, it is. We store the index
- break;
-
- //no, it is not, insert new row.
- if (index == table->rowCount()) {
- QProgressBar *p = new QProgressBar(this); //is sure that we destroy it?
- table->insertRow(index);
- table->setCellWidget(index, 2, p);
- p->setValue(0);
- newStation = true;
- }
-
- //insert items of row
- table->setItem(index, 0, utils::toItem(infoC.getBSSID()));
- table->setItem(index, 1, utils::toItem(infoC.getStation()));
- ((QProgressBar *)table->cellWidget(index,2))->setValue(infoC.getPower());
- table->setItem(index, 2, utils::toItem(infoC.getPower())); //we need to insert also this item to can sorting by it
- table->setItem(index, 3, utils::toItem(infoC.getRate()));
- table->setItem(index, 4, utils::toItem(infoC.getLost()));
- table->setItem(index, 5, utils::toItem(infoC.getPackets()));
- table->setItem(index, 6, utils::toItem(infoC.getProbes()));
-
- if (newStation) //new station is entered
- emit stationAppear(infoC);
-
- //all correct
- return true;
-
-
-
- }
-
- bool Airodump::insertRow(const infoESSID &info, QTableWidget *table){
- //info empty?
- if (info.getBSSID().isEmpty())
- return false;
- //init
- int index = 0;
- //is the info ALREADY in the table?
- for (index=0; index<table->rowCount(); ++index)
- if (table->item(index,0)->text() == info.getBSSID()) //yes, it is. We store the index
- break;
-
- //no, it is not, insert new row.
- if (index == table->rowCount()) {
- QProgressBar *p = new QProgressBar(this); //is sure that we destroy it?, SI CREO QUE SE DESTRUYE, porque el padre lo destruye cuando muere.
- table->insertRow(index);
- table->setCellWidget(index, 1, p);
- }
-
- //insert items of row
- table->setItem(index, 0, utils::toItem(info.getBSSID()));
- ((QProgressBar *)table->cellWidget(index,1))->setValue(info.getPowerConverted());
- table->setItem(index, 1, utils::toItem(info.getPowerConverted())); //we need to insert also this item to can sorting by it
- table->setItem(index, 2, utils::toItem(info.getBeacons()));
- table->setItem(index, 3, utils::toItem(info.getData()));
- table->setItem(index, 4, utils::toItem(info.getDataS()));
- table->setItem(index, 5, utils::toItem(info.getChannel()));
- table->setItem(index, 6, utils::toItem(info.getMb()));
- table->setItem(index, 7, utils::toItem(info.getEnc()));
- table->setItem(index, 8, utils::toItem(info.getCipher()));
- table->setItem(index, 9, utils::toItem(info.getAuth()));
- table->setItem(index, 10, utils::toItem(info.getName()));
-
-
-
- return true;
- }
-
- infoESSID Airodump::getSelectedInfoESSID(){
- infoESSID out;
- QList<QTableWidgetItem*> items = this->ui->tableWidgetAirodumpGeneral->selectedItems(); //one row
- if (items.isEmpty()) //no selection?
- return out; //no me mola muxo devolver una local posiblemente vacia
-
- out.setBSSID(items.at(0)->text());
- out.setPower(items.at(1)->text());
- out.setBeacons(items.at(2)->text());
- out.setData(items.at(3)->text());
- out.setDataS(items.at(4)->text());
- out.setChannel(items.at(5)->text());
- out.setMb(items.at(6)->text());
- out.setEnc(items.at(7)->text());
- out.setCipher(items.at(8)->text());
- out.setAuth(items.at(9)->text());
- out.setName(items.at(10)->text());
-
- return out;
-
- }
-
-
-
- infoConnectionBssid Airodump::getSelectedInfoConnectionBssid(){
- infoConnectionBssid out;
- QList<QTableWidgetItem*> items = this->ui->tableWidgetAirodumpAux->selectedItems(); //one row
- if (items.isEmpty()) //no selection?
- return out; //no me mola muxo devolver una local posiblemente vacia
-
- out.setBSSID(items.at(0)->text());
- out.setStation(items.at(1)->text());
- out.setPower(items.at(2)->text());
- out.setRate(items.at(3)->text());
- out.setLost(items.at(4)->text());
- out.setPackets(items.at(5)->text());
- out.setProbes(items.at(6)->text());
-
- return out;
-
- }
-
- //a implementar
- infoConnectionBssid Airodump::getRowInfoConnectionBssid(int row){
-
- }
-
- void Airodump::uploadTime(){
- this->ui->spinBoxTime->setValue(this->ui->spinBoxTime->value()+1);
- }
-
-
- void Airodump::clearInfoVectors(){
- infoE.clear();
- infoC.clear();
- }
-
- void Airodump::clearTables(){
-
- while (this->ui->tableWidgetAirodumpAux->rowCount() > 0)
- this->ui->tableWidgetAirodumpAux->removeRow(this->ui->tableWidgetAirodumpAux->rowCount()-1);
- while (this->ui->tableWidgetAirodumpGeneral->rowCount() > 0)
- this->ui->tableWidgetAirodumpGeneral->removeRow(this->ui->tableWidgetAirodumpGeneral->rowCount()-1);
-
- }