zoukankan      html  css  js  c++  java
  • 一个简单的tcp代理实现

    There are a number of reasons to have a TCP proxy in your tool belt, both
    for forwarding traffic to bounce from host to host, but also when assessing
    network-based software. When performing penetration tests in enterprise
    environments, you'll commonly be faced with the fact that you can't run
    Wireshark, that you can't load drivers to sniff the loopback on Windows, or
    that network segmentation prevents you from running your tools directly
    against your target host. I have employed a simple Python proxy in a number of cases to help understand unknown protocols, modify traffic being
    sent to an application, and create test cases for fuzzers. Let's get to it.

    --black python

     

    一个简单的tcp代理实现,当然是socket层面的实现。

    可以说对应用是透明的。

    用法如下:

    tcpproxy -localhost 0.0.0.0 -localport 9000 -remotehost 20.3.3.3 -remoteport 80

    browser open http://127.0.0.1:9000 is the same as open http://20.3.3.3:80

     

    实现的时候还考虑unix环境高级编程中的select之类的多路复用,后来觉得还是gopher的方式比较好,直接上goroutine,既简单清晰,还高效。

    实现思路基本上和blackhat python是一样的,不过它是基于线程,其实没啥差别。

    package main

    import (
    "flag"
    "fmt"
    "os"
    "net"
    "encoding/hex"
    )

    func usage() {
    s := `
    a tcp proxy util
    tcpproxy -localhost 127.0.0.1 -localport 9000 -remotehost 192.168.1.2 -remoteport 80
    -localhost 127.0.0.1 default is 0.0.0.0 - listen on [localhost]:[localport] for incoming connections
    -localport
    -remotehost
    -remoteport redirect incomming connection to [remotehost]:[remoteport]

    Examples:
    tcpproxy -localhost 0.0.0.0 -localport 9000 -remotehost 20.3.3.3 -remoteport 80

    browser open http://127.0.0.1:9000 is the same as open http://20.3.3.3:80

    `
    fmt.Println(s)
    os.Exit(0)
    }

    //send all received data to my client
    func remoteConnHandler(rc, lc net.Conn) {
    buf := make([]byte, 4096)
    for {
    n, err := rc.Read(buf)
    if err != nil {
    break
    }
    if n > 0 {
    fmt.Printf("[<==] Sending %d bytes to localhost. ", n)
    hex.Dump(buf[:n])
    lc.Write(buf[:n])
    }
    }
    fmt.Println("[*] Closing remote connection...")
    rc.Close()
    lc.Close()
    }
    //first connect to remote server
    //then send all received data to remote server
    func localConnHandler(c net.Conn, remoteHost string, remotePort int) {
    rc, err := net.Dial("tcp", fmt.Sprintf("%s:%d", remoteHost, remotePort))
    if err != nil {
    fmt.Printf("connect to remote server failed!")
    return
    }
    go remoteConnHandler(rc, c)
    buf := make([]byte, 4096)
    for {
    n, err := c.Read(buf) // only proxy normal data, urgent data is ignored
    if err != nil {
    break
    }
    if n > 0 {
    fmt.Printf("[==>] Received %d bytes from localhost. ", n)
    hex.Dump(buf[:n])
    rc.Write(buf[:n])
    }
    }
    fmt.Println("[*] close local connection...")
    //duplicat close is ok
    rc.Close()
    c.Close()
    }
    func serverLoop(localHost string, localPort int, remoteHost string, remotePort int) {
    listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", localHost, localPort))
    if err != nil {
    fmt.Errorf("listen on port %d error ", localPort)
    return
    }
    fmt.Printf("Listenging on %s:%d ", localHost, localPort)
    for {
    conn, err := listener.Accept()
    if err != nil {
    fmt.Errorf("accept error:", err)
    break
    }
    fmt.Printf("[==>] Received incoming connection from %s ", conn.RemoteAddr())
    go localConnHandler(conn, remoteHost, remotePort)
    }
    }
    func main() {
    var (
    localHost string
    localPort int
    remoteHost string
    remotePort int
    )

    flag.StringVar(&localHost, "localhost", "0.0.0.0", "listening local ip")
    flag.StringVar(&remoteHost, "remotehost", "", "remote host address")
    flag.IntVar(&localPort, "localport", 0, "listening local port")
    flag.IntVar(&remotePort, "remoteport", 0, "remote host's port to connect")
    flag.Parse()
    if len(remoteHost) <= 0 || localPort == 0 || remotePort == 0 {
    usage()
    }
    serverLoop(localHost, localPort, remoteHost, remotePort)
    }

     

  • 相关阅读:
    Go中的结构实现它的的写法注意事项
    Go语言中的struct的初始化。
    python中的number类型
    python的类型
    今天起,每天记录python等语言的编程心得和体会
    destoon 下apache伪静态排除目录规则
    如何进行数据库设计?
    Spring IOC知识点
    SpringBoot框架:集成Security完成认证鉴权
    CentOS 7 本地安装kubernetes
  • 原文地址:https://www.cnblogs.com/baizx/p/5500216.html
Copyright © 2011-2022 走看看