PageRenderTime 24ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/airodump.cpp

https://gitlab.com/gustawho/aircrackgui-m4
C++ | 1023 lines | 634 code | 247 blank | 142 comment | 180 complexity | b3555b3842661d5006c4df01df3b4a65 MD5 | raw file
  1. #include "airodump.h"
  2. #include "ui_airodump.h"
  3. #define QT_NO_CAST_FROM_ASCII
  4. Airodump::Airodump(QWidget *parent) :
  5. QWidget(parent),
  6. ui(new Ui::Airodump)
  7. {
  8. logThread::addLog("Constructor of airodump GUI", logInfo::MAIN);
  9. ui->setupUi(this);
  10. process = new QProcess(this);
  11. this->status = STOPPED;
  12. //initializing
  13. //this->ui->pushButtonStop->hide();
  14. //connecting buttons
  15. connect(this->ui->pushButtonStart, SIGNAL(clicked()), this, SLOT(start()));
  16. connect(this->ui->pushButtonStop, SIGNAL(clicked()), this, SLOT(stop()));
  17. //connect button to sort
  18. connect(this->ui->pushButtonSort, SIGNAL(clicked()), this, SLOT(sort()));
  19. //connect things to trigger associated stations
  20. connect(this->ui->tableWidgetAirodumpGeneral, SIGNAL(itemSelectionChanged()), this, SLOT(selectStationsAssociated()));
  21. //below table, signal when new station appear
  22. connect(this, SIGNAL(stationAppear(infoConnectionBssid)), this, SLOT(newStationAppear(infoConnectionBssid)));
  23. connect(this, SIGNAL(BSSIDAppear(infoESSID)), this, SLOT(newBSSIDAppear(infoESSID)));
  24. //attack deauth
  25. connect(this->ui->pushButtonDeauth, SIGNAL(clicked()), this, SLOT(attackDeauth()));
  26. //attack auth
  27. connect(this->ui->pushButtonAuth, SIGNAL(clicked()), this, SLOT(attackAuth()));
  28. //attack broadcast
  29. connect(this->ui->pushButtonBroadcast, SIGNAL(clicked()), this, SLOT(attackBroadcast()));
  30. //aircrack
  31. connect(this->ui->pushButtonCrack, SIGNAL(clicked()), this, SLOT(aircrack()));
  32. //capture
  33. connect(this->ui->pushButtonCapture, SIGNAL(clicked()), this, SLOT(capture()));
  34. //arp replay
  35. connect(this->ui->pushButtonARP, SIGNAL(clicked()), this, SLOT(attackArpReplay()));
  36. //interactive
  37. connect(this->ui->pushButtonInteractiveARP, SIGNAL(clicked()), this, SLOT(attackInteractiveARP()));
  38. //frag
  39. connect(this->ui->pushButtonFrag, SIGNAL(clicked()), this, SLOT(attackFragmetation()));
  40. //chop
  41. connect(this->ui->pushButtonChop, SIGNAL(clicked()), this, SLOT(attackChopChop()));
  42. //reaver
  43. connect(this->ui->pushButtonReaver, SIGNAL(clicked()), this, SLOT(attackReaver()));
  44. //all
  45. connect(this->ui->pushButtonAllAttacks, SIGNAL(clicked()), this, SLOT(allAttacks()));
  46. //status
  47. connect(this, SIGNAL(statusChanged(STATUS)), this, SLOT(enableCorrectOptions(STATUS)));
  48. //more info
  49. connect(this->ui->pushButtonMoreInfo, SIGNAL(clicked()), this, SLOT(showMoreInfo()));
  50. //stop all
  51. connect(this->ui->pushButtonStopAll, SIGNAL(clicked()), this, SLOT(stopAllAttacks()));
  52. //changes the main interface
  53. connect(this->ui->comboBoxInterfaces, SIGNAL(currentIndexChanged(QString)), this, SLOT(setMainInterface(QString)));
  54. //
  55. //when guy changes the attack type, stop airodump
  56. connect(this->ui->tabWidgetAttack, SIGNAL(currentChanged(int)), this->ui->pushButtonStop, SLOT(click()));
  57. connect(this->ui->tabWidgetAttack, SIGNAL(currentChanged(int)), this, SLOT(clearTables()));
  58. //donate
  59. connect(this->ui->pushButtonDonate, SIGNAL(clicked()), this, SLOT(openDonate()));
  60. // available later
  61. connect(this->ui->pushButtonCaptureHandshake, SIGNAL(clicked()), this, SLOT(availableLater()));
  62. connect(this->ui->pushButtonM4Auto, SIGNAL(clicked()), this, SLOT(attackM4()));
  63. connect(this->ui->spinBoxInjectionRate, SIGNAL(valueChanged(int)),
  64. this, SIGNAL(injectionRateChanged(int)));
  65. //load interfaces in monitor mode
  66. this->ui->comboBoxInterfaces->addItems(utils::getListInterfacesMonitorMode());
  67. //disabling things
  68. //this->ui->groupBoxAttackOptions->setEnabled(false);
  69. this->ui->pushButtonCapture->setEnabled(false);
  70. this->ui->pushButtonCrack->setEnabled(false);
  71. this->ui->pushButtonMoreInfo->setEnabled(false);
  72. connect(this->ui->spinBoxChannel, SIGNAL(valueChanged(int)), this, SLOT(restart()));
  73. process->setProcessChannelMode(QProcess::MergedChannels);
  74. }
  75. Airodump::~Airodump()
  76. {
  77. logThread::addLog("Destructor of airodump GUI", logInfo::MAIN);
  78. delete ui;
  79. if (process->state() == QProcess::Running) {
  80. //utils::killProcess(process->pid());
  81. process->waitForFinished(WAIT_FOR_PROCESS);
  82. }
  83. }
  84. void Airodump::setMainInterface(QString interface)
  85. {
  86. logThread::addLog("Airodump: Set main interface to " + interface, logInfo::MAIN);
  87. GLOBALS::INTERFACE=interface;
  88. }
  89. void Airodump::reloadInterfaces()
  90. {
  91. this->ui->comboBoxInterfaces->clear();
  92. this->ui->comboBoxInterfaces->addItems(utils::getListInterfacesMonitorMode());
  93. }
  94. void Airodump::start(){
  95. this->startMonitor(false);
  96. }
  97. void Airodump::capture(){
  98. this->startMonitor(true);
  99. }
  100. void Airodump::setStatus(STATUS s){
  101. status = s;
  102. emit statusChanged(s);
  103. }
  104. void Airodump::openDonate()
  105. {
  106. QDesktopServices::openUrl(QUrl("https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=Q7WM3MVSDTR8W&lc=ES&item_name=Aircrack%20GUI%20M4&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted"));
  107. }
  108. void Airodump::stopAllAttacks(){
  109. emit doStopAllAttacks();
  110. }
  111. void Airodump::updateAircrackStatus(const QString &status)
  112. {
  113. utils::setBackgroundColorAutomaticWithText(this->ui->lineEditStatusAircrack, status);
  114. }
  115. void Airodump::updateAuthStatus(const QString &status){
  116. utils::setBackgroundColorAutomaticWithText(this->ui->lineEditStatusAuth, status);
  117. }
  118. void Airodump::updateARPReplayStatus(const QString &status){
  119. utils::setBackgroundColorAutomaticWithText(this->ui->lineEditStatusARPReplay, status);
  120. }
  121. void Airodump::updateReaverStatus(const QString &status){
  122. utils::setBackgroundColorAutomaticWithText(this->ui->lineEditStatusReaver, status);
  123. }
  124. void Airodump::updateFragmentationStatus(const QString &status){
  125. utils::setBackgroundColorAutomaticWithText(this->ui->lineEditStatusFragmentation, status);
  126. }
  127. void Airodump::updateChopChopStatus(const QString &status){
  128. utils::setBackgroundColorAutomaticWithText(this->ui->lineEditStatusChopChop, status);
  129. }
  130. void Airodump::updateBroadcastStatus(const QString &status){
  131. utils::setBackgroundColorAutomaticWithText(this->ui->lineEditStatusBroadcast, status);
  132. }
  133. void Airodump::updateDeauthStatus(const QString &status){
  134. utils::setBackgroundColorAutomaticWithText(this->ui->lineEditStatusDeauth, status);
  135. }
  136. void Airodump::allAttacks(){
  137. logThread::addLog("Airodump: Trying to launch all attacks", logInfo::MAIN);
  138. if (this->getSelectedInfoESSID() == NULL || this->getSelectedInfoESSID()->getBSSID().isEmpty()){
  139. utils::mostrarMensaje("Please, select a BSSID in the up table");
  140. return;
  141. }
  142. if (this->getSelectedInfoConnectionBssid() == NULL || !utils::validMAC(this->getSelectedInfoConnectionBssid()->getBSSID())) //can be (not associated)
  143. if (QMessageBox::question(this, "Message", "We need any station associated to do the attacks.\n Would you want to do a Fake Auth Attack?",
  144. QMessageBox::Yes, QMessageBox::No) != QMessageBox::Yes)
  145. return;
  146. //Broadcast
  147. attackBroadcast();
  148. //ARP-REPLAY
  149. attackArpReplay();
  150. //Fragmentation
  151. attackFragmetation();
  152. //ChopChop
  153. attackChopChop();
  154. //focus airodump in the main window
  155. emit focus(this);
  156. utils::mostrarMensaje("All attacks launched!");
  157. }
  158. void Airodump::showMoreInfo(){
  159. QList<QTableWidgetItem*> listE = this->ui->tableWidgetAirodumpGeneral->selectedItems();
  160. QList<QTableWidgetItem*> listC = this->ui->tableWidgetAirodumpAux->selectedItems();
  161. if (listE.isEmpty()) //FIX: to avoid crash when start with any selected row
  162. return;
  163. const QString BSSID = listE.at(0)->data(Qt::DisplayRole).toString();
  164. const infoESSID* selected = infoE.get(BSSID);
  165. if (selected == NULL)
  166. return;
  167. //showing info
  168. /*
  169. QString mb;
  170. QString enc;
  171. QString cipher;
  172. QString auth;
  173. */
  174. QString auth;
  175. if (selected->getAuth().isEmpty())
  176. auth = "Not Known Yet";
  177. else
  178. auth = selected->getAuth();
  179. int nStations = 0;
  180. //fix: if we are capturing, not all rows selected are selected, only one.
  181. if (this->status == CAPTURING)
  182. nStations = this->ui->tableWidgetAirodumpAux->rowCount();
  183. else {
  184. //Important: There are 7 items per row, so the rows selected is items/7
  185. for (int i=0; i<listC.size(); i=i+7)
  186. if (listC.at(i)->text() == BSSID)
  187. nStations++;
  188. }
  189. const QString info =
  190. "\nBSSID = " + selected->getBSSID() +
  191. "\nName = " + selected->getName() +
  192. "\nEncryption = " + selected->getEnc() +
  193. "\nCipher = " + selected->getCipher() +
  194. "\nAuthentication = " + auth +
  195. "\nNumber Of Stations Associated Now = " + QString::number(nStations);
  196. utils::mostrarMensaje(info, "More info about BSSID");
  197. }
  198. void Airodump::attackInteractiveARP(){
  199. logThread::addLog("Airodump: Trying to launch Interactive ARP attack", logInfo::MAIN);
  200. infoESSID *infoE = this->getSelectedInfoESSID();
  201. infoConnectionBssid *infoC = this->getSelectedInfoConnectionBssid();
  202. if (infoE == NULL || infoE->getBSSID().isEmpty()){
  203. utils::mostrarMensaje("Please, select a BSSID in the up table");
  204. return;
  205. }
  206. //problem: arp must be from a specific mac to a specific bssid
  207. QString MAC;
  208. if (infoC == NULL || infoC->getBSSID().isEmpty()) {
  209. //I think any arp to that BSSID must works
  210. //utils::mostrarMensaje("Using our MAC as source MAC to do the interactive attack.\narp.cap must have been produced by our MAC as well" +
  211. // QString(" for do a succesfull attack"));
  212. MAC = utils::getMacAdress(GLOBALS::INTERFACE);
  213. }
  214. else
  215. MAC = infoC->getStation();
  216. utils::mostrarMensaje(QString() + "Please, select cap where you have a valid arp capture to\n" +
  217. //I think any arp to that BSSID must works
  218. //QString("MAC = ") + MAC +
  219. "\nBSSID = " + infoE->getBSSID());
  220. //if we have a folder with caps from that BSSID, looking in it
  221. QString searchFolder;
  222. if (QFile::exists(FORGED_ARPS+infoE->getBSSID())) {
  223. logThread::addLog("Airodump: ARP Interactive, Detected forged arp in " + FORGED_ARPS+infoE->getBSSID(), logInfo::MAIN);
  224. searchFolder = FORGED_ARPS+infoE->getBSSID();
  225. }
  226. else
  227. searchFolder = FORGED_ARPS;
  228. //searchFolder = "./";
  229. const QString cap = QFileDialog::getOpenFileName(this, "", searchFolder, "*.cap");
  230. if (cap.isEmpty())
  231. return;
  232. //correct
  233. emit doAttackInteractiveARP(infoE->getBSSID(), MAC, cap);
  234. }
  235. void Airodump::attackFragmetation(){
  236. logThread::addLog("Airodump: Trying to launch Fragmentation attack", logInfo::MAIN);
  237. infoConnectionBssid *infoC = this->getSelectedInfoConnectionBssid();
  238. infoESSID *infoE = this->getSelectedInfoESSID();
  239. if (infoE == NULL || infoE->getBSSID().isEmpty()){
  240. utils::mostrarMensaje("Please, select a BSSID in the up table");
  241. return;
  242. }
  243. if (infoC == NULL || !utils::validMAC(infoC->getBSSID())) { //can be (not associated)
  244. if (QMessageBox::question(this, "Message", "We need any station associated to do the attack.\n Would you want to do a Fake Auth Attack?",
  245. QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
  246. emit doAttackAuth(infoE->getBSSID(), "");
  247. return;
  248. }
  249. emit doAttackFragmentation(infoE->getBSSID(), infoC->getStation());
  250. }
  251. void Airodump::attackReaver()
  252. {
  253. logThread::addLog("Airodump: Trying to launch Reaver attack", logInfo::MAIN);
  254. infoESSID *infoE = this->getSelectedInfoESSID();
  255. if (infoE == NULL || infoE->getBSSID().isEmpty()){
  256. utils::mostrarMensaje("Please, select a BSSID in the up table");
  257. return;
  258. }
  259. emit doAttackReaver(infoE->getBSSID());
  260. }
  261. /*
  262. DETERMINATE WICH ATTACK IS BETTER TO BE LAUNCHED
  263. */
  264. void Airodump::attackM4()
  265. {
  266. logThread::addLog("Airodump: * M4 ATTACK IN PROCESS !!!!!!", logInfo::MAIN);
  267. infoConnectionBssid *infoC = this->getSelectedInfoConnectionBssid();
  268. infoESSID *infoE = this->getSelectedInfoESSID();
  269. bool isWep = this->ui->tabWidgetAttack->isVisible();
  270. bool haveClientAssociated = false;
  271. if (infoE == NULL || infoE->getBSSID().isEmpty()){
  272. utils::mostrarMensaje("Please, select a BSSID in the up table");
  273. return;
  274. }
  275. if (infoC != NULL)
  276. if (utils::validMAC(infoC->getBSSID())) //can be (not associated)
  277. haveClientAssociated = true;
  278. // WEP
  279. // Case 1. Have client associated. ARP REPLAY + DEAUTH
  280. if (isWep && haveClientAssociated) {
  281. logThread::addLog("Airodump: * M4 ATTACK: Case 1. Have client associated. ARP REPLAY + DEAUTH", logInfo::MAIN);
  282. emit doAttackArpReplay(infoE->getBSSID(), infoC->getStation());
  283. emit doAttackDeauth(infoE->getBSSID(), infoC->getStation());
  284. }
  285. // Case X....
  286. }
  287. void Airodump::attackChopChop(){
  288. logThread::addLog("Airodump: Trying to launch ChopChop attack", logInfo::MAIN);
  289. infoConnectionBssid *infoC = this->getSelectedInfoConnectionBssid();
  290. infoESSID *infoE = this->getSelectedInfoESSID();
  291. if (infoE == NULL || infoE->getBSSID().isEmpty()){
  292. utils::mostrarMensaje("Please, select a BSSID in the up table");
  293. return;
  294. }
  295. if (infoC == NULL || !utils::validMAC(infoC->getBSSID())) { //can be (not associated)
  296. if (QMessageBox::question(this, "Message", "We need any station associated to do the attack.\n Would you want to do a Fake Auth Attack?",
  297. QMessageBox::Yes, QMessageBox::No)
  298. == QMessageBox::Yes)
  299. emit doAttackAuth(infoE->getBSSID(), "");
  300. return;
  301. }
  302. emit doAttackChopChop(infoE->getBSSID(), infoC->getStation());
  303. }
  304. void Airodump::attackBroadcast(){
  305. logThread::addLog("Airodump: Trying to launch Broadcast attack", logInfo::MAIN);
  306. infoConnectionBssid *infoC = this->getSelectedInfoConnectionBssid();
  307. infoESSID *infoE = this->getSelectedInfoESSID();
  308. if (infoE == NULL || infoE->getBSSID().isEmpty()){
  309. utils::mostrarMensaje("Please, select a BSSID in the up table");
  310. return;
  311. }
  312. if (infoC == NULL || !utils::validMAC(infoC->getBSSID())) { //can be (not associated)
  313. if (QMessageBox::question(this, "Message", "We need any station associated to do the attack.\n Would you want to do a Fake Auth Attack?",
  314. QMessageBox::Yes, QMessageBox::No)
  315. == QMessageBox::Yes)
  316. emit doAttackAuth(infoE->getBSSID(), "");
  317. return;
  318. }
  319. emit doAttackBroadcast(infoE->getBSSID(), infoC->getStation());
  320. }
  321. void Airodump::attackArpReplay(){
  322. logThread::addLog("Airodump: Trying to launch ARP Replay attack", logInfo::MAIN);
  323. infoConnectionBssid *infoC = this->getSelectedInfoConnectionBssid();
  324. infoESSID *infoE = this->getSelectedInfoESSID();
  325. if (infoE == NULL || infoE->getBSSID().isEmpty()){
  326. utils::mostrarMensaje("Please, select a BSSID in the up table");
  327. return;
  328. }
  329. if (infoC == NULL || !utils::validMAC(infoC->getBSSID())) { //can be (not associated)
  330. if (QMessageBox::question(this, "Message", "We need any station associated to do the attack.\nWould you want to do a Fake Auth Attack?",
  331. QMessageBox::Yes, QMessageBox::No)
  332. == QMessageBox::Yes)
  333. emit doAttackAuth(infoE->getBSSID(), "");
  334. return;
  335. }
  336. emit doAttackArpReplay(infoE->getBSSID(), infoC->getStation());
  337. }
  338. //depends of the STATE and the tables (if there are selected rows)
  339. void Airodump::enableCorrectOptions(STATUS status){
  340. if (status == STOPPED) {
  341. utils::setBackgroundColor(this->ui->lineEditStatusAirodump, utils::RED);
  342. this->ui->lineEditStatusAirodump->setText("STOPPED");
  343. //this->ui->groupBoxAttackOptions->setEnabled(false);
  344. this->ui->pushButtonCapture->setEnabled(false);
  345. this->ui->pushButtonCrack->setEnabled(false);
  346. this->ui->pushButtonStart->setEnabled(true);
  347. this->ui->pushButtonMoreInfo->setEnabled(false);
  348. this->ui->groupBoxAttackOptions->setDisabled(false);
  349. }
  350. else if (status == MONITORING) {
  351. this->ui->lineEditStatusAirodump->setText("MONITORING");
  352. utils::setBackgroundColor(this->ui->lineEditStatusAirodump, utils::YELLOW);
  353. //this->ui->groupBoxAttackOptions->setEnabled(false);// maybe we can set to true
  354. //row selected?, then active capture and crack
  355. if (!this->ui->tableWidgetAirodumpGeneral->selectedItems().isEmpty()) {
  356. this->ui->pushButtonCapture->setEnabled(true);
  357. this->ui->pushButtonCrack->setEnabled(true);
  358. }
  359. else
  360. this->ui->pushButtonCapture->setEnabled(false);
  361. //anyway pushbutton start deactivate
  362. this->ui->pushButtonStart->setEnabled(false);
  363. //if we are monitoring, we can select multi-rows
  364. this->ui->tableWidgetAirodumpAux->setSelectionMode(QAbstractItemView::MultiSelection);
  365. statusInform("Start Monitoring");
  366. this->ui->groupBoxAttackOptions->setDisabled(true);
  367. }
  368. else if (status == CAPTURING) {
  369. this->ui->lineEditStatusAirodump->setText("CAPTURING");
  370. utils::setBackgroundColor(this->ui->lineEditStatusAirodump, utils::GREEN);
  371. //select the unique row
  372. if (this->ui->tableWidgetAirodumpGeneral->selectedItems().isEmpty()) //to avoid infinite bucle between selectStationsAssociated and this
  373. this->ui->tableWidgetAirodumpGeneral->selectRow(0);
  374. this->ui->pushButtonCrack->setEnabled(true);
  375. //this->ui->groupBoxAttackOptions->setEnabled(true);
  376. this->ui->pushButtonCapture->setEnabled(false);
  377. //anyway pushbutton start deactivate
  378. this->ui->pushButtonStart->setEnabled(false);
  379. //if we are capturing, only can select one row
  380. this->ui->tableWidgetAirodumpAux->setSelectionMode(QAbstractItemView::SingleSelection);
  381. infoESSID *iaux = this->getSelectedInfoESSID();
  382. if (iaux)
  383. statusInform("Start Capturing BSSID " + iaux->getBSSID());
  384. else
  385. statusInform("Start Capturing");
  386. this->ui->groupBoxAttackOptions->setDisabled(false);
  387. }
  388. }
  389. void Airodump::attackDeauth(){
  390. logThread::addLog("Airodump: Trying to launch Deauth attack", logInfo::MAIN);
  391. infoConnectionBssid *infoC = this->getSelectedInfoConnectionBssid();
  392. infoESSID *infoE = this->getSelectedInfoESSID();
  393. if (infoE == NULL || infoE->getBSSID().isEmpty()){
  394. utils::mostrarMensaje("Please, select a BSSID in the up table");
  395. return;
  396. }
  397. //if there are a row of below selected, we already have BSSID + MAC ASSOCIATED
  398. if (infoC != NULL && !infoC->getBSSID().isEmpty())
  399. emit doAttackDeauth(infoC->getBSSID(), infoC->getStation());
  400. //if there are a row of up table selected, we have the BSSID, we can do deauth to all
  401. else if (!infoE->getBSSID().isEmpty())
  402. emit doAttackDeauth(infoE->getBSSID(), "");
  403. else //nothing selected
  404. utils::mostrarMensaje("Please, select a row of tables to attack. Below table to do Deauth to One Mac Station connected (RECOMMENDED).\n" \
  405. "Up table to do a massive deauthentication to all stations connected to that BSSID.");
  406. }
  407. void Airodump::attackAuth(){
  408. logThread::addLog("Airodump: Trying to launch Auth attack", logInfo::MAIN);
  409. infoESSID *infoE = this->getSelectedInfoESSID();
  410. if (infoE == NULL || infoE->getBSSID().isEmpty()){
  411. utils::mostrarMensaje("Please, select a BSSID in the up table");
  412. return;
  413. }
  414. //if there are a row of up table selected
  415. if (!infoE->getBSSID().isEmpty())
  416. emit doAttackAuth(infoE->getBSSID(), "");
  417. else //nothing selected
  418. utils::mostrarMensaje("Please, select a row of table to attack (BSSID)");
  419. }
  420. void Airodump::aircrack(){
  421. logThread::addLog("Airodump: Trying to launch Aircrack attack", logInfo::MAIN);
  422. infoESSID *infoE = this->getSelectedInfoESSID();
  423. if (infoE == NULL || infoE->getBSSID().isEmpty()){
  424. utils::mostrarMensaje("Please, select a BSSID in the up table");
  425. return;
  426. }
  427. //if there are a row of up table selected
  428. if (!infoE->getBSSID().isEmpty())
  429. emit doAircrack(infoE->getBSSID());
  430. else //nothing selected
  431. utils::mostrarMensaje("Please, select a row of table to attack (BSSID)");
  432. }
  433. void Airodump::selectStationsAssociated(){
  434. if (this->ui->tableWidgetAirodumpGeneral->selectedItems().isEmpty()) //FIX: to avoid crash when start with any selected row
  435. return;
  436. //since here, there are any selected row
  437. //enabling more info
  438. this->ui->pushButtonMoreInfo->setEnabled(true);
  439. //reset
  440. this->ui->tableWidgetAirodumpAux->clearSelection();
  441. //updating enabled options
  442. this->enableCorrectOptions(status);
  443. //taking BSSID to see if he have any station associated
  444. const QString BSSID = this->ui->tableWidgetAirodumpGeneral->selectedItems().at(0)->data(Qt::DisplayRole).toString();
  445. for (int i=0; i<this->ui->tableWidgetAirodumpAux->rowCount(); ++i) {
  446. //if BSSID is in the bottom table, then he has any station associated
  447. if (this->ui->tableWidgetAirodumpAux->item(i, 0)->data(Qt::DisplayRole).toString() == BSSID) {
  448. //if the row in the bottom table is not selected
  449. if (!this->ui->tableWidgetAirodumpAux->item(i, 0)->isSelected()) {
  450. this->ui->tableWidgetAirodumpAux->selectRow(i);
  451. //if we are capturing, select ONE row
  452. if (this->status == CAPTURING)
  453. return;
  454. }
  455. }
  456. }
  457. }
  458. void Airodump::newStationAppear(infoConnectionBssid infoC){
  459. logThread::addLog(QString("Airodump: NEW STATION APPEAR! Station=%1, Associated with=%2").arg(infoC.getStation()).arg(infoC.getBSSID()), logInfo::MAIN);
  460. //if we are capturing, we only select the first row in the below table
  461. //to avoid select always the last row that are being introduced below and avoid little errors
  462. if (this->status == CAPTURING) {
  463. QList<QTableWidgetItem*> selectedAUX = this->ui->tableWidgetAirodumpAux->selectedItems();
  464. if (!selectedAUX.isEmpty())
  465. return; //break function
  466. }
  467. QList<QTableWidgetItem*> selected = this->ui->tableWidgetAirodumpGeneral->selectedItems();
  468. if (selected.isEmpty()) //FIX: to avoid crash when start with any selected row
  469. return;
  470. //if the new station that appear contains a BSSID selected in the bottom table
  471. if (infoC.getBSSID() == selected.at(0)->data(Qt::DisplayRole).toString())
  472. this->ui->tableWidgetAirodumpAux->selectRow(this->ui->tableWidgetAirodumpAux->rowCount()-1);
  473. }
  474. void Airodump::newBSSIDAppear(infoESSID infoE){
  475. logThread::addLog(QString("Airodump: NEW BSSID APPEAR! BSSID=%1, ESSID=%2").arg(infoE.getBSSID()).arg(infoE.getName()), logInfo::MAIN);
  476. }
  477. void Airodump::startMonitor(bool capture){
  478. //init
  479. QString args;
  480. if (!capture)
  481. if (this->ui->spinBoxChannel->value() != 0)
  482. args += (QString)" -c " += QString::number(this->ui->spinBoxChannel->value());
  483. if (this->ui->WEP->isVisible()) {
  484. logThread::addLog(QString("Airodump: Start monitoring. WEP MODE. Capture=%1").arg(capture), logInfo::MAIN);
  485. args += (QString)" --enc wep";
  486. }
  487. else if (this->ui->WPA->isVisible()) {
  488. logThread::addLog(QString("Airodump: Start monitoring. WPA MODE"), logInfo::MAIN);
  489. args += (QString)" --enc wpa";
  490. }
  491. QString command;
  492. if (capture) {
  493. infoESSID *infoE = this->getSelectedInfoESSID();
  494. if (infoE == NULL || infoE->getBSSID().isEmpty()) {
  495. utils::mostrarError("You must specify a BSSID selecting a row of the up table");
  496. return;
  497. }
  498. /*
  499. //checking if the folder BSSID exists. If not, we create it to store there caps
  500. if (!QFile::exists(CAPTURE_FOLDER + infoE->getBSSID()))
  501. QDir::current().mkdir( QString("mkdir " + CAPTURE_FOLDER + infoE->getBSSID()).toLatin1().data() );
  502. */
  503. // in wpa no capture packets
  504. if (this->ui->WEP->isVisible()) {
  505. logThread::addLog("Airodump: WEP MODE. BSSID=" + infoE->getBSSID() + " channel=" + QString::number(infoE->getChannel()), logInfo::MAIN);
  506. command = (AIRODUMP_COM + " -c " + QString::number(infoE->getChannel()) + " --bssid " +
  507. infoE->getBSSID() + " -w " + CAPTURE_FOLDER + infoE->getBSSID()
  508. + " " + GLOBALS::INTERFACE);
  509. }
  510. else {
  511. logThread::addLog("Airodump: WPA MODE. BSSID=" + infoE->getBSSID() + " channel=" + QString::number(infoE->getChannel()), logInfo::MAIN);
  512. command = (AIRODUMP_COM + " -c " + QString::number(infoE->getChannel()) + " --bssid " +
  513. infoE->getBSSID() + " " + GLOBALS::INTERFACE);
  514. }
  515. this->ui->spinBoxChannel->setValue(infoE->getChannel());
  516. }
  517. else
  518. command = (AIRODUMP_COM + " " + args + " " + GLOBALS::INTERFACE);
  519. //stopping previus process
  520. stop();
  521. //REMOVE ANY PREVIOUS BUFFER
  522. if (QFile::exists(BUFFER_AIRODUMP_FILENAME))
  523. if (!fileM4.remove(BUFFER_AIRODUMP_FILENAME))
  524. utils::mostrarError("Error trying to remove previus .M4 file buffer");
  525. //START!
  526. process->start(command);
  527. emit toLog(command);
  528. if (!process->waitForStarted(WAIT_FOR_PROCESS))
  529. utils::mostrarError("Error al intentar ejecutar " + command);
  530. //checking errors. //Wait for reading enough information
  531. //work?
  532. QString info;
  533. //si el programa sigue corriendo despues de 1 segundos, es que ha funcionado
  534. if (process->waitForFinished(1000)) {
  535. info = process->readAllStandardOutput();
  536. if (!info.isEmpty()) {
  537. toLog(utils::htmlRojo(info));
  538. utils::mostrarError(info);
  539. }
  540. utils::mostrarError("Are you sure that you have executed Airmon-ng in options\nto put interface into Monitor Mode and select correct\
  541. interface?\nSEE LOG");
  542. //stopping
  543. this->ui->pushButtonStop->click();
  544. }
  545. else if (!this->openFileM4()){
  546. utils::mostrarError("Error trying to open .M4 file");
  547. //stopping
  548. this->ui->pushButtonStop->click();
  549. }
  550. else {
  551. //starting
  552. //init vectors
  553. this->clearInfoVectors();
  554. //clear tables
  555. this->clearTables();
  556. update();
  557. //setStatus is the latest to do (to avoid problems associated a enableCorrectOptions)
  558. if (capture)
  559. this->setStatus(CAPTURING);
  560. else
  561. this->setStatus(MONITORING);
  562. }
  563. }
  564. void Airodump::restart()
  565. {
  566. if (status != STOPPED) {
  567. logThread::addLog("Airodump: Restarting...", logInfo::MAIN);
  568. stop();
  569. start();
  570. }
  571. }
  572. void Airodump::availableLater()
  573. {
  574. utils::mostrarMensaje("Available in next version ;)");
  575. }
  576. bool Airodump::openFileM4(){
  577. logThread::addLog(QString("Airodump: Openning %1 as airodump buffer").arg(BUFFER_AIRODUMP_FILENAME), logInfo::MAIN);
  578. fileM4.setFileName(BUFFER_AIRODUMP_FILENAME);
  579. return fileM4.open(QIODevice::ReadOnly);
  580. }
  581. void Airodump::stop(){
  582. logThread::addLog("Airodump: Stopping", logInfo::MAIN);
  583. //terminating process
  584. if (process->state() == QProcess::Running) {
  585. process->terminate();
  586. //utils::killProcess(process->pid());
  587. if (!process->waitForFinished(WAIT_FOR_PROCESS))
  588. utils::mostrarError("Critical. Error trying to finalize the process airodump");
  589. statusInform("Airodump Stopped");
  590. }
  591. //closing buffer
  592. this->fileM4.close();
  593. //de-selecting tables
  594. this->ui->tableWidgetAirodumpAux->clearSelection();
  595. this->ui->tableWidgetAirodumpGeneral->clearSelection();
  596. //status
  597. this->setStatus(STOPPED);
  598. }
  599. void Airodump::update(){
  600. //taking BSSIDS
  601. convertInfo();
  602. //inserting values
  603. for (int i=0; !infoE[i].getBSSID().isEmpty(); ++i)
  604. insertRow(infoE[i], this->ui->tableWidgetAirodumpGeneral);
  605. for (int i=0; !infoC[i].getBSSID().isEmpty(); ++i)
  606. insertRow(infoC[i], this->ui->tableWidgetAirodumpAux);
  607. if (process->state() == QProcess::Running)
  608. QTimer::singleShot(TIME_UPDATE_AIRODUMP, this, SLOT(update()));
  609. }
  610. void Airodump::sort(){
  611. //activate sorting
  612. this->ui->tableWidgetAirodumpGeneral->setSortingEnabled(true);
  613. //0 = POWER
  614. //1 = Beacons
  615. //2 = ivs/s
  616. //3 = current ivs
  617. //4 = stored ivs
  618. this->ui->tableWidgetAirodumpGeneral->sortByColumn(this->ui->comboBoxSort->currentIndex() + 2, Qt::DescendingOrder);
  619. //disabling sorting
  620. this->ui->tableWidgetAirodumpGeneral->setSortingEnabled(false);
  621. }
  622. //CRITICAL FUNCTION. Convert info from buffer.
  623. int Airodump::convertInfo(){
  624. static int nInfoE, nInfoC;
  625. static QStringList fields;
  626. //close the buffer to re-read it (because it is updated all time)
  627. fileM4.close();
  628. if (!this->fileM4.open(QIODevice::ReadOnly))
  629. utils::mostrarError("Error trying to re-open .M4 to be read");
  630. //init index of vectors
  631. nInfoE = nInfoC = 0;
  632. //nothing to read?
  633. if (fileM4.readLine().isEmpty())
  634. return -1;
  635. //reading trash
  636. fileM4.readLine();
  637. //filling first table
  638. while (1) {
  639. fields = QString(fileM4.readLine()).split(',');
  640. //fields.replaceInStrings(" ", ""); // esto lo tenia puesto y no se para que
  641. if (fields.size() != 16)
  642. break;
  643. this->infoE[nInfoE].setAuth(fields.at(7));
  644. this->infoE[nInfoE].setBeacons(fields.at(9));
  645. this->infoE[nInfoE].setBSSID(fields.at(0));
  646. this->infoE[nInfoE].setChannel(fields.at(3));
  647. this->infoE[nInfoE].setCipher(fields.at(6));
  648. this->infoE[nInfoE].setData(fields.at(10));
  649. this->infoE[nInfoE].setDataS(fields.at(14));
  650. this->infoE[nInfoE].setEnc(fields.at(5));
  651. this->infoE[nInfoE].setMb(fields.at(4));
  652. this->infoE[nInfoE].setName(fields.at(13));
  653. this->infoE[nInfoE].setPower(fields.at(8));
  654. nInfoE++;
  655. }
  656. //reading trash
  657. fileM4.readLine();
  658. //filling second table
  659. while (1){
  660. fields = QString(fileM4.readLine()).split(',');
  661. fields.replaceInStrings(" ", "");
  662. if (fields.size() != 9)
  663. break;
  664. this->infoC[nInfoC].setBSSID(fields.at(5));
  665. this->infoC[nInfoC].setLost(fields.at(6));
  666. this->infoC[nInfoC].setPackets(fields.at(4));
  667. this->infoC[nInfoC].setPower(fields.at(3));
  668. this->infoC[nInfoC].setProbes(((QString)fields.at(8))); //aki hay caracteres erroneos
  669. this->infoC[nInfoC].setRate(fields.at(7));
  670. this->infoC[nInfoC].setStation(fields.at(0));
  671. nInfoC++;
  672. }
  673. return 1;
  674. }
  675. bool Airodump::insertRow(const infoConnectionBssid &infoC, QTableWidget *table){
  676. //infoC empty?
  677. if (infoC.getBSSID().isEmpty())
  678. return false;
  679. //init
  680. int index = 0;
  681. bool newStation = false;
  682. //is the infoC ALREADY in the table?
  683. for (index=0; index<table->rowCount(); ++index)
  684. //SUPER FIX!!! ROW IS NOT THE SAME IF THE STATION IS DIFFERENT!!!!!!!!!!!!1
  685. if (table->item(index,1)->text() == infoC.getStation()) //yes, it is. We store the index
  686. break;
  687. //no, it is not, insert new row.
  688. if (index == table->rowCount()) {
  689. QProgressBar *p = new QProgressBar(this); //is sure that we destroy it?
  690. table->insertRow(index);
  691. table->setCellWidget(index, 2, p);
  692. p->setValue(0);
  693. newStation = true;
  694. }
  695. //insert items of row
  696. table->setItem(index, 0, utils::toItem(infoC.getBSSID()));
  697. table->setItem(index, 1, utils::toItem(infoC.getStation()));
  698. ((QProgressBar *)table->cellWidget(index,2))->setValue(infoC.getPower());
  699. table->setItem(index, 2, utils::toItem(infoC.getPower())); //we need to insert also this item to can sorting by it
  700. table->setItem(index, 3, utils::toItem(infoC.getRate()));
  701. table->setItem(index, 4, utils::toItem(infoC.getLost()));
  702. table->setItem(index, 5, utils::toItem(infoC.getPackets()));
  703. table->setItem(index, 6, utils::toItem(infoC.getProbes()));
  704. if (newStation) //new station is entered
  705. emit stationAppear(infoC);
  706. //all correct
  707. return true;
  708. }
  709. bool Airodump::insertRow(const infoESSID &info, QTableWidget *table){
  710. //info empty?
  711. if (info.getBSSID().isEmpty())
  712. return false;
  713. //init
  714. int index = 0;
  715. bool newBSSID = false;
  716. //is the info ALREADY in the table?
  717. for (index=0; index<table->rowCount(); ++index)
  718. if (table->item(index,0)->text() == info.getBSSID()) //yes, it is. We store the index
  719. break;
  720. //no, it is not, insert new row.
  721. if (index == table->rowCount()) {
  722. QProgressBar *p = new QProgressBar(this); //is sure that we destroy it?, SI CREO QUE SE DESTRUYE, porque el padre lo destruye cuando muere.
  723. table->insertRow(index);
  724. table->setCellWidget(index, 2, p);
  725. //inserting ONE TIME stored IVS
  726. table->setItem(index, 6, utils::toItem(histAux->getStoredIvs(info.getBSSID())));
  727. newBSSID = true;
  728. }
  729. //insert items of row
  730. table->setItem(index, 0, utils::toItem(info.getBSSID()));
  731. table->setItem(index, 1, utils::toItem(info.getName()));
  732. ((QProgressBar *)table->cellWidget(index,2))->setValue(info.getPowerConverted());
  733. table->setItem(index, 2, utils::toItem(info.getPowerConverted())); //we need to insert also this item to can sorting by it
  734. table->setItem(index, 3, utils::toItem(info.getBeacons()));
  735. table->setItem(index, 4, utils::toItem(info.getDataS()));
  736. table->setItem(index, 5, utils::toItem(info.getData()));
  737. table->setItem(index, 7, utils::toItem(info.getChannel()));
  738. table->setItem(index, 8, utils::toItem(info.getEnc()));
  739. if (newBSSID)
  740. emit BSSIDAppear(info);
  741. return true;
  742. }
  743. infoESSID* Airodump::getSelectedInfoESSID(){
  744. QList<QTableWidgetItem*> items = this->ui->tableWidgetAirodumpGeneral->selectedItems(); //one row
  745. if (items.isEmpty()) //no selection?
  746. return NULL;
  747. for (int i=0; i < MAX_ESSID && this->infoE[i].getBSSID() != ""; ++i)
  748. if (items.at(0)->text() == this->infoE[i].getBSSID())
  749. return &this->infoE[i];
  750. utils::mostrarError("Maximum of ESSID reached, limit is " + MAX_ESSID);
  751. //FIX CRITICAL BUG [thx drvalium]. WHEN LIMIT IS REACHED, RETURN NULL
  752. return NULL;
  753. }
  754. infoConnectionBssid* Airodump::getSelectedInfoConnectionBssid(){
  755. QList<QTableWidgetItem*> items = this->ui->tableWidgetAirodumpAux->selectedItems(); //one row
  756. if (items.isEmpty()) //no selection?
  757. return NULL;
  758. //FIX SUPER BUG 0.6.8: BSSID COULD BE THE SAME (MANY STATIONS ASSOCIATED TO HIM)
  759. //BUT WE HAVE TO CHOOSE THE SELECTED ROW
  760. //BEFORE WE SELECTED RANDOM STATION ASSOCIATED, NOT THE SELECTED ONE
  761. for (int i=0; i<MAX_BSSID_CON && this->infoC[i].getBSSID() != ""; ++i)
  762. if (items.at(1)->text() == this->infoC[i].getStation())
  763. return &this->infoC[i];
  764. utils::mostrarError("Maximum of ESSID-Stations associated reached, limit is " + MAX_BSSID_CON);
  765. return NULL;
  766. }
  767. void Airodump::clearInfoVectors(){
  768. infoE.clear();
  769. infoC.clear();
  770. }
  771. void Airodump::clearTables(){
  772. while (this->ui->tableWidgetAirodumpAux->rowCount() > 0)
  773. this->ui->tableWidgetAirodumpAux->removeRow(this->ui->tableWidgetAirodumpAux->rowCount()-1);
  774. while (this->ui->tableWidgetAirodumpGeneral->rowCount() > 0)
  775. this->ui->tableWidgetAirodumpGeneral->removeRow(this->ui->tableWidgetAirodumpGeneral->rowCount()-1);
  776. }