diff --git a/Plugins/RDP.go b/Plugins/RDP.go index 4e80e1f..2bf9025 100644 --- a/Plugins/RDP.go +++ b/Plugins/RDP.go @@ -15,6 +15,7 @@ import ( "github.com/tomatome/grdp/protocol/tpkt" "github.com/tomatome/grdp/protocol/x224" "log" + "net" "os" "strconv" "strings" @@ -22,29 +23,37 @@ import ( "time" ) +// Brutelist 表示暴力破解的用户名密码组合 type Brutelist struct { user string pass string } +// RdpScan 执行RDP服务扫描 func RdpScan(info *Config.HostInfo) (tmperr error) { if Common.IsBrute { return } - var wg sync.WaitGroup - var signal bool - var num = 0 - var all = len(Common.Userdict["rdp"]) * len(Common.Passwords) - var mutex sync.Mutex + var ( + wg sync.WaitGroup + signal bool + num = 0 + all = len(Common.Userdict["rdp"]) * len(Common.Passwords) + mutex sync.Mutex + ) + + // 创建任务通道 brlist := make(chan Brutelist) port, _ := strconv.Atoi(info.Ports) + // 启动工作协程 for i := 0; i < Common.BruteThread; i++ { wg.Add(1) go worker(info.Host, Common.Domain, port, &wg, brlist, &signal, &num, all, &mutex, Common.Timeout) } + // 分发扫描任务 for _, user := range Common.Userdict["rdp"] { for _, pass := range Common.Passwords { pass = strings.Replace(pass, "{user}", user, -1) @@ -52,6 +61,8 @@ func RdpScan(info *Config.HostInfo) (tmperr error) { } } close(brlist) + + // 等待所有任务完成 go func() { wg.Wait() signal = true @@ -62,16 +73,22 @@ func RdpScan(info *Config.HostInfo) (tmperr error) { return tmperr } -func worker(host, domain string, port int, wg *sync.WaitGroup, brlist chan Brutelist, signal *bool, num *int, all int, mutex *sync.Mutex, timeout int64) { +// worker RDP扫描工作协程 +func worker(host, domain string, port int, wg *sync.WaitGroup, brlist chan Brutelist, + signal *bool, num *int, all int, mutex *sync.Mutex, timeout int64) { defer wg.Done() + for one := range brlist { - if *signal == true { + if *signal { return } go incrNum(num, mutex) + user, pass := one.user, one.pass flag, err := RdpConn(host, domain, user, pass, port, timeout) - if flag == true && err == nil { + + if flag && err == nil { + // 连接成功 var result string if domain != "" { result = fmt.Sprintf("[+] RDP %v:%v:%v\\%v %v", host, port, domain, user, pass) @@ -81,113 +98,147 @@ func worker(host, domain string, port int, wg *sync.WaitGroup, brlist chan Brute Common.LogSuccess(result) *signal = true return - } else { - errlog := fmt.Sprintf("[-] (%v/%v) rdp %v:%v %v %v %v", *num, all, host, port, user, pass, err) - Common.LogError(errlog) } + + // 连接失败 + errlog := fmt.Sprintf("[-] (%v/%v) RDP %v:%v %v %v %v", *num, all, host, port, user, pass, err) + Common.LogError(errlog) } } +// incrNum 线程安全地增加计数器 func incrNum(num *int, mutex *sync.Mutex) { mutex.Lock() - *num = *num + 1 + *num++ mutex.Unlock() } +// RdpConn 尝试RDP连接 func RdpConn(ip, domain, user, password string, port int, timeout int64) (bool, error) { target := fmt.Sprintf("%s:%d", ip, port) - g := NewClient(target, glog.NONE) - err := g.Login(domain, user, password, timeout) - if err == nil { - return true, nil + // 创建RDP客户端 + client := NewClient(target, glog.NONE) + if err := client.Login(domain, user, password, timeout); err != nil { + return false, err } - return false, err + return true, nil } +// Client RDP客户端结构 type Client struct { - Host string // ip:port - tpkt *tpkt.TPKT - x224 *x224.X224 - mcs *t125.MCSClient - sec *sec.Client - pdu *pdu.Client - vnc *rfb.RFB + Host string // 服务地址(ip:port) + tpkt *tpkt.TPKT // TPKT协议层 + x224 *x224.X224 // X224协议层 + mcs *t125.MCSClient // MCS协议层 + sec *sec.Client // 安全层 + pdu *pdu.Client // PDU协议层 + vnc *rfb.RFB // VNC协议(可选) } +// NewClient 创建新的RDP客户端 func NewClient(host string, logLevel glog.LEVEL) *Client { + // 配置日志 glog.SetLevel(logLevel) logger := log.New(os.Stdout, "", 0) glog.SetLogger(logger) + return &Client{ Host: host, } } +// Login 执行RDP登录 func (g *Client) Login(domain, user, pwd string, timeout int64) error { + // 建立TCP连接 conn, err := Common.WrapperTcpWithTimeout("tcp", g.Host, time.Duration(timeout)*time.Second) if err != nil { - return fmt.Errorf("[dial err] %v", err) + return fmt.Errorf("[连接错误] %v", err) } defer conn.Close() glog.Info(conn.LocalAddr().String()) + // 初始化协议栈 + g.initProtocolStack(conn, domain, user, pwd) + + // 建立X224连接 + if err = g.x224.Connect(); err != nil { + return fmt.Errorf("[X224连接错误] %v", err) + } + glog.Info("等待连接建立...") + + // 等待连接完成 + wg := &sync.WaitGroup{} + breakFlag := false + wg.Add(1) + + // 设置事件处理器 + g.setupEventHandlers(wg, &breakFlag, &err) + + wg.Wait() + return err +} + +// initProtocolStack 初始化RDP协议栈 +func (g *Client) initProtocolStack(conn net.Conn, domain, user, pwd string) { + // 创建协议层实例 g.tpkt = tpkt.New(core.NewSocketLayer(conn), nla.NewNTLMv2(domain, user, pwd)) g.x224 = x224.New(g.tpkt) g.mcs = t125.NewMCSClient(g.x224) g.sec = sec.NewClient(g.mcs) g.pdu = pdu.NewClient(g.sec) + // 设置认证信息 g.sec.SetUser(user) g.sec.SetPwd(pwd) g.sec.SetDomain(domain) - //g.sec.SetClientAutoReconnect() + // 配置协议层关联 g.tpkt.SetFastPathListener(g.sec) g.sec.SetFastPathListener(g.pdu) g.pdu.SetFastPathSender(g.tpkt) +} - //g.x224.SetRequestedProtocol(x224.PROTOCOL_SSL) - //g.x224.SetRequestedProtocol(x224.PROTOCOL_RDP) - - err = g.x224.Connect() - if err != nil { - return fmt.Errorf("[x224 connect err] %v", err) - } - glog.Info("wait connect ok") - wg := &sync.WaitGroup{} - breakFlag := false - wg.Add(1) - +// setupEventHandlers 设置PDU事件处理器 +func (g *Client) setupEventHandlers(wg *sync.WaitGroup, breakFlag *bool, err *error) { + // 错误处理 g.pdu.On("error", func(e error) { - err = e - glog.Error("error", e) + *err = e + glog.Error("错误:", e) g.pdu.Emit("done") }) + + // 连接关闭 g.pdu.On("close", func() { - err = errors.New("close") - glog.Info("on close") + *err = errors.New("连接关闭") + glog.Info("连接已关闭") g.pdu.Emit("done") }) + + // 连接成功 g.pdu.On("success", func() { - err = nil - glog.Info("on success") + *err = nil + glog.Info("连接成功") g.pdu.Emit("done") }) + + // 连接就绪 g.pdu.On("ready", func() { - glog.Info("on ready") + glog.Info("连接就绪") g.pdu.Emit("done") }) + + // 屏幕更新 g.pdu.On("update", func(rectangles []pdu.BitmapData) { - glog.Info("on update:", rectangles) + glog.Info("屏幕更新:", rectangles) }) + + // 完成处理 g.pdu.On("done", func() { - if breakFlag == false { - breakFlag = true + if !*breakFlag { + *breakFlag = true wg.Done() } }) - wg.Wait() - return err }