Replace sendkeys with keylogger
This commit is contained in:
parent
75907dff43
commit
d48ca89d20
@ -16,7 +16,7 @@ When the GoSmartKeyboard client is started, it does the following:
|
|||||||
if len(os.Args) > 1 {
|
if len(os.Args) > 1 {
|
||||||
@{get client fifo input file from environment}
|
@{get client fifo input file from environment}
|
||||||
@{setup client}
|
@{setup client}
|
||||||
if clientFifoInputFileExists {
|
if clientFifoInputFileEnvExists {
|
||||||
@{start client with fifo}
|
@{start client with fifo}
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
@ -97,6 +97,8 @@ if !strings.HasPrefix(connectionURL, "ws://") && !strings.HasPrefix(connectionUR
|
|||||||
|
|
||||||
var inputString string
|
var inputString string
|
||||||
|
|
||||||
|
syscall.Mkfifo(clientFifoInputFile, syscall.S_IFIFO|0666)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
input, err := ioutil.ReadFile(clientFifoInputFile)
|
input, err := ioutil.ReadFile(clientFifoInputFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -118,7 +120,6 @@ for {
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Sending keys from stdin
|
## Sending keys from stdin
|
||||||
|
|
||||||
|
|
||||||
@ -187,6 +188,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"syscall"
|
||||||
"io"
|
"io"
|
||||||
"bufio"
|
"bufio"
|
||||||
"log"
|
"log"
|
||||||
|
@ -24,14 +24,13 @@ We use sha3 to hash authentication tokens. It is not in the crypto standard libr
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# sendkeys
|
# keylogger
|
||||||
|
|
||||||
|
We use keylogger to get keyboard input on the client and simulate keystrokes on the server.
|
||||||
|
|
||||||
In order to avoid coding key press simulation for every major platform, we use [sendkeys](https://github.com/yunginnanet/sendkeys). This is a cross-platform library that uses the OS's native key press simulation using [keybd_event](https://github.com/micmonay/keybd_event)
|
--- keylogger import string
|
||||||
|
|
||||||
--- sendkeys import string
|
"github.com/MarinX/keylogger"
|
||||||
|
|
||||||
"github.com/EgosOwn/sendkeys"
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ Some users may always want xdotool, see the [Streaming.md](Streaming.md) file fo
|
|||||||
|
|
||||||
``` go
|
``` go
|
||||||
--- always use xdotool environment variable
|
--- always use xdotool environment variable
|
||||||
var alwaysUseXdotool := false
|
var alwaysUseXdotool = false
|
||||||
alwaysUseXdotoolEnv, alwaysUseXdotoolExists := os.LookupEnv("KEYBOARD_ALWAYS_USE_XDOTOOL")
|
alwaysUseXdotoolEnv, alwaysUseXdotoolExists := os.LookupEnv("KEYBOARD_ALWAYS_USE_XDOTOOL")
|
||||||
if alwaysUseXdotoolExists {
|
if alwaysUseXdotoolExists {
|
||||||
if alwaysUseXdotoolEnv == "true" || alwaysUseXdotoolEnv == "1" {
|
if alwaysUseXdotoolEnv == "true" || alwaysUseXdotoolEnv == "1" {
|
||||||
@ -46,7 +46,7 @@ authTokenInput, authTokenInputExists := os.LookupEnv("KEYBOARD_AUTH")
|
|||||||
|
|
||||||
--- get client fifo input file from environment
|
--- get client fifo input file from environment
|
||||||
|
|
||||||
clientFifoInputFile, clientFifoInputFileExists := os.LookupEnv("KEYBOARD_FIFO")
|
clientFifoInputFile, clientFifoInputFileEnvExists := os.LookupEnv("KEYBOARD_FIFO")
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -1,39 +1,25 @@
|
|||||||
# Send keys streaming approach
|
# uinput streaming approach
|
||||||
|
|
||||||
When applicable to use send keys, we need to detect Enter, Tab, and BackSpace and use the applicatble functions.
|
|
||||||
|
|
||||||
We test if it meets the characterRegex, and if so we iterate for each character and send the corresponding key.
|
|
||||||
Otherwise we send the entire string at once.
|
|
||||||
|
|
||||||
``` go
|
``` go
|
||||||
--- do streaming sendkeys approach
|
--- do streaming keylogger approach
|
||||||
if characterRegex.MatchString(message_string) {
|
|
||||||
for _, character := range message_string {
|
key := ""
|
||||||
charString := string(character)
|
if strings.HasPrefix(message_string, "{KEYDWN}") {
|
||||||
if charString == "\n" {
|
key = strings.TrimPrefix(string(message_string), "{KEYDWN}")
|
||||||
keyboard.Enter()
|
k.Write(1, key)
|
||||||
continue
|
} else if strings.HasPrefix(message_string, "{KEYUP}") {
|
||||||
}
|
key = strings.TrimPrefix(string(message_string), "{KEYUP}")
|
||||||
if charString == "\t" {
|
k.Write(0, key)
|
||||||
keyboard.Tab()
|
} else{
|
||||||
continue
|
for _, key := range message_string {
|
||||||
}
|
// write once will simulate keyboard press/release, for long press or release, lookup at Write
|
||||||
if charString == "\b" {
|
k.WriteOnce(string(key))
|
||||||
keyboard.BackSpace()
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
err = keyboard.Type(charString)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("type:", err)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
continue
|
|
||||||
}
|
|
||||||
err = keyboard.Type(message_string)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("type:", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```
|
```
|
@ -68,7 +68,7 @@ import(
|
|||||||
"log"
|
"log"
|
||||||
"keyboard.voidnet.tech/auth"
|
"keyboard.voidnet.tech/auth"
|
||||||
@{gorilla/websocket import string}
|
@{gorilla/websocket import string}
|
||||||
@{sendkeys import string}
|
@{keylogger import string}
|
||||||
)
|
)
|
||||||
|
|
||||||
var listener net.Listener
|
var listener net.Listener
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
We use the Gorilla websocket library to handle the websocket connection.
|
We use the Gorilla websocket library to handle the websocket connection.
|
||||||
|
|
||||||
Most of the time, we can use sendkeys (which uses libinput) to effeciently press keys. However, if we need to send a character that sendkeys doesn't know about, we can use the xdotool command. xdotool is also useful if one does not want to use root.
|
Most of the time, we can use the keylogger library (which uses uinput) to effeciently press keys. However, if we need to send a character that keylogger doesn't know about, we can use the xdotool command. xdotool is also useful if one does not want to use root.
|
||||||
|
|
||||||
xdotool spawns a new process for each keypress, so it's not as effecient as sendkeys.
|
xdotool spawns a new process for each keypress, so it's not as effecient as keylogger.
|
||||||
|
|
||||||
To specify xdotool usage, the client should send a message with the format `{kb_cmd:xdotool}:message` where message is a utf-8 string.
|
To specify xdotool usage, the client should send a message with the format `{kb_cmd:xdotool}:message` where message is a utf-8 string.
|
||||||
|
|
||||||
@ -14,7 +14,20 @@ To specify xdotool usage, the client should send a message with the format `{kb_
|
|||||||
func clientConnected(w http.ResponseWriter, r *http.Request) {
|
func clientConnected(w http.ResponseWriter, r *http.Request) {
|
||||||
// regex if string has characters we need to convert to key presses
|
// regex if string has characters we need to convert to key presses
|
||||||
characterRegex, _ := regexp.Compile(`[^\x08]\x08|\t|\n`)
|
characterRegex, _ := regexp.Compile(`[^\x08]\x08|\t|\n`)
|
||||||
keyboard, err := sendkeys.NewKBWrapWithOptions(sendkeys.Noisy)
|
|
||||||
|
// find keyboard device, does not require a root permission
|
||||||
|
keyboard := keylogger.FindKeyboardDevice()
|
||||||
|
|
||||||
|
// check if we found a path to keyboard
|
||||||
|
if len(keyboard) <= 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
k, err := keylogger.New(keyboard)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer k.Close()
|
||||||
|
|
||||||
@{always use xdotool environment variable}
|
@{always use xdotool environment variable}
|
||||||
|
|
||||||
@ -84,7 +97,7 @@ doXDoTool := func(command string, keys string)(err error) {
|
|||||||
|
|
||||||
@{handle xdotoool commands}
|
@{handle xdotoool commands}
|
||||||
|
|
||||||
@{do streaming sendkeys approach}
|
@{do streaming keylogger approach}
|
||||||
|
|
||||||
---
|
---
|
||||||
```
|
```
|
@ -19,7 +19,7 @@ import (
|
|||||||
|
|
||||||
func main(){
|
func main(){
|
||||||
var input string
|
var input string
|
||||||
@{get client fifo input file from environment}
|
@{get client input file from environment}
|
||||||
if ! clientFifoInputFileExists {
|
if ! clientFifoInputFileExists {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user