From 9e674c864b25fde82c79524271cf58c8117f1c20 Mon Sep 17 00:00:00 2001 From: Pourliver Date: Wed, 22 May 2019 15:45:36 -0400 Subject: [PATCH] Updated logs for rdp proxy --- modules/events_stream/events_view.go | 13 ++++++++ modules/rdp_proxy/rdp_proxy_event.go | 24 +++++++++++++ modules/rdp_proxy/rdp_proxy_linux_amd64.go | 39 +++++++++++----------- 3 files changed, 57 insertions(+), 19 deletions(-) create mode 100644 modules/rdp_proxy/rdp_proxy_event.go diff --git a/modules/events_stream/events_view.go b/modules/events_stream/events_view.go index c529db58..61fcabc3 100644 --- a/modules/events_stream/events_view.go +++ b/modules/events_stream/events_view.go @@ -10,6 +10,7 @@ import ( "github.com/bettercap/bettercap/session" "github.com/bettercap/bettercap/modules/net_sniff" + "github.com/bettercap/bettercap/modules/rdp_proxy" "github.com/bettercap/bettercap/modules/syn_scan" "github.com/google/go-github/github" @@ -84,6 +85,16 @@ func (mod *EventsStream) viewSnifferEvent(e session.Event) { e.Data.(net_sniff.SnifferEvent).Message) } } +func (mod *EventsStream) viewRDPEvent(e session.Event) { + t := e.Data.(rdp_proxy.RdpProxyEvent) + + fmt.Fprintf(mod.output, "[%s] [%s] [%s -> %s] %s\n", + e.Time.Format(mod.timeFormat), + tui.Green(e.Tag), + tui.Bold(t.Source), + tui.Bold(t.Destination), + t.Message) +} func (mod *EventsStream) viewSynScanEvent(e session.Event) { se := e.Data.(syn_scan.SynScanEvent) @@ -172,6 +183,8 @@ func (mod *EventsStream) View(e session.Event, refresh bool) { mod.viewModuleEvent(e) } else if strings.HasPrefix(e.Tag, "net.sniff.") { mod.viewSnifferEvent(e) + } else if e.Tag == "rdp.proxy" { + mod.viewRDPEvent(e) } else if e.Tag == "syn.scan" { mod.viewSynScanEvent(e) } else if e.Tag == "update.available" { diff --git a/modules/rdp_proxy/rdp_proxy_event.go b/modules/rdp_proxy/rdp_proxy_event.go new file mode 100644 index 00000000..d4247f50 --- /dev/null +++ b/modules/rdp_proxy/rdp_proxy_event.go @@ -0,0 +1,24 @@ +package rdp_proxy + +import ( + "github.com/bettercap/bettercap/session" +) + +type RdpProxyEvent struct { + Source string + Destination string + Message string +} + +func NewRdpProxyEvent(src string, dst string, msg string) RdpProxyEvent { + return RdpProxyEvent{ + Source: src, + Destination: dst, + Message: msg, + } +} + +func (e RdpProxyEvent) Push() { + session.I.Events.Add("rdp.proxy", e) + session.I.Refresh() +} diff --git a/modules/rdp_proxy/rdp_proxy_linux_amd64.go b/modules/rdp_proxy/rdp_proxy_linux_amd64.go index cd381967..072feb10 100644 --- a/modules/rdp_proxy/rdp_proxy_linux_amd64.go +++ b/modules/rdp_proxy/rdp_proxy_linux_amd64.go @@ -162,10 +162,7 @@ func (mod *RdpProxy) isNLAEnforced(target string) (nla bool, err error){ return false, nil } -func (mod *RdpProxy) startProxyInstance(src string, sport string, dst string, dport string) (err error) { - target := fmt.Sprintf("%s:%s", dst, dport) - ips := fmt.Sprintf("[%s:%s -> %s:%s]", src, sport, dst, dport) - +func (mod *RdpProxy) startProxyInstance(client string, target string) (err error) { // 3.1. Create a proxy agent and firewall rules. args := []string{ "-l", fmt.Sprintf("%d", mod.startPort), @@ -181,20 +178,21 @@ func (mod *RdpProxy) startProxyInstance(src string, sport string, dst string, dp if err := cmd.Start(); err != nil { // Wont't handle things like "port already in use" since it happens at runtime mod.Error("PyRDP Start error : %v", err.Error()) - mod.Info("Failed to start PyRDP, won't intercept target %s", ips) + + NewRdpProxyEvent(client, target, "Failed to start PyRDP, won't intercept target").Push() return err } // Use goroutines to keep logging each instance of PyRDP - go mod.filterLogs(ips, stderrPipe) + go mod.filterLogs(client, target, stderrPipe) mod.active[target] = *cmd return } // Filter PyRDP logs to only show those that matches mod.regexp -func (mod *RdpProxy) filterLogs(prefix string, output io.ReadCloser) { +func (mod *RdpProxy) filterLogs(src string, dst string, output io.ReadCloser) { scanner := bufio.NewScanner(output) // For every log in the queue @@ -207,7 +205,7 @@ func (mod *RdpProxy) filterLogs(prefix string, output io.ReadCloser) { // Get last element data := chunks[len(chunks) - 1] - mod.Info("%s %s", prefix, data) + NewRdpProxyEvent(src, dst, fmt.Sprintf("%s", data)).Push() } } } @@ -270,14 +268,14 @@ func (mod *RdpProxy) configureFirewall(enable bool) (err error) { // Fixes a bug that may come up when interrupting the application too quickly. func (mod *RdpProxy) repairFirewall() (err error) { rules := [][]string{ + { "-t", "nat", "-D", "PREROUTING", "-j", "BCAPRDP" }, { "-t", "nat", "-F", "BCAPRDP" }, { "-t", "nat", "-X", "BCAPRDP" }, } + // Force a cleaning of previous rules for _, rule := range rules { - if _, err = core.Exec("iptables", rule); err != nil { - return err - } + core.Exec("iptables", rule); } return } @@ -352,11 +350,10 @@ func (mod *RdpProxy) handleRdpConnection(payload *nfqueue.Payload) int { src, sport := p.NetworkLayer().NetworkFlow().Src().String(), fmt.Sprintf("%s", p.TransportLayer().TransportFlow().Src()) dst, dport := p.NetworkLayer().NetworkFlow().Dst().String(), fmt.Sprintf("%s", p.TransportLayer().TransportFlow().Dst()) - // TODO : Log everything inside the events stream - ips := fmt.Sprintf("[%s:%s -> %s:%s]", src, sport, dst, dport) + client := fmt.Sprintf("%s:%s", src, sport) + target := fmt.Sprintf("%s:%s", dst, dport) if mod.isTarget(dst) { - target := fmt.Sprintf("%s:%s", dst, dport) // 2. Check if the destination IP already has a PyRDP session active, if so, do nothing. if _, ok := mod.active[target]; !ok { @@ -368,8 +365,10 @@ func (mod *RdpProxy) handleRdpConnection(payload *nfqueue.Payload) int { // TODO : Find a way to disconnect user right after stealing credentials. // Start a PyRDP instance to the preconfigured vulnerable host // and forward packets to the target to this host instead - mod.Info("%s Target has NLA enabled and mode REDIRECT, forwarding to the vulnerable host...", ips) - err := mod.startProxyInstance(src, sport, mod.redirectIP.String(), fmt.Sprintf("%d", mod.redirectPort)) + NewRdpProxyEvent(client, target, "Target has NLA enabled and mode REDIRECT, forwarding to the vulnerable host...").Push() + + redirectTarget := fmt.Sprintf("%s:%d", mod.redirectIP.String(), mod.redirectPort) + err := mod.startProxyInstance(client, redirectTarget) if err != nil { // Add an exception in the firewall to avoid intercepting packets to this destination and port @@ -383,13 +382,13 @@ func (mod *RdpProxy) handleRdpConnection(payload *nfqueue.Payload) int { mod.startPort += 1 default: // Add an exception in the firewall to avoid intercepting packets to this destination and port - mod.Info("%s Target has NLA enabled and mode IGNORE, won't intercept", ips) + NewRdpProxyEvent(client, target, "Target has NLA enabled and mode IGNORE, won't intercept").Push() mod.doReturn(dst, dport) } } else { // Starts a PyRDP instance. - if err := mod.startProxyInstance(src, sport, dst, dport); err != nil { + if err := mod.startProxyInstance(client, target); err != nil { // Add an exception in the firewall to avoid intercepting packets to this destination and port mod.doReturn(dst, dport) payload.SetVerdict(nfqueue.NF_DROP) @@ -403,7 +402,8 @@ func (mod *RdpProxy) handleRdpConnection(payload *nfqueue.Payload) int { } } } else { - mod.Info("Non-target, won't intercept %s", ips) + NewRdpProxyEvent(client, target, "Non-target, won't intercept").Push() + // Add an exception in the firewall to avoid intercepting packets to this destination and port mod.doReturn(dst, dport) @@ -424,6 +424,7 @@ func (mod *RdpProxy) Start() error { if mod.Running() { return session.ErrAlreadyStarted(mod.Name()) } else if err := mod.Configure(); err != nil { + mod.Error("%s", err.Error()) return err }