通过上述的流程,我们就可以简单理解示例程序了
func main() {
// 在所有接口上绑定TCP端口20080,启动监听服务
listener, err := net.Listen("tcp", ":20080")
// 判断监听服务是否启动,否则抛出异常
if err != nil {
log.Fatalln("Unable to Bind to port")
}
// 打印语句,成功监听
log.Println("Listening on localhost:20080")
// 无限循环,等待客户端进行连接
for {
// 等待连接,创建与返回net.Conn
conn, err := listener.Accpet()
log.Println("Reveived connection")
if err != nil {
log.Fatalln("Unable to accept connection")
}
// 处理连接,使用goroutine实现并发
go handle(conn)
}
}
代理TCP客户端
func handle(src net.Conn) {
dst, err := net.Dial("tcp", "targethost:80")
if err != nil {
log.Fatalln("Unable to connect to host")
}
defer dst.Close()
go func() {
// 将源的输出复制到目标
// io.Copy(dst Writer, src Reader)
// 将Reader读取到的数据复制到Writer
if _, err := io.Copy(dst, src); err != nil {
log.Fatalln(err)
}
}()
// 将目标的输出复制回源
if _, err := io.Copy(src, dst); err != nil{
log.Fatalln(err)
}
}
复现Netcat命令执行
Netcat,命令行网络工具,用来在两台机器之间建立TCP/UDP连接,相比Telnet更灵活且可以编写脚本
"安全巨洞"
nc -lp port -e /bin/bash
// 命令在port端口创建一个监听器,任何可能通过Telnet连接的远程客户端都可以执行任意bash命令
// Netcat允许在程序编译期间根据需要添加此功能
Go:os/exec包
可以运行操作系统命令
定义了一种名为Cmd的类型,包含运行命令以及操作stdin(Reader)和stdout(Writer)所需的方法和属性
创建实例
// Command(name string, arg...string)
cmd := exec.Command("/bin/sh", "-i")
Reader和Writer赋给Cmd
cmd.Stdin = conn
cmd.Stdout = conn
使用cmd.Run运行命令
if err := cmd.Run(); err != nil {
// 处理异常
}
io.Pipe()
该函数是Go的同步内存管道,可用于连接Reader和Writer
func Pipe() (*PipeReader, *PipeWriter)
使用PipeReader和PipeWriter可以避免显示刷新writer并同步连接stdout和TCP连接
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。