Compare commits

..

No commits in common. "a2e9ce6aeb8c9b7fe9bf08f16d8cabc33003da8f" and "3d9a31f4af05adb71a7be368307554a4e8b86450" have entirely different histories.

9 changed files with 34 additions and 73 deletions

View File

@ -7,11 +7,12 @@ When the GoSmartKeyboard client is started, it does the following:
3. Connect to the server. 3. Connect to the server.
4 Send the auth token to the server. 4 Send the auth token to the server.
5. If the server responds with "authenticated", we start reading keys from stdin and sending them to the server until EOF. 5. If the server responds with "authenticated", we start reading keys from stdin and sending them to the server until EOF.
5.1 If the environment variable `KEYBOARD_FIFO` is set, we read from the path specified there instead as a named pipe. 6. If KEYBOARD_FIFO is specified as an environment variable, we read from the path specified there instead as a named pipe.
5.2 Regardless, each message is sent to the server with the prefix `@{payload delimiter}`.
``` go ``` go
--- handle client command --- handle client command
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}
@ -35,7 +36,6 @@ The base64 authentication token is loaded from the environment variable `KEYBOAR
--- setup client --- setup client
@{handle version command}
@{load connection URL from second CLI argument} @{load connection URL from second CLI argument}
@{get authTokenInput from environment} @{get authTokenInput from environment}
@{add xdotool if non qwerty function} @{add xdotool if non qwerty function}
@ -91,24 +91,23 @@ if !strings.HasPrefix(connectionURL, "ws://") && !strings.HasPrefix(connectionUR
## Sending keys from a named pipe ## Sending keys from a named pipe
We create a fifo and then continuously read from it in a loop.
``` go ``` go
--- start client with fifo --- start client with fifo
var inputString string
syscall.Mkfifo(clientFifoInputFile, syscall.S_IFIFO|0666) syscall.Mkfifo(clientFifoInputFile, syscall.S_IFIFO|0666)
inputString := ""
for { for {
readData, err := ioutil.ReadFile(clientFifoInputFile) input, err := ioutil.ReadFile(clientFifoInputFile)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
inputString = addXDoToolIfNonQWERTY(string(input))
inputString = addXDoToolIfNonQWERTY(string(readData)) input = []byte(inputString)
input := []byte(inputString)
if len(input) > 0 { if len(input) > 0 {
fmt.Println("send" + strings.Replace(string(input), " ", "space", 10))
err = client.WriteMessage(websocket.TextMessage, input) err = client.WriteMessage(websocket.TextMessage, input)
if err != nil { if err != nil {
log.Fatal("write:", err) log.Fatal("write:", err)
@ -147,6 +146,7 @@ for {
} }
log.Fatal(err) log.Fatal(err)
} }
fmt.Println("send" + strings.Replace(key, " ", "space", 10))
err = client.WriteMessage(websocket.TextMessage, []byte(key)) err = client.WriteMessage(websocket.TextMessage, []byte(key))
if err != nil { if err != nil {
log.Fatal("write:", err) log.Fatal("write:", err)
@ -164,13 +164,13 @@ for {
--- add xdotool if non qwerty function --- noWeave --- add xdotool if non qwerty function --- noWeave
addXDoToolIfNonQWERTY := func(message string)(string) { addXDoToolIfNonQWERTY := func(message string)(string) {
if strings.HasPrefix(message, "@{use xdotool cmd}") { if strings.HasPrefix(message, "{kb_cmd:xdotool}:") {
return message return message
} }
for _, char := range message { for _, char := range message {
if char < 32 || char > 126 { if char < 32 || char > 126 {
if char != 8 && char != 9 && char != 10 { if char != 8 && char != 9 && char != 10 {
return "@{use xdotool cmd}" + message return "{kb_cmd:xdotool}:" + message
} }
} }
} }

View File

@ -1,13 +1,11 @@
weave: weave:
srcweave --formatter srcweave-format --weave docs/ ReadMe.md Building.md Dependencies.md EnvironmentVariables.md LICENSE.md \ srcweave --formatter srcweave-format --weave docs/ ReadMe.md Building.md Dependencies.md EnvironmentVariables.md LICENSE.md \
security/Authentication.md security/ThreatModel.md Plumbing.md server/Server.md server/Streaming.md server/Sendkeys.md server/XdotoolCommands.md \ security/Authentication.md security/ThreatModel.md Plumbing.md server/Server.md server/Streaming.md server/Sendkeys.md server/XdotoolCommands.md \
server/StringCommands.md
Client.md tools/Tools.md tools/Editor.md tools/Input.md tools/RawCapture.md tools/TUI.md Client.md tools/Tools.md tools/Editor.md tools/Input.md tools/RawCapture.md tools/TUI.md
util/clean.py util/clean.py
tangle: tangle:
srcweave --formatter srcweave-format --tangle smartkeyboard/ ReadMe.md Plumbing.md security/Authentication.md EnvironmentVariables.md Dependencies.md \ srcweave --formatter srcweave-format --tangle smartkeyboard/ ReadMe.md Plumbing.md security/Authentication.md EnvironmentVariables.md Dependencies.md \
server/Server.md server/Streaming.md server/Sendkeys.md server/XdotoolCommands.md server/StringCommands.md \ server/Server.md server/Streaming.md server/Sendkeys.md server/XdotoolCommands.md security/ThreatModel.md Client.md tools/Tools.md tools/Editor.md tools/Input.md \
security/ThreatModel.md Client.md tools/Tools.md tools/Editor.md tools/Input.md \
tools/RawCapture.md tools/TUI.md tools/RawCapture.md tools/TUI.md
clean: clean:
rm -rf docs rm -rf docs

View File

@ -6,7 +6,7 @@ Copyright [Kevin Froman](https://chaoswebs.net/) [Licensed under GPLv3](LICENSE.
Work in progress Work in progress
--- version --- version
3.0.0 0.0.1
--- ---

View File

@ -5,14 +5,14 @@
--- do streaming keylogger approach --- do streaming keylogger approach
key := "" key := ""
if strings.HasPrefix(message_string, "@{keydown cmd}") { if strings.HasPrefix(message_string, "{KEYDWN}") {
key = strings.TrimPrefix(string(message_string), "@{keydown cmd}") key = strings.TrimPrefix(string(message_string), "{KEYDWN}")
k.Write(1, key) k.Write(1, key)
} else if strings.HasPrefix(message_string, "@{keyup cmd}") { } else if strings.HasPrefix(message_string, "{KEYUP}") {
key = strings.TrimPrefix(string(message_string), "@{keyup cmd}") key = strings.TrimPrefix(string(message_string), "{KEYUP}")
k.Write(0, key) k.Write(0, key)
} else if strings.HasPrefix(message_string, "@{keyheld cmd}") { } else if strings.HasPrefix(message_string, "{KEYHLD}") {
key = strings.TrimPrefix(string(message_string), "@{keyheld cmd}") key = strings.TrimPrefix(string(message_string), "{KEYHLD}")
k.Write(2, key) k.Write(2, key)
} else{ } else{
for _, key := range message_string { for _, key := range message_string {

View File

@ -102,6 +102,7 @@ package server
import( import(
"net" "net"
"time"
"os" "os"
"os/exec" "os/exec"
"strings" "strings"

View File

@ -6,7 +6,7 @@ Most of the time, we can use the keylogger library (which uses uinput) to effeci
xdotool spawns a new process for each keypress, so it's not as effecient as keylogger. 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 `@{use xdotool cmd}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.
``` go ``` go
--- streaming keyboard input --- streaming keyboard input
@ -57,6 +57,7 @@ func clientConnected(w http.ResponseWriter, r *http.Request) {
c.WriteMessage(websocket.TextMessage, []byte("authenticated")) c.WriteMessage(websocket.TextMessage, []byte("authenticated"))
for { for {
time.Sleep(25 * time.Millisecond)
_, message, err := c.ReadMessage() _, message, err := c.ReadMessage()
if err != nil { if err != nil {
log.Println("read:", err) log.Println("read:", err)
@ -67,11 +68,9 @@ func clientConnected(w http.ResponseWriter, r *http.Request) {
if message_string == "" { if message_string == "" {
message_string = "\n" message_string = "\n"
} }
for _, part := range strings.Split(message_string, "@{payload delimiter}") {
message_string = part
@{send keys to system} @{send keys to system}
} }
}
} }
--- ---

View File

@ -1,37 +0,0 @@
# String Commands
To control key events and the input method we use special command strings at the beginning of a message.
They are as follows:
Payload delimiter:
--- payload delimiter
{KB_MSG}
---
Xdotool typing:
--- use xdotool cmd
{KEYDOXDOTOOL}:
---
Xdotool key command:
--- use xdotool key cmd
{KEYDOXTOOLKEY}:
---
Send keys commands:
--- keydown cmd
{KEYDWN}
---
--- keyup cmd
{KEYUP}
---
--- keyheld cmd
{KEYHLD}
---

View File

@ -2,14 +2,14 @@
Currently the two commands are `type` and `key`. `type` is used to type a character and `key` is used to type a special character like `Enter` or `Backspace`. Currently the two commands are `type` and `key`. `type` is used to type a character and `key` is used to type a special character like `Enter` or `Backspace`.
`type` is specified by '@{use xdotool cmd}', and `key` is specified by '@{use xdotool key cmd}'. If the command is not specified and `alwaysUseXdotool` is set from the environment variable, it will default to `type`. `type` is specified by '{kb_cmd:xdotool}:', and `key` is specified by '{kb_cmd:kxdotool}:'. If the command is not specified and `alwaysUseXdotool` is set from the environment variable, it will default to `type`.
``` go ``` go
--- handle xdotoool commands --- handle xdotoool commands
if alwaysUseXdotool || strings.HasPrefix(message_string, "@{use xdotool cmd}") { if alwaysUseXdotool || strings.HasPrefix(message_string, "{kb_cmd:xdotool}:") {
message_string = strings.TrimPrefix(message_string, "@{use xdotool cmd}") message_string = strings.TrimPrefix(message_string, "{kb_cmd:xdotool}:")
if message_string == "" { if message_string == "" {
message_string = "\n" message_string = "\n"
} }
@ -37,8 +37,8 @@ if alwaysUseXdotool || strings.HasPrefix(message_string, "@{use xdotool cmd}") {
doXDoTool("type", message_string) doXDoTool("type", message_string)
} }
continue continue
} else if strings.HasPrefix(message_string, "@{use xdotool key cmd}") { } else if strings.HasPrefix(message_string, "{kb_cmd:kxdotool}:") {
message_string = strings.TrimPrefix(message_string, "@{use xdotool key cmd}") message_string = strings.TrimPrefix(message_string, "{kb_cmd:kxdotool}:")
if message_string == "" { if message_string == "" {
message_string = "\n" message_string = "\n"
} }

View File

@ -248,13 +248,13 @@ try:
except KeyError: except KeyError:
print("Unknown key: " + str(e_code)) print("Unknown key: " + str(e_code))
if event.value == 1: if event.value == 1:
key_str = "@{payload delimiter}@{keydown cmd}" + key_str key_str = "{KEYDWN}" + key_str
log.append(e_code) log.append(e_code)
quit_if_necessry(log) quit_if_necessry(log)
elif event.value == 0: elif event.value == 0:
key_str = "@{payload delimiter}@{keyup cmd}" + key_str key_str = "{KEYUP}" + key_str
elif event.value == 2: elif event.value == 2:
key_str = "@{payload delimiter}@{keyheld cmd}" + key_str key_str = "{KEYHLD}" + key_str
else: else:
print("Unknown value: " + str(event.value)) print("Unknown value: " + str(event.value))
continue continue