Skip to content

Netcat with automated NAT traversal, secure P2P, and advanced features for shell access, file transfer, and network proxying.

License

threatexpert/gonc

Repository files navigation

gonc 简介

README in English中文

gonc 是一个基于 Golang 的 netcat 工具,旨在更方便地建立点对点通信。其主要特点包括:

  • 🔁 自动化内网穿透:零配置,双方仅需约定一个口令,使用参数-p2p既可自动发现彼此网络地址和穿透内网建立点对点连接,使用公共 STUN 和 MQTT 服务交换地址信息。

  • 🔒 端到端双向认证的加密:支持 TCP 的 TLS 和 UDP 的 DTLS 加密传输,可基于口令双向身份认证。

  • 🧩 灵活的服务配置:通过参数 -e 可灵活的设置为每个连接提供服务的应用程序,例如-e /bin/sh可提供远程cmdshell,还可以使用内置的虚拟命令便捷的使用socks5服务、http文件服务和流量转发功能。


最新版本下载


使用示例

基本用法

  • 可像 nc 一样使用:

    gonc www.baidu.com 80
    gonc -tls www.baidu.com 443
    gonc -l 4444  #监听模式

    nc只能根据IP和端口建立点对点的连接

  • 现在,还可以基于约定口令,建立点对点连接了,还能自动化内网穿透。

    下图是gonc在家庭宽带(困难型NAT)环境和对端为手机移动网络(对称型NAT)之间建立P2P连接的过程。由于两边都有IPv6,因此两边都使用了-4强制使用IPv4来演示NAT打洞。

    hole-punching

P2P 传输文件的例子

  • 双方约定一个相同的口令,然后发送文件的一端,执行下面命令启动 HTTP 文件服务器,最后一个参数c:/RootDir就是要发送的文件所在目录:

    gonc -p2p <口令> -httpserver c:/RootDir
  • 要下载文件的另一端有2种方式:

    1、自动下载完整目录,执行下面命令后,会递归下载所有文件到本地,中断重新执行会自动断点续传:

    gonc -p2p <口令> -download c:/SavePath

    2、这种不会自动开始下载,需手动打开浏览器访问 http://127.0.0.1:9999 浏览对端的文件列表和针对性下载文件

    gonc -p2p <口令> -httplocal-port 9999

玩转 P2P 通信

  • 双方约定一个相同的口令,然后双方都执行下面命令:

    gonc -p2p <口令>

    双方就能基于口令发现彼此的网络地址,内网穿透 NAT ,双向认证和加密通讯。双方都用口令派生证书,基于 TLS 1.3 保证安全通信。(口令相当于证书私钥,建议使用 gonc -psk . 随机生成高强度的口令)

    注意这条命令在两端的运行时差不能太久(30秒以内),否则错过NAT打洞时机会失败退出。因此还支持基于MQTT消息订阅的等待机制,使用-mqtt-wait和-mqtt-hello来同步双方开始P2P的时机。例如,下面用了-mqtt-wait可以持续等待,

    gonc -p2p <口令> -mqtt-wait

    另一端使用:

    gonc -p2p <口令> -mqtt-hello

    以上这样建立的裸连接,也只是可以互相打字发消息哦。如果你是懂nc的,现在要p2p传输数据的话,例如发送文件的命令应该类似是这样:

    cat 文件路径 | gonc -p2p 口令 -mqtt-wait    #linux风格
    
    或
    
    gonc -p2p 口令 -mqtt-wait -send 文件路径    #用-send参数,兼容linux和windows

    另一端使用:

    gonc -p2p 口令 > 保存文件名

反弹 Shell(类UNIX支持pseudo-terminal shell )

  • 监听端(不使用 -keep-open,仅接受一次连接;未使用 -psk,无身份认证):
    gonc -tls -exec ":sh /bin/bash" -l 1234
  • 另一端连接获取 Shell(支持 TAB、Ctrl+C 等操作):
    gonc -tls -pty x.x.x.x 1234
  • 使用 P2P 方式反弹 Shell(<口令> 用于身份认证,基于 TLS 1.3 实现安全通信):
    gonc -exec ":sh /bin/bash" -p2p <口令>
    另一端:
    gonc -pty -p2p <口令>

