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", 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", 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\n", localPort)
return
}
fmt.Printf("Listenging on %s:%d \n", localHost, localPort)
for {
conn, err := listener.Accept()
if err != nil {
fmt.Errorf("accept error:", err)
break
}
fmt.Printf("[==>] Received incoming connection from %s\n", 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)
}

一个简单的tcp代理实现的更多相关文章

  1. C#socket编程之实现一个简单的TCP通信

    TCP(TransmissionControl Protocol)传输控制协议. 是一种可靠的.面向连接的协议(eg:打电话).传输效率低全双工通信(发送缓存&接收缓存).面向字节流.使用TC ...

  2. Node.js实战14:一个简单的TCP服务器。

    本文,将会展示如何用Nodejs内置的net模块开发一个TCP服务器,同时模拟一个客户端,并实现客户端和服务端交互. net模块是nodejs内置的基础网络模块,通过使用net,可以创建一个简单的tc ...

  3. 使用 TUN 设备实现一个简单的 UDP 代理隧道

    若要实现在 Linux 下的代理程序,方法有很多,比如看着 RFC 1928 来实现一个 socks5 代理并自行设置程序经过 socks5 代理等方式,下文是使用 Linux 提供的 tun/tap ...

  4. 一个简单JDK动态代理的实例

    动态代理的步骤: 创建一个实现了InvocationHandler接口的类,必须重写接口里的invoke()方法. 创建被代理的类和接口 通过Proxy的静态方法 newProxyInsatance( ...

  5. 一个简单 JDK 动态代理的实例

    动态代理的步骤: 创建一个实现了 InvocationHandler 接口的类,必须重写接口里的 invoke()方法. 创建被代理的类和接口 通过 Proxy 的静态方法 newProxyInsat ...

  6. 编写一个简单的TCP服务端和客户端

    下面的实验环境是linux系统. 效果如下: 1.启动服务端程序,监听在6666端口上  2.启动客户端,与服务端建立TCP连接  3.建立完TCP连接,在客户端上向服务端发送消息 4.断开连接 实现 ...

  7. golang实现一个简单的http代理

    代理是网络中的一项重要的功能,其功能就是代理网络用户去取得网络信息.形象的说:它是网络信息的中转站,对于客户端来说,代理扮演的是服务器的角色,接收请求报文,返回响应报文:对于web服务器来说,代理扮演 ...

  8. 【实验 1-1】编写一个简单的 TCP 服务器和 TCP 客户端程序。程序均为控制台程序窗口。

    在新建的 C++源文件中编写如下代码. 1.TCP 服务器端#include<winsock2.h> //包含头文件#include<stdio.h>#include<w ...

  9. [Python网络编程]一个简单的TCP时间服务器

    服务器端: 1.创建一个面向网络的TCP套接字对象socket, 2.绑定地址和端口 3.监听 4.当有客户端连接时候,接受连接并给此连接分配一个新的套接字 5.当客户端发送空信息时候,关闭新分配的套 ...

随机推荐

  1. 1041 Be Unique

    题意:找到一串数字序列中首个出现的不重复的数字. 思路:用哈希,因为数值大小在[1,10^4],所以可以直接开数组.输入数据时记录每个数字出现过的次数.然后遍历原序列,遇到第一个次数为1的数字就是所求 ...

  2. 1116 Come on! Let's C

    题意:略. 思路:略. 代码: #include <cstdio> #include <cmath> ; }; bool isPrime(int n) { ) return f ...

  3. 二 mysql容量规划,性能测试

    何为基线- 当前运行状态记录.快照- 用于和未来的状态进行对比- 未来时刻产生关键事件后的新状态,作为下一个基线基线数据收集,关注哪些要点- 系统负载- MySQL运行状态- 相应的业务指标1.系统& ...

  4. MMU_段式映射

    首先, 段式映射的示意图如下: 该例程有5个文件构成: head.s-------------入口程序 mmu.lds-----------连接文件 init.c---------------初始化文 ...

  5. yield-from示例

    #!/usr/bin/python3# -*- coding: utf-8 -*-# @Time    : 2018/6/20 9:13# @File    : yield_from11.py fro ...

  6. Delphi PDF

    llPDFLib,TPDFDocument 2016开始开源. procedure TForm2.Button1Click(Sender: TObject); var lPdf : TPdfDocum ...

  7. angularJS笔记之Promise

    Promise是一种模式,以同步操作的流程形式来操作异步事件,避免了层层嵌套,可以链式操作异步事件. 我们知道,在编写javascript异步代码时,callback是最最简单的机制,可是用这种机制的 ...

  8. android 标签页<include /> 的使用

    在android页面布局设计中,有时候需要用到很多相同的布局设计.如果每个用到该布局的xml里都写那个相同布局的话,会造成语句冗余,而且可读性很差. 为了解决这个问题的话,我们可以把相同布局的代码单独 ...

  9. sklearn中的cross_val_score()函数

    sklearn.cross_validation.cross_val_score(estimator, X, y=None, scoring=None, cv=None, n_jobs=1, verb ...

  10. JAVA基础知识总结17(网络编程)

    端口: 物理端口:IP地址 逻辑端口:用于标识进程的逻辑地址,不同进程的标识:有效端口:0~65535,其中0~1024系统使用或保留端口. JAVA中ip对象:InetAddress. import ...