124 lines
4.5 KiB
HTML
124 lines
4.5 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html lang="en">
|
||
|
<head>
|
||
|
<meta charset="utf-8">
|
||
|
<meta name="viewport" content="width=device-width">
|
||
|
<title>GoSmartKeyboard</title>
|
||
|
<link rel="stylesheet" href="google-code-prettify/prettify.css">
|
||
|
<link rel="stylesheet" href="styles/prettify-theme.css">
|
||
|
<script defer src="google-code-prettify/prettify.js"></script>
|
||
|
<script defer src="google-code-prettify/run_prettify.js"></script>
|
||
|
<link rel="stylesheet" href="styles/main.css">
|
||
|
</head>
|
||
|
|
||
|
<!-- Generated by srcweave https://github.com/justinmeiners/srcweave -->
|
||
|
<h1>Streaming keyboard input<a id="c16"></a></h1>
|
||
|
|
||
|
|
||
|
<p>We use the Gorilla websocket library to handle the websocket connection.</p>
|
||
|
|
||
|
<p>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.</p>
|
||
|
|
||
|
<p>xdotool spawns a new process for each keypress, so it’s not as effecient as keylogger.</p>
|
||
|
|
||
|
<p>To specify xdotool usage, the client should send a message with the format <code>{kb_cmd:xdotool}:message</code> where message is a utf-8 string.</p>
|
||
|
|
||
|
|
||
|
<div class="code-block">
|
||
|
<span class="block-header">
|
||
|
<strong class="block-title"><em><a id="streaming-keyboard-input-block-56" href="#streaming-keyboard-input-block-56">streaming keyboard input</a></em></strong></span>
|
||
|
<pre class="prettyprint"><code class="">func clientConnected(w http.ResponseWriter, r *http.Request) {
|
||
|
// regex if string has characters we need to convert to key presses
|
||
|
characterRegex, _ := regexp.Compile(`[^\x08]\x08|\t|\n`)
|
||
|
|
||
|
// 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()
|
||
|
|
||
|
<em class="block-link nocode" title="EnvironmentVariables.html"><a href="EnvironmentVariables.html#always-use-xdotool-environment-variable-block-14">@{always use xdotool environment variable}</a></em>
|
||
|
|
||
|
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
c, err := upgrader.Upgrade(w, r, nil)
|
||
|
if err != nil {
|
||
|
log.Print("upgrade:", err)
|
||
|
return
|
||
|
}
|
||
|
defer c.Close()
|
||
|
|
||
|
// get auth token
|
||
|
_, message, err := c.ReadMessage()
|
||
|
if err != nil {
|
||
|
log.Println("read:", err)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if auth.CheckAuthToken(string(message)) != nil {
|
||
|
log.Println("invalid token")
|
||
|
c.WriteMessage(websocket.TextMessage, []byte("invalid token"))
|
||
|
return
|
||
|
}
|
||
|
c.WriteMessage(websocket.TextMessage, []byte("authenticated"))
|
||
|
|
||
|
for {
|
||
|
time.Sleep(25 * time.Millisecond)
|
||
|
_, message, err := c.ReadMessage()
|
||
|
if err != nil {
|
||
|
log.Println("read:", err)
|
||
|
break
|
||
|
}
|
||
|
log.Printf("recv: %s", message)
|
||
|
message_string := string(message)
|
||
|
if message_string == "" {
|
||
|
message_string = "\n"
|
||
|
}
|
||
|
|
||
|
<em class="block-link nocode"><a href="#send-keys-to-system-block-58">@{send keys to system}</a></em>
|
||
|
}
|
||
|
}
|
||
|
</code></pre>
|
||
|
<p class="block-usages"><small>Used by <a href="Server.html#-server-server-server.go-block-53" title="/server/server/server.go. Server.html">1</a> </small></p></div>
|
||
|
|
||
|
|
||
|
|
||
|
<h1>Sending the keys<a id="c17"></a></h1>
|
||
|
|
||
|
|
||
|
<p>Sending the keys is a bit tricky as we need to manually convert backspace, tab, enter and modifier keys.</p>
|
||
|
|
||
|
|
||
|
<div class="code-block">
|
||
|
<span class="block-header">
|
||
|
<strong class="block-title"><em><a id="send-keys-to-system-block-58" href="#send-keys-to-system-block-58">send keys to system</a></em></strong></span>
|
||
|
<pre class="prettyprint"><code class="">doXDoTool := func(command string, keys string)(err error) {
|
||
|
var cmd *exec.Cmd
|
||
|
if command == "type" {
|
||
|
cmd = exec.Command("xdotool", command, "--delay", "25", keys)
|
||
|
} else {
|
||
|
cmd = exec.Command("xdotool", command, keys)
|
||
|
}
|
||
|
return cmd.Run()
|
||
|
}
|
||
|
|
||
|
<em class="block-link nocode" title="XdotoolCommands.html"><a href="XdotoolCommands.html#handle-xdotoool-commands-block-64">@{handle xdotoool commands}</a></em>
|
||
|
|
||
|
<em class="block-link nocode" title="Sendkeys.html"><a href="Sendkeys.html#do-streaming-keylogger-approach-block-61">@{do streaming keylogger approach}</a></em>
|
||
|
</code></pre>
|
||
|
<p class="block-usages"><small>Used by <a href="#streaming-keyboard-input-block-56" title="streaming keyboard input">1</a> </small></p></div>
|
||
|
|
||
|
|
||
|
</body>
|
||
|
</html>
|