From 037a9d69a424e31f01235b755a28fcb9ee23d840 Mon Sep 17 00:00:00 2001 From: Simon Moser Date: Tue, 12 Oct 2021 14:37:56 +0200 Subject: [PATCH] Proxy forwards and displays binary traffic --- proxy/cmd/cmd.go | 41 ++++++++++++++++----------- proxy/main.go | 55 +++++++++++++++++++++++------------- test-env/qemu-environment.sh | 12 +++++--- 3 files changed, 68 insertions(+), 40 deletions(-) diff --git a/proxy/cmd/cmd.go b/proxy/cmd/cmd.go index 273f6e8..82f420d 100644 --- a/proxy/cmd/cmd.go +++ b/proxy/cmd/cmd.go @@ -1,33 +1,42 @@ package cmd import ( - "bytes" "io" "log" "os" "os/exec" ) +// Overloads the exec.Cmd class to save the full command +// and adds custom input/output pipes type cmd struct { fullCommand string *exec.Cmd - bufOut bytes.Buffer - bufErr bytes.Buffer + inReader io.Reader + InWriter io.Writer + OutReader io.Reader + outWriter io.Writer } +// New creates a new cmd object with given arguments and returns it func New(name string, args string) *cmd{ - var bO, bE bytes.Buffer + ir, iw := io.Pipe() + or, ow := io.Pipe() c := cmd { name + " " + args, exec.Command(name, args), - bO, - bE, + ir, + iw, + or, + ow, } - c.Stdout = io.MultiWriter(os.Stdout, &c.bufOut) - c.Stderr = io.MultiWriter(os.Stderr, &c.bufErr) + c.Stdout = c.outWriter + c.Stdin = c.inReader + c.Stderr = os.Stderr return &c } +// Execute runs Cmd.Start() and catches the possible error func (c *cmd) Execute() { err := c.Start() if err != nil { @@ -35,17 +44,15 @@ func (c *cmd) Execute() { } } -func (c *cmd) GetOut() string { - return string(c.bufOut.Bytes()) -} - -func (c *cmd) GetErr() string { - return string(c.bufErr.Bytes()) -} - +// WaitH runs Cmd.Wait() and catches the possible error func (c *cmd) WaitH() { err := c.Wait() if err != nil { log.Printf("%s failed with %s\n", c.fullCommand, err) } -} \ No newline at end of file +} + +const ( + Out = "\u001b[31m>> " // Prefix for traffic from VM + In = "\u001b[32m<< " // Prefix for traffic to VM +) \ No newline at end of file diff --git a/proxy/main.go b/proxy/main.go index 6a38d98..1d30b39 100644 --- a/proxy/main.go +++ b/proxy/main.go @@ -1,31 +1,48 @@ package main import ( + "fmt" + "io" + "os" "proxy/cmd" + "unicode" ) +// Start the two plugs and run two concurrent forward methods func main() { - //c1 := cmd.New("sh", "-c \"vde_plug /run/vde/sw_main.sock\"") + c1 := cmd.New("vde_plug", "/run/vde/sw_main.sock") c2 := cmd.New("vde_plug", "/run/vde/sw_proxy.sock") - //c1 := cmd.New("ping", "localhost", "-c 10") - //c2 := cmd.New("nc", "google.com", "80") - //stdin, err := c2.StdinPipe() - //if err != nil { - // log.Fatal(err) - //} - //c1.Execute() + c1.Execute() c2.Execute() - //time.Sleep(time.Second) - //io.WriteString(stdin, "GET / HTTP/1.0\n\n") - //time.Sleep(time.Second) - //stdin.Close() - //c1.WaitH() + go pipeForward(c1.OutReader, c2.InWriter, cmd.In) + go pipeForward(c2.OutReader, c1.InWriter, cmd.Out) + c1.WaitH() c2.WaitH() +} - /* cmds := []*cmd.cmd{c1} - for _, x := range cmds { - go func(cmd *exec.Cmd) { - fmt.Printf(x.String()) - }(cmd) - }*/ +// Reads from an input and writes to and output, +// do things to the content in between. +// For now only output it in xxd format. +// Is meant to be run concurrently with "go pipeForward(...)" +func pipeForward(reader io.Reader, writer io.Writer, prefix string) { + i := 0 + for { + bytes := make([]byte, 16) + bytesReadable := make([]byte, 16) + _, err := reader.Read(bytes) + if err == io.EOF { + break + } + for i, ch := range bytes { + if ch > unicode.MaxASCII || ch < '\u0020' { + bytesReadable[i] = '\u002E' + } else { + bytesReadable[i] = ch + } + } + xxdString := fmt.Sprintf("%s%08x: %04x %04x %04x %04x %04x %04x %04x %04x %s\n", prefix, i, bytes[0:1], bytes[2:3], bytes[4:5], bytes[6:7], bytes[8:9], bytes[10:11], bytes[12:13], bytes[14:15], bytesReadable) + os.Stdout.WriteString(xxdString) + writer.Write(bytes) + i += 16 + } } \ No newline at end of file diff --git a/test-env/qemu-environment.sh b/test-env/qemu-environment.sh index 8df5cb8..c845876 100755 --- a/test-env/qemu-environment.sh +++ b/test-env/qemu-environment.sh @@ -12,10 +12,11 @@ case "$1" in vde_switch -daemon -s $RUN/sw_main.sock -p $RUN/sw_main.pid # Proxy switch -.- vde_switch -daemon -s $RUN/sw_proxy.sock -p $RUN/sw_proxy.pid - # Slirp NAT - slirpvde --dhcp --daemon -s $RUN/sw_main.sock -p $RUN/slirp.pid - echo "Run:\nqemu -m 512 -nic vde,mac='52:54:00:12:34:56',sock=$RUN/sw_proxy.sock -hda alpine1.qcow2 -nographic" - $qemu -m 512 -nic vde,mac='52:54:00:12:34:66',sock=$RUN/sw_main.sock -hda alpine2.qcow2 -daemonize -vnc :1 -pidfile $RUN/vm_2.pid + # Slirp NAT + Port forwarding SSH + slirpvde -D -H 10.0.0.2 --daemon -s $RUN/sw_main.sock -p $RUN/slirp.pid + #echo "Run:\nqemu -m 512 -nic vde,mac='52:54:00:12:34:56',sock=$RUN/sw_proxy.sock -hda alpine1.qcow2 -nographic" + $qemu -m 512 -nic vde,mac='52:54:00:12:34:56',sock=$RUN/sw_proxy.sock -hda alpine1.qcow2 -daemonize -vnc :1 -pidfile $RUN/vm_1.pid + $qemu -m 512 -nic vde,mac='52:54:00:12:34:66',sock=$RUN/sw_main.sock -hda alpine2.qcow2 -daemonize -vnc :2 -pidfile $RUN/vm_2.pid ;; stop) echo "Stopping VDE network for QEMU: " @@ -29,6 +30,9 @@ case "$1" in status) ps -fq `cat $RUN/*.pid | xargs | sed 's/ /,/g'` ;; + ssh) + ssh -p 2222 root@localhost + ;; *) echo "Usage: $0 {start|stop|restart|reload}" exit 1