Детектор RubberDucky


RubberDucky, который будет выглядеть как обычный USB-накопитель, но он будет действовать как устройство keystorke.

Эта программа на языке C++ поможет вам найти, является ли подключенное устройство вообще устройства USB вообще-то USB-устройство или ключ инжектор хода(резиновая уточка)

Что эта программа делает: при запуске программы это измерять количество USB-устройств и он будет измерять количество устройств ввода. При вставке USB-накопителя есть количество USB-накопитель будет увеличиваться, так он будет информировать пользователя о том, что подключенное устройство является USB-устройством. Если резиновая уточка вставляется(хотя он выглядит как USB-это ключевое устройство, поглаживание) устройства ввода количество будет увеличиваться, так он будет информировать пользователя о том, что подключенное устройство является Рубер Даки.

Вот .файл HPP

// SWAMI KARUPPASWAMI THUNNAI
#ifndef RUBBERDUCKYDETECTOR_HPP
#define RUBBERDUCKYDETECTOR_HPP

#include <QDialog>
#include <QtConcurrent>

namespace Ui {
class RubberDuckyDetector;
}

class RubberDuckyDetector : public QDialog
{
    Q_OBJECT

public:
    explicit RubberDuckyDetector(QWidget *parent = 0);
    ~RubberDuckyDetector();
public slots:
    /**
     * @brief checkPresenceOfKeyStrokeInjector This method is actually used to detect the presence
     * of malicious devices like rubber ducky. [RUN THIS SLOT AS A SEPERATE THREAD]
     */
    void checkPresenceOfKeyStrokeInjector();
    /**
     * @brief informKeystrokeInjector This slot will inform the user that the keystroke injector has
     * been inserted.
     */
    void informKeystrokeInjector();
    /**
     * @brief informUSBDrive This method is used to inform the presence of USB device
     */
    void informUSBDrive();
signals:
    /**
     * @brief driveIsKeyStrokeInjector This signal will be emitted if the connected
     * input drive is actually a KeyStroke injector
     */
    void driveIsKeyStrokeInjector();
    /**
     * @brief driveIsUSB This method will check if the drive is a USB device or not.
     */
    void driveIsUSB();

private:
    Ui::RubberDuckyDetector *ui;

    // Initial no of USB drives present in the computer
    volatile int initial_usbDrivesCount = 0;
    // Initial no of Input devices present in the computer
    volatile int initial_inputDevicesCount = 0;
    // A thread to check for the keystroke injector
    QFuture<void> checkForKeyStrokeInjectoThread;
    // The state of the thread [RUNNING/TERMINATED]
    volatile bool running = true;
    // Private method declarations

    /**
     * @brief getCountOfUSBDevices This method will get the total no of usb drives present in the system
     * @returns the total no of usb drives
     */
    int getCountOfUSBDevices();
    /**
     * @brief getCountOfInputDevices This method will be useful to get the count of input devices
     * @return count of input devices
     */
    int getCountOfInputDevices();

};

#endif // RUBBERDUCKYDETECTOR_HPP

А .файл cpp

// SWAMI KARUPPASWAMI THUNNAI
#include "rubberduckydetector.hpp"
#include "ui_rubberduckydetector.h"
#include <QFileInfo>
#include <QDir>
#include <Windows.h>
#include <WinUser.h>
#include <QMessageBox>
#include <QException>

RubberDuckyDetector::RubberDuckyDetector(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::RubberDuckyDetector)
{
    ui->setupUi(this);
    // Initialize the count of usb drives
    initial_usbDrivesCount = getCountOfUSBDevices();
    initial_inputDevicesCount = getCountOfInputDevices();
    checkForKeyStrokeInjectoThread = QtConcurrent::run(this, &RubberDuckyDetector::checkPresenceOfKeyStrokeInjector);
    connect(this, SIGNAL(driveIsKeyStrokeInjector()), this, SLOT(informKeystrokeInjector()));
    connect(this, SIGNAL(driveIsUSB()), this, SLOT(informUSBDrive()));
 }

RubberDuckyDetector::~RubberDuckyDetector()
{
    running = false;
    checkForKeyStrokeInjectoThread.cancel();
    checkForKeyStrokeInjectoThread.waitForFinished();
    delete ui;
}
//=========================================================
//          PRIVATE METHOD DEFINITIONS
//=========================================================
int RubberDuckyDetector::getCountOfUSBDevices()
{
    int totalRemovableDrives = 0;
    QDir driveList;
    for(QFileInfo drive : driveList.drives())
    {
        QString driveLetter = drive.absoluteFilePath();
        LPCWSTR driveType = (const wchar_t*) driveLetter.utf16();
        if(GetDriveType(driveType) == 2)
        {
            totalRemovableDrives++;
        }
    }
    return totalRemovableDrives;
}

int RubberDuckyDetector::getCountOfInputDevices()
{
    try{
    UINT totalDevices;
    GetRawInputDeviceList(NULL, &totalDevices, sizeof(RAWINPUTDEVICELIST));
    return totalDevices;
    }
    catch(...){return 0;}
}

//=========================================================
//        PUBLIC SLOT DEFINITIONS
//=========================================================

void RubberDuckyDetector::checkPresenceOfKeyStrokeInjector()
{
    while(running)
    {
        try{
            // Once a new device is inserted
            int keystrokeDeviceCount = getCountOfInputDevices();
            // If the input devices count increses then it is a keystroking device
            if(keystrokeDeviceCount>initial_inputDevicesCount)
            {
                emit driveIsKeyStrokeInjector();
                initial_inputDevicesCount = keystrokeDeviceCount;
            }
            // If decreases user has unplugged an input device
            if(keystrokeDeviceCount<initial_inputDevicesCount)
            {
                initial_inputDevicesCount = keystrokeDeviceCount;
            }
            int usbDeviceCount = getCountOfUSBDevices();
            // If the usb devices count increases then it is a USB device
            if(usbDeviceCount>initial_usbDrivesCount)
            {
                emit driveIsUSB();
                initial_usbDrivesCount = usbDeviceCount;
            }
            // If decreases user has unplugged an USB device
            if(usbDeviceCount<initial_usbDrivesCount)
            {
                initial_usbDrivesCount = usbDeviceCount;
            }
        } catch(...){}
    }
}

void RubberDuckyDetector::informKeystrokeInjector()
{
    QMessageBox::critical(this, "CRITICAL", "You have inserted a keystroke injector");
}

void RubberDuckyDetector::informUSBDrive()
{
    QMessageBox::information(this, "INFORMATION", "You have inserted a USB device");
}

Посмотреть весь проект: https://github.com/VISWESWARAN1998/CyberGod-KSGMPRH

Программа будет выглядеть следующим образом:

enter image description here



157
4
задан 11 марта 2018 в 04:03 Источник Поделиться
Комментарии
1 ответ

У вас есть гонки данных в коде. Вы получите доступ к running чтение и письмо. volatile не значит, многопотоковое исполнение. Таким образом, ваш код экспонатов неопределенное поведение.


Ни getCountOfUSBDevices ни getCountOfInputDevices должны быть связаны с RubberDuckyDetector. Они могут быть static или—еще лучше—свободный стоящий функций.


Если можно использовать C++11 особенности connect вместо SLOT и SIGNAL:

connect(this, &RubberDuckyDetector::driveIsKeyStrokeInjector, 
this, &RubberDuckyDetector::informKeystrokeInjector);
connect(this, &RubberDuckyDetector::driveIsUSB,
this, &RubberDuckyDetector::informUSBDrive);

Это позволит компилятору проверить, есть ли сигнал и слот существует) и Б) являются совместимыми.


Для удаления данных гонок checkForKeyStrokeInjectoThread есть checkPresenceOfKeyStrokeInjector принимать два аргумента. Тогда вам не придется хранить initial_usbDrivesCount в вашем классе вообще.


Вы переключаете именования. initial_usbDrivesCount как camelCase и python_case.


Это личные предпочтения, но если вы разместите в комментариях Doxygen в реализации, заголовок становится намного меньше и легче читать, например

namespace Ui {
class RubberDuckyDetector;
}

int getCountOfUSBDevices();
int getCountOfInputDevices();

class RubberDuckyDetector : public QDialog
{
Q_OBJECT

public:
explicit RubberDuckyDetector(QWidget *parent = 0);
~RubberDuckyDetector();
public slots:
void checkPresenceOfKeyStrokeInjector(int initial_usb, int initial_input);
void informKeystrokeInjector();
void informUSBDrive();
signals:
void driveIsKeyStrokeInjector();
void driveIsUSB();

private:
Ui::RubberDuckyDetector *ui; //!< User interface handle.

QFuture<void> checkForKeyStrokeInjectoThread; //!< concurrent keystroke thread
QAtomicInt running = 1; //!< the state of the thread [RUNNING/TERMINATED]
};

Таким образом, вы также более правоподобны для того чтобы расширить документации в файл реализации, а не только краткий комментарий:

/**
* @brief Perpetually checks changes in the count of USB devices.
* @param initial_usb must be the count of initial usb devices
* @param initial_input must be the count of initial input devices
*
* This method should get run in a separate thread, as it will not exit
* as long as `running.load()` does not return `0`. Use an `std::thread`,
* `QConcurrent::run` or `QThread`, for example:
*
* @code
* QConcurrent::run(this, &RubberDuckyDetector::checkPresenceOfKeyStrokeInjector,
* getCountOfUSBDevices(), getCountOfInputDevices());
* @endcode
*
* RubberDuckyDetector's destructor will set `running` to `0`, so destroy
* the RubberDuckyDetector instance if you do not want to continue.
*
* @sa RubberDuckyDetector::~RubberDuckyDetector()
* @sa getCountOfUSBDevices()
* @sa getCountOfInputDevices()
*/

void RubberDuckyDetector::checkPresenceOfKeyStrokeInjector(int initial_usb, int initial_input)
{
while(running.load())
{
...
}
}

Кроме того, вам не придется перекомпилировать все файлы в зависимости от того, для того, чтобы улучшить документацию.

3
ответ дан 11 марта 2018 в 07:03 Источник Поделиться