This is a basic listener that works similarly to nc -l It's selling point is that you can run a command when the window is resized. An example is given for putting an appropraet stty command on the clipboard for a reverse shellmaster
commit
329a709d49
2 changed files with 225 additions and 0 deletions
@ -0,0 +1,9 @@ |
||||
#!/usr/bin/env bash |
||||
# |
||||
# This gets the dimentions of the terminal and puts the approprate stty command on the clipboard for reverse shells |
||||
|
||||
|
||||
columns=$(stty -a < /dev/stdin | grep -oE 'columns [0-9]+' | cut -d' ' -f2) |
||||
rows=$(stty -a < /dev/stdin | grep -oE 'rows [0-9]+' | cut -d' ' -f2) |
||||
notify-send "Terminal dimensions" "Rows: $rows\nColumns: $columns\nstty command on clipboard" |
||||
echo "stty rows $rows cols $columns" | xclip -i -selection clipboard |
@ -0,0 +1,216 @@ |
||||
// go-nc project main.go
|
||||
package main |
||||
|
||||
import ( |
||||
"flag" |
||||
"fmt" |
||||
"io" |
||||
"log" |
||||
"net" |
||||
"os" |
||||
"os/exec" |
||||
"os/signal" |
||||
"strconv" |
||||
"syscall" |
||||
) |
||||
|
||||
// Handles TC connection and perform synchorinization:
|
||||
// TCP -> Stdout and Stdin -> TCP
|
||||
func tcp_con_handle(con net.Conn) { |
||||
chan_to_stdout := stream_copy(con, os.Stdout) |
||||
chan_to_remote := stream_copy(os.Stdin, con) |
||||
select { |
||||
case <-chan_to_stdout: |
||||
log.Println("Remote connection is closed") |
||||
case <-chan_to_remote: |
||||
log.Println("Local program is terminated") |
||||
} |
||||
} |
||||
|
||||
// Performs copy operation between streams: os and tcp streams
|
||||
func stream_copy(src io.Reader, dst io.Writer) <-chan int { |
||||
buf := make([]byte, 1024) |
||||
sync_channel := make(chan int) |
||||
go func() { |
||||
defer func() { |
||||
if con, ok := dst.(net.Conn); ok { |
||||
con.Close() |
||||
log.Printf("Connection from %v is closed\n", con.RemoteAddr()) |
||||
} |
||||
sync_channel <- 0 // Notify that processing is finished
|
||||
}() |
||||
for { |
||||
var nBytes int |
||||
var err error |
||||
nBytes, err = src.Read(buf) |
||||
if err != nil { |
||||
if err != io.EOF { |
||||
log.Printf("Read error: %s\n", err) |
||||
} |
||||
break |
||||
} |
||||
_, err = dst.Write(buf[0:nBytes]) |
||||
if err != nil { |
||||
log.Fatalf("Write error: %s\n", err) |
||||
} |
||||
} |
||||
}() |
||||
return sync_channel |
||||
} |
||||
|
||||
//Accept data from UPD connection and copy it to the stream
|
||||
func accept_from_udp_to_stream(src net.Conn, dst io.Writer) <-chan net.Addr { |
||||
buf := make([]byte, 1024) |
||||
sync_channel := make(chan net.Addr) |
||||
con, ok := src.(*net.UDPConn) |
||||
if !ok { |
||||
log.Printf("Input must be UDP connection") |
||||
return sync_channel |
||||
} |
||||
go func() { |
||||
var remoteAddr net.Addr |
||||
for { |
||||
var nBytes int |
||||
var err error |
||||
var addr net.Addr |
||||
nBytes, addr, err = con.ReadFromUDP(buf) |
||||
if err != nil { |
||||
if err != io.EOF { |
||||
log.Printf("Read error: %s\n", err) |
||||
} |
||||
break |
||||
} |
||||
if remoteAddr == nil && remoteAddr != addr { |
||||
remoteAddr = addr |
||||
sync_channel <- remoteAddr |
||||
} |
||||
_, err = dst.Write(buf[0:nBytes]) |
||||
if err != nil { |
||||
log.Fatalf("Write error: %s\n", err) |
||||
} |
||||
} |
||||
}() |
||||
log.Println("Exit write_from_udp_to_stream") |
||||
return sync_channel |
||||
} |
||||
|
||||
// Put input date from the stream to UDP connection
|
||||
func put_from_stream_to_udp(src io.Reader, dst net.Conn, remoteAddr net.Addr) <-chan net.Addr { |
||||
buf := make([]byte, 1024) |
||||
sync_channel := make(chan net.Addr) |
||||
go func() { |
||||
for { |
||||
var nBytes int |
||||
var err error |
||||
nBytes, err = src.Read(buf) |
||||
if err != nil { |
||||
if err != io.EOF { |
||||
log.Printf("Read error: %s\n", err) |
||||
} |
||||
break |
||||
} |
||||
log.Println("Write to the remote address:", remoteAddr) |
||||
if con, ok := dst.(*net.UDPConn); ok && remoteAddr != nil { |
||||
_, err = con.WriteTo(buf[0:nBytes], remoteAddr) |
||||
} |
||||
if err != nil { |
||||
log.Fatalf("Write error: %s\n", err) |
||||
} |
||||
} |
||||
}() |
||||
return sync_channel |
||||
} |
||||
|
||||
// Handle UDP connection
|
||||
func udp_con_handle(con net.Conn) { |
||||
in_channel := accept_from_udp_to_stream(con, os.Stdout) |
||||
log.Println("Waiting for remote connection") |
||||
remoteAddr := <-in_channel |
||||
log.Println("Connected from", remoteAddr) |
||||
out_channel := put_from_stream_to_udp(os.Stdin, con, remoteAddr) |
||||
select { |
||||
case <-in_channel: |
||||
log.Println("Remote connection is closed") |
||||
case <-out_channel: |
||||
log.Println("Local program is terminated") |
||||
} |
||||
} |
||||
|
||||
func main() { |
||||
var destinationPort string |
||||
var resizeCommand string |
||||
var isUdp bool |
||||
|
||||
sigs := make(chan os.Signal, 1) |
||||
|
||||
flag.BoolVar(&isUdp, "u", false, "Use UDP instead of the default option of TCP.") |
||||
flag.StringVar(&resizeCommand, "r", "", "Use UDP instead of the default option of TCP.") |
||||
flag.Parse() |
||||
if flag.NFlag() == 0 && flag.NArg() == 0 { |
||||
fmt.Println("go-nc [-u] [-r command] [port]") |
||||
flag.Usage() |
||||
os.Exit(1) |
||||
} |
||||
|
||||
if isUdp { |
||||
log.Println("Protocol:", "udp") |
||||
} else { |
||||
log.Println("Protocol:", "tcp") |
||||
} |
||||
|
||||
if flag.NArg() < 1 { |
||||
fmt.Println("when you use -l option [port] is mandatory argument") |
||||
os.Exit(1) |
||||
} |
||||
if _, err := strconv.Atoi(flag.Arg(0)); err != nil { |
||||
log.Println("Destination port shall be not empty and have integer value") |
||||
os.Exit(1) |
||||
} |
||||
destinationPort = fmt.Sprintf(":%v", flag.Arg(0)) |
||||
|
||||
log.Println("Port:", destinationPort) |
||||
|
||||
if len(resizeCommand) != 0 { |
||||
log.Println("Resize command:", resizeCommand) |
||||
signal.Notify(sigs, syscall.SIGWINCH) |
||||
go func() { |
||||
for true{ |
||||
<-sigs |
||||
log.Println("Window Resized") |
||||
cmd := exec.Command(resizeCommand) |
||||
cmd.Stdin = os.Stdin |
||||
_, err := cmd.Output() |
||||
|
||||
log.Printf("err: %#v\n", err) |
||||
} |
||||
}() |
||||
} |
||||
|
||||
if !isUdp { |
||||
|
||||
listener, err := net.Listen("tcp", destinationPort) |
||||
if err != nil { |
||||
log.Fatalln(err) |
||||
} |
||||
log.Println("Listening on", destinationPort) |
||||
con, err := listener.Accept() |
||||
if err != nil { |
||||
log.Fatalln(err) |
||||
} |
||||
log.Println("Connect from", con.RemoteAddr()) |
||||
tcp_con_handle(con) |
||||
|
||||
} else { |
||||
addr, err := net.ResolveUDPAddr("udp", destinationPort) |
||||
if err != nil { |
||||
log.Fatalln(err) |
||||
} |
||||
con, err := net.ListenUDP("udp", addr) |
||||
if err != nil { |
||||
log.Fatalln(err) |
||||
} |
||||
log.Println("Has been resolved UDP address:", addr) |
||||
log.Println("Listening on", destinationPort) |
||||
udp_con_handle(con) |
||||
} |
||||
} |
Loading…
Reference in new issue