传输速度测试

  • 发送数据并统计传输速度(内置 /dev/zero/dev/urandom):
    gonc.exe -send /dev/zero -P x.x.x.x 1234
    输出示例:
    IN: 76.8 MiB (80543744 bytes), 3.3 MiB/s | OUT: 0.0 B (0 bytes), 0.0 B/s | 00:00:23
    
    另一端接收:
    gonc -P -l 1234 > NUL

P2P 隧道与 Socks5 代理

  • 等待建立隧道:

    gonc -p2p <口令> -socks5server
  • 另一端将本机监听端口3080提供socks5服务:

    gonc -p2p <口令> -socks5local-port 3080

    接下来例如你想连接远程网络的10.0.0.1:3389,你可以直接在本地远程桌面客户端填要连接的地址为:

    10.0.0.1-3389.gonc.cc:3080
    

    该域名会被解析为类似127.b.c.d的IP,因此远程桌面客户端会连入本地的socks5代理端口3080,然后gonc根据连接一端的127.b.c.d地址去反解析出域名中的10.0.0.1-3389这个信息。

灵活服务配置

  • -exec可灵活的设置为每个连接提供服务的应用程序,除了指定/bin/bash这种提供shell命令的方式,也可以用来端口转发流量,不过下面这种每个连接进来就会开启一个新的gonc进程:
    gonc -keep-open -exec "gonc -tls www.baidu.com 443" -l 8000
  • 避免大量子进程,使用内置命令方式调用nc模块:
    gonc -keep-open -exec ":nc -tls www.baidu.com 443" -l 8000

Socks5 代理服务

  • 配置客户端模式:

    gonc -x s.s.s.s:port x.x.x.x 1234
  • 内置 Socks5 服务端,使用-e :s5s提供socks5标准服务,支持-auth设置一个socks5的账号密码,用-keep-open可提供持续接受客户端连入socks5服务器,受益于golang的协程,可以获得不错的多客户端并发性能:

    gonc -e ":s5s -auth user:passwd" -keep-open -l 1080
  • 使用高安全性 Socks5 over TLS,由于标准socks5是不加密的,我们可使用-e :s5s,结合-tls-psk定制高安全性的socks5 over tls通讯,使用-P统计连接传输信息,还可以使用-acl对接入和代理目的地实现访问控制。acl.txt文件格式详见acl-example.txt

    gonc.exe -tls -psk randomString -e :s5s -keep-open -acl acl.txt -P -l 1080

    另一端使用:nc把socks5 over tls转为标准socks5,在本地127.0.0.1:3080提供本地客户端接入

    gonc.exe -e ":nc -tls -psk randomString x.x.x.x 1080" -keep-open -l -local 127.0.0.1:3080

多服务监听模式

  • 参考SSH的22端口,既可提供shell也提供sftp和端口转发功能,gonc使用 -e ":service" 也可监听在一个服务端口,基于tls+psk安全认证提供shell、socks5(支持CONNECNT+BIND)和文件服务。(请务必使用gonc -psk .生成高熵PSK替换randomString)

    gonc -k -l -local :2222 -tls -psk randomString -e ":service" -:sh "/bin/bash" -:s5s "-c -b" -:mux "httpserver /"

    另一端使用获得shell

    gonc -tls -psk randomString -remote <server-ip>:2222 -call :sh -pty

    另一端把socks5 over tls转为本地标准socks5端口1080

    gonc -e ":nc -tls -psk randomString -call :s5s <server-ip> 2222" -k -P -l -local 127.0.0.1:1080

    另一端把文件服务为本地标准HTTP端口8000

    gonc -tls -psk randomString -remote <server-ip>:2222 -call :mux -httplocal-port 8000

给其他应用建立通道

  • 帮WireGuard打洞组VPN

    在被动等待连接的PC-S运行下面的参数(直接拿节点公钥来当口令,接口的监听端口51820):

    gonc -p2p PS-S的公钥 -mqtt-wait -u -k -e ":nc -u 127.0.0.1 51820"

    其他发起主动连接的PC-C,设置WireGuard节点PS-S公钥的Endpoint = 127.0.0.1:51821,接口的监听端口51820,gonc运行下面的参数,-k可以让gonc在网络异常后自动重新建立连接。

    gonc -p2p PS-S的公钥 -mqtt-hello -u -k -e ":nc -u -local 127.0.0.1:51821 127.0.0.1 51820"

