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)
    }

     

  • 相关阅读:
    剑指OFFER之合并有序链表(九度OJ1519)
    剑指OFFER之反转链表(九度OJ1518)
    剑指OFFER之链表中倒数第k个节点(九度OJ1517)
    一分钟教你在博客园中制作自己的动态云球形标签页
    剑指OFFER之调整数组顺序使奇数位于偶数前面找(九度OJ1516)
    剑指OFFER之打印1到最大的N位数(九度OJ1515)
    剑指OFFER之矩形覆盖(九度OJ1390)
    剑指OFFER之数值的整数次方(九度OJ1514)
    剑指OFFER之变态跳台阶(九度OJ1389)
    剑指OFFER之二进制中1的个数(九度OJ1513)
  • 原文地址:https://www.cnblogs.com/baizx/p/5500216.html
Copyright © 2011-2022 走看看