检测USB硬件键盘记录器

时间:2015-08-03 21:28:07

标签: c++ usb hardware libusb keylogger

我需要确定是否有使用USB键盘插入PC的硬件键盘记录器。它需要通过软件方法,从用户土地完成。但是wiki说使用soft检测HKL是不可能的,有几种方法存在。最好的,我认为只有一个与网络相关的概念是#34;检测硬件键盘记录,由Fabian Mihailowi​​tsch撰写 - youtube"。

使用此概述我正在开发一种检测USB硬件键盘记录器的工具。用于检测PS / 2键盘记录器的源已经由作者共享且可用here。所以我的任务是让它只适用于USB。

正如我所建议的那样,我使用libusb库来干扰系统中的USB设备。

所以,我选择了一些方法来检测HKL:

  1. 找到HKL窃听的USB键盘。请注意HKL通常是 从系统中的设备列表中不可见或由libusb返回。
  2. 通过以下方式检测Keyghost HKL:从USB HID设备中断读取,发送usb reset(libusb_reset_device),再次读取中断。如果上次读取时返回的数据不为空,则检测到键盘记录。 Mihailowitsch's presentation
  3. 的第45页对此进行了描述
  4. 时间测量。这个想法是使用原始键盘的控制传输测量发送/接收数据包的时间数千次。如果已插入HKL,程序将再次测量时间,然后将时间与原始值进行比较。对于HKL来说,它必须更多(或不那么多)。 算法是:
    • 向键盘发送输出报告(作为控制转移)(HID_REPORT_TYPE_OUTPUT 0x02)
    • 等待确认数据包
    • 重复循环(10.000次)
    • 测量时间
  5. 根据检测步骤,下面是我的代码。

    1。查找USB键盘

    libusb_device * UsbKeyboard::GetSpecifiedDevice(PredicateType pred)
    {
        if (_usbDevices == nullptr) return nullptr;
        int i = 0;
        libusb_device *dev = nullptr;
        while ((dev = _usbDevices[i++]) != NULL)
        {
            struct libusb_device_descriptor desc;
            int r = libusb_get_device_descriptor(dev, &desc);
            if (r >= 0)
            {
                if (pred(desc))
                    return dev;
            }
        }
    
        return nullptr;
    }
    
    libusb_device * UsbKeyboard::FindKeyboard()
    {
        return GetSpecifiedDevice([&](libusb_device_descriptor &desc) {
            bool isKeyboard = false;
            auto dev_handle = libusb_open_device_with_vid_pid(_context, desc.idVendor, desc.idProduct);     
            if (dev_handle != nullptr)
            {
                unsigned char buf[255] = "";
    
                // product description contains 'Keyboard', usually string is 'USB Keyboard'            
                if (libusb_get_string_descriptor_ascii(dev_handle, desc.iProduct, buf, sizeof(buf)) >= 0)
                    isKeyboard = strstr((char*)buf, "Keyboard") != nullptr;
                libusb_close(dev_handle);           
            }
    
            return isKeyboard;
        });
    }
    

    在这里,我们重复遍历系统中的所有USB设备并检查其产品字符串。在我的系统中,这个用于键盘的字符串是' USB键盘' (明显)。 通过Product string检测键盘是否稳定?还有其他方法吗?

    2。使用中断读取检测Keyghost HKL

    int UsbKeyboard::DetectKeyghost(libusb_device *kbdev)
    {
        int r, i;
    
        int transferred;
        unsigned char answer[PACKET_INT_LEN];
        unsigned char question[PACKET_INT_LEN];
        for (i = 0; i < PACKET_INT_LEN; i++) question[i] = 0x40 + i;
        libusb_device_handle *devh = nullptr;
        if ((r = libusb_open(kbdev, &devh)) < 0)
        {
            ShowError("Error open device", r);
            return r;
        }
    
        r = libusb_set_configuration(devh, 1);
        if (r < 0)
        {
            ShowError("libusb_set_configuration error ", r);
            goto out;
        }
        printf("Successfully set usb configuration 1\n");
    
        r = libusb_claim_interface(devh, 0);
        if (r < 0)
        {
            ShowError("libusb_claim_interface error ", r);
            goto out;
        }
    
        r = libusb_interrupt_transfer(devh, 0x81 , answer, PACKET_INT_LEN,  
                    &transferred, TIMEOUT);
        if (r < 0) 
        {
            ShowError("Interrupt read error ", r);
            goto out;
        }
        if (transferred < PACKET_INT_LEN) 
        {
            ShowError("Interrupt transfer short read %", r);
            goto out;
        }
    
        for (i = 0; i < PACKET_INT_LEN; i++) {
            if (i % 8 == 0)
                printf("\n");
            printf("%02x, %02x; ", question[i], answer[i]);
        }
        printf("\n");
    
    out:
        libusb_close(devh);
        return 0;
    }
    

    我在libusb_interrupt_transfer上遇到了这样的错误:

    libusb: error [hid_submit_bulk_transfer] HID transfer failed: [5] Access denied
    Interrupt read error  - Input/Output Error (LIBUSB_ERROR_IO) (GetLastError() - 1168)
    

    不知道为什么&#39;访问被拒绝&#39;,然后IO错误,GetLastError()返回1168,这意味着 - 找不到元素(什么元素?)。在这里寻求帮助。

    1. 时间测量。发送输出报告并等待ACK数据包。

      int UsbKeyboard :: SendOutputReport(libusb_device * kbdev) {     const int PACKET_INT_LEN = 1;     int r,i;     unsigned char answer [PACKET_INT_LEN];     unsigned char question [PACKET_INT_LEN];     for(i = 0; i&lt; PACKET_INT_LEN; i ++)question [i] = 0x30 + i;     for(i = 1; i&lt; PACKET_INT_LEN; i ++)answer [i] = 0;

      libusb_device_handle *devh = nullptr;
      if ((r = libusb_open(kbdev, &devh)) < 0)
      {
          ShowError("Error open device", r);
          return r;
      }
      
      r = libusb_set_configuration(devh, 1);
      if (r < 0) 
      {
          ShowError("libusb_set_configuration error ", r);
          goto out;
      }
      printf("Successfully set usb configuration 1\n");
      
      r = libusb_claim_interface(devh, 0);
      if (r < 0) 
      {
          ShowError("libusb_claim_interface error ", r);      
          goto out;
      }
      printf("Successfully claim interface\n");   
      
      r = libusb_control_transfer(devh, CTRL_OUT, HID_SET_REPORT, (HID_REPORT_TYPE_OUTPUT << 8) | 0x00, 0, question, PACKET_INT_LEN, TIMEOUT);
      if (r < 0) {
          ShowError("Control Out error ", r);
          goto out;
      }
      
      r = libusb_control_transfer(devh, CTRL_IN, HID_GET_REPORT, (HID_REPORT_TYPE_INPUT << 8) | 0x00, 0, answer, PACKET_INT_LEN, TIMEOUT);
      if (r < 0) {
          ShowError("Control In error ", r);
          goto out;
      }    
      

      出:     libusb_close(devh);     返回0; }

    2. 与读取中断相同的错误:     控制输出错误 - 输入/输出错误(LIBUSB_ERROR_IO)(GetLastError() - 1168     )

      如何解决?如何等待ACK数据包?

      谢谢。

      更新
      我花了一天时间进行搜索和重新调整。所以目前我的问题只是 通过libusb_control_transfer发送输出报告。由于Windows拒绝使用ReadFile从USB设备读取访问权限,因此无需实现具有中断读取的第二种方法。 它只剩下libusb的东西,这是我想要编写的代码(来自第3个例子):

      // sending Output report (LED)
      // ...
          unsigned char buf[65]; 
              buf[0] = 1; // First byte is report number
              buf[1] = 0x80;
      
              r = libusb_control_transfer(devh, CTRL_OUT,
                  HID_SET_REPORT/*0x9*/, (HID_REPORT_TYPE_OUTPUT/*0x2*/ << 8) | 0x00,
                  0, buf, (uint16_t)2, 1000);
          ...
      

      我遇到的错误:

      [ 0.309018] [00001c0c] libusb: debug [_hid_set_report] Failed to Write HID Output Report: [1] Incorrect function
      Control Out error  - Input/Output Error (LIBUSB_ERROR_IO) (GetLastError() - 1168)
      

      在libusb内部中 DeviceIoControl 调用后立即发生此错误。 什么意思&#34;不正确的功能&#34;那里?

0 个答案:

没有答案