P2P NAT 穿透能力

gonc如何建立P2P?

  • 并发使用多个公用 STUN 服务,探测本地的 TCP / UDP NAT 映射,并智能识别 NAT 类型
  • 通过基于口令(SessionKey)派生的哈希作为 MQTT 共享话题,借助公用 MQTT 服务安全交换地址信息
  • 按优先级顺序尝试直连:IPv6 TCP > IPv4 TCP > IPv4 UDP,尽可能实现真正的点对点通信
  • 没有设立中转服务器,不提供备用转发模式:要么连接失败,要么成功就是真的P2P

如何部署中转服务器适应实在无法P2P的条件?

  • 一个公网IP上支持UDP ASSOCIATE的Socks5服务器就可以,也可以用自己的VPS,运行gonc本身的socks5代理服务器便可让其成为中转服务器。

    下面命令启动了仅支持UDP转发功能的socks5代理,-psk和-tls开启了加密和PSK口令认证。注意防火墙不能只开放1080,因为每次提供转发的UDP端口是随机。

    gonc -e ":s5s -u -c=0" -psk 口令 -tls -k -l 1080

  • P2P遇到困难的时候,只需要有一端的gonc使用-x参数再进行P2P就可以。你也可以把-x换为-x2,这样就是先P2P,失败了再尝试用中转

    gonc -p2p randomString -x "-psk 口令 -tls <socks5server-ip>:1080"

  • 下面例子是使用标准的socks5代理服务器(需服务器支持UDP)。

    gonc -p2p randomString -x "<socks5server-ip>:1080" -auth "user:password"

例如原本两端都是对称型NAT,无法P2P,现在一端使用了socks5代理(UDP模式),就相当于转为容易型的NAT了,于是就能很容易和其他建立连接,数据加密仍然是端到端的。

内置的公用服务器(STUN和MQTT):

	"tcp://turn.cloudflare.com:80",
	"udp://turn.cloudflare.com:53",
	"udp://stun.l.google.com:19302",
	"udp://stun.miwifi.com:3478",
	"global.turn.twilio.com:3478",
	"stun.nextcloud.com:443",

	"tcp://broker.hivemq.com:1883",
	"tcp://broker.emqx.io:1883",
	"tcp://test.mosquitto.org:1883",

gonc的NAT穿透成功率如何?

除了两端都是对称类型的情况,其他都有非常高的成功率

gonc将NAT类型分为3种:

当固定一个内网端口去访问多个STUN服务器,根据多个STUN服务器反馈的地址研判:

  1. 容易型:NAT端口与内网端口都是保持不变的
  2. 困难型:NAT端口都变为另一个共同的端口号,相对1困难。
  3. 对称型:NAT端口每个都不一样,算是最困难的类型

针对这些类型,gonc采用了如下一些NAT穿透策略:

  • 使用多个STUN服务器(涵盖国内外和TCP/UDP协议)检测NAT地址并研判NAT类型,以及发现多IP出口的网络环境
  • 双方都有ipv6地址时优先使用ipv6地址建立直连
  • 有一端是容易型的才建立TCP P2P,因为与STUN服务器的TCP一旦断开容易影响这个洞,而确定是容易型后可以直接约定新的端口号,并避开使用与STUN服务器连接的源端口
  • TCP两端都处于监听状态,复用端口,并相互dial对方建立直连
  • 相对容易的一端延迟UDP发包,避免触发困难端的洞(端口号)变更
  • 相对困难的一端使用小TTL值UDP包,降低触发对端的洞的防火墙策略
  • 使用生日悖论,当简单策略无法打通时,相对困难的一端使用600个随机源端口,与另一端使用600个随机目的端口进行碰撞。

About

Netcat with automated NAT traversal, secure P2P, and advanced features for shell access, file transfer, and network proxying.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published