一个简单的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", 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代理实现的更多相关文章
- C#socket编程之实现一个简单的TCP通信
TCP(TransmissionControl Protocol)传输控制协议. 是一种可靠的.面向连接的协议(eg:打电话).传输效率低全双工通信(发送缓存&接收缓存).面向字节流.使用TC ...
- Node.js实战14:一个简单的TCP服务器。
本文,将会展示如何用Nodejs内置的net模块开发一个TCP服务器,同时模拟一个客户端,并实现客户端和服务端交互. net模块是nodejs内置的基础网络模块,通过使用net,可以创建一个简单的tc ...
- 使用 TUN 设备实现一个简单的 UDP 代理隧道
若要实现在 Linux 下的代理程序,方法有很多,比如看着 RFC 1928 来实现一个 socks5 代理并自行设置程序经过 socks5 代理等方式,下文是使用 Linux 提供的 tun/tap ...
- 一个简单JDK动态代理的实例
动态代理的步骤: 创建一个实现了InvocationHandler接口的类,必须重写接口里的invoke()方法. 创建被代理的类和接口 通过Proxy的静态方法 newProxyInsatance( ...
- 一个简单 JDK 动态代理的实例
动态代理的步骤: 创建一个实现了 InvocationHandler 接口的类,必须重写接口里的 invoke()方法. 创建被代理的类和接口 通过 Proxy 的静态方法 newProxyInsat ...
- 编写一个简单的TCP服务端和客户端
下面的实验环境是linux系统. 效果如下: 1.启动服务端程序,监听在6666端口上 2.启动客户端,与服务端建立TCP连接 3.建立完TCP连接,在客户端上向服务端发送消息 4.断开连接 实现 ...
- golang实现一个简单的http代理
代理是网络中的一项重要的功能,其功能就是代理网络用户去取得网络信息.形象的说:它是网络信息的中转站,对于客户端来说,代理扮演的是服务器的角色,接收请求报文,返回响应报文:对于web服务器来说,代理扮演 ...
- 【实验 1-1】编写一个简单的 TCP 服务器和 TCP 客户端程序。程序均为控制台程序窗口。
在新建的 C++源文件中编写如下代码. 1.TCP 服务器端#include<winsock2.h> //包含头文件#include<stdio.h>#include<w ...
- [Python网络编程]一个简单的TCP时间服务器
服务器端: 1.创建一个面向网络的TCP套接字对象socket, 2.绑定地址和端口 3.监听 4.当有客户端连接时候,接受连接并给此连接分配一个新的套接字 5.当客户端发送空信息时候,关闭新分配的套 ...
随机推荐
- java代码求奖金。要求从键盘输入利润
总结:看似文字描述很多, package com.ai; import java.util.Scanner; import com.b.Scaner; //v企业发放的奖金根据利润提成.利润(I)低于 ...
- 缓存 memcached 与 redis
Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度 ...
- kettle init oracle jdbc
- JavaScript高级程序设计学习
1.变量 变量使用var操作符定义,var message,定义一个message变量,可用来保存任何类型的变量.未经初始化的变量值为undifided: 如果没变量没有被var定义,那么被执行后会成 ...
- nginx搭建文件服务器配置文件
worker_processes 1; events { worker_connections 1024;} http { include mime.types; default_type appli ...
- oracle使用exp/imp导入导出(用户)
实例,从远程机器上导出nxgy用户的所有对象和数据,然后导入到本机数据库的nxgy用户里(用户名可自定义) 如果本机nxgy用户已经存在(数据没用,可以删除),级联删除用户所有对象 首先,从远程机器上 ...
- 思考ASP.NET网站静态化的利与弊
最近在思考网站要不要进行静态化的问题,在网上收集和整理了有关静态化利与弊的资料,于是写下此博文分享到网络上.由于本人是一名asp.net开发人员,所以本文的观点可能无法涉及到全部方面,但是比较注重于使 ...
- 虚拟机安装CentOS以及SecureCRT设置【完美无错版】
一.CentOS简介 CentOS是Linux的发行版之一,它安全.稳定.高效,是我最喜欢的Linux发行版之一.CentOS根据Red Hat Enterprise Linux开放源代码编译而成,与 ...
- MyBatis—实现关联表查询
一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数据 创建一张教师表和班级表,这里我们假设一个老师只负责教一个班,那么老师和班级之间的关系就是一种一对一的关 ...
- Python代码注释
1.单行注释使用# # Code 2.多行注释,成对使用'''或""",三个单撇号或三个双引号 “”” Code “”” 3.多行快捷注释 1).增加注释 选中待注释的多 ...