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. spring-session之一:简介、使用及实现原理

    一.背景 http session(企业)一直都是我们做集群时需要解决的一个难题,我们知道HttpSession是通过Servlet容器创建和管理的,像Tomcat/Jetty都是保存在内存中的.而如 ...

  2. 第八章 JVM内存管理

    8.1 物理内存与虚拟内存 地址总线(连接处理器和RAM或处理器和寄存器的)的宽度影响了物理地址的索引范围,决定了处理器一次可以从寄存器或内存中获取多少个bit.同时决定了处理器最大的寻址空间,32位 ...

  3. java成神之——安全和密码

    安全和密码 加密算法 公钥和私钥加密解密 生成私钥和公钥 加密数据 解密数据 公钥私钥生成的不同算法 密钥签名 生成加密随机数 基本用法 指定算法 加密对象 SealedObject Signatur ...

  4. MySQL中SQL_CALC_FOUND_ROWS的用法

    1. SQL_CALC_FOUND_ROWS简述 在很多分页的程序中都这样写: #查出符合条件的记录总数 SELECT COUNT(*) from [table] WHERE ......; #查询当 ...

  5. clock函数返回负值~ (转)

    使用clock() 函数来进行计时,时不时的返回一个很大的负数,怎么检查也检查不出错误,现在找出错误原因,给大家分享一下. 来源网页:http://kebe-jea.blogbus.com/logs/ ...

  6. [故障及解决]SoundPool没有声音

    问题描述:使用SoundPool类进行播放声音时,在手机上没有声音. 问题代码: /** * 声音播放 */ private void playSound() { SoundPool soundPoo ...

  7. 【原】Coursera—Andrew Ng机器学习—课程笔记 Lecture 6_Logistic Regression 逻辑回归

    Lecture6 Logistic Regression 逻辑回归 6.1 分类问题 Classification6.2 假设表示 Hypothesis Representation6.3 决策边界 ...

  8. char(10)、varchar(10)、nchar(10)、nvarchar(10)的区别

    CHAR CHAR是定长的,当输入的字符小于10时,会在后面补空值,如果长度大于10,则会截取超出的字符 CHAR字段上的索引效率级高 VARCHAR 存储边长数据,但存储效率没有CHAR高 从空间上 ...

  9. vectors 使用应该注意到的问题

    ector1. vector的元素必须具备 assignable和 copyable . 2.vector的迭代器是随机存取迭代器. 3.要考虑到vector的大小(size)和容量(capacity ...

  10. 409. Longest Palindrome 最长对称串

    [抄题]: Given a string which consists of lowercase or uppercase letters, find the length of the longes ...