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

     

  • 相关阅读:
    jquery ajax 赋值问题, 后面程序判断逻辑用
    jquery formValidator 表单验证插件, ajax无法传值到后台问题的解决
    学习写了一个点击按钮倒计时的jquery小插件
    点击按钮复制指定代码
    discuz 修改积分策略( 在周期中添加"每周" )
    php获取本周周一、周日时间,上周周一、周日时间,本月第一天,本月最后一天,上个月第一天,最后一天时间
    php用正则判断是否为数字
    discuz 标签详解
    用dwz时, 由于粗心产生的一些问题(记录方便自己查阅)
    yii mailer 扩展发送邮件
  • 原文地址:https://www.cnblogs.com/baizx/p/5500216.html
Copyright © 2011-2022 走看看