diff --git a/README.md b/README.md index ad75ed4..df44358 100644 --- a/README.md +++ b/README.md @@ -5,14 +5,13 @@

- -![Language](https://img.shields.io/badge/Language-Go-blue.svg?longCache=true&style=flat-square) ![License](https://img.shields.io/badge/License-MIT-purple.svg?longCache=true&style=flat-square) - +![Language](https://img.shields.io/badge/Language-Go-blue.svg?longCache=true&style=flat-square) ![License](https://img.shields.io/badge/License-MIT-purple.svg?longCache=true&style=flat-square) ## Introduction + GodSpeed is a robust and intuitive manager for reverse shells. -It supports tab-completion, verbose listing of connected hosts and easy interaction with selected shells by passing their corresponding ID. +It supports tab-completion, verbose listing of connected hosts and easy interaction with selected shells by passing their corresponding ID. ## Basic usage @@ -20,7 +19,7 @@ When no options are used, the reverse listener is launched on port 4444 and the Listening port can be specified with `--port` flag. The full address of the listening server can be copied to clipboard with `--clip`. -From the prompt, you can list connected shells with `list` command, interact with them using `interact ... ` and see if each connection is alive with `check` command. +From the prompt, you can list connected shells with `list` command, interact with them using `interact ... ` and see if each connection is alive with `check` command. Running `check -r` will remove dead connections from the pool. @@ -28,17 +27,8 @@ Running `interact *` will set status of every connected shell as active. Running `interact -r ` sets status of selected ID as inactive (this connection will not receive entered commands). -## Requirements - - github.com/akamensky/argparse - github.com/olekukonko/tablewriter - github.com/atotto/clipboard - github.com/c-bata/go-prompt - github.com/common-nighthawk/go-figure - github.com/fatih/color - github.com/redcode-labs/Coldfire - github.com/taion809/haikunator ## Screenshots +

@@ -50,6 +40,6 @@ Running `interact -r ` sets status of selected ID as inactive (this connecti

- ## License -This software is under [MIT License](https://en.wikipedia.org/wiki/MIT_License) \ No newline at end of file + +This software is under [MIT License](https://en.wikipedia.org/wiki/MIT_License) diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..eec0412 --- /dev/null +++ b/go.mod @@ -0,0 +1,31 @@ +module github.com/redcode-labs/GodSpeed + +go 1.17 + +require ( + github.com/akamensky/argparse v1.3.1 + github.com/atotto/clipboard v0.1.4 + github.com/c-bata/go-prompt v0.2.6 + github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be + github.com/fatih/color v1.12.0 + github.com/olekukonko/tablewriter v0.0.5 + github.com/redcode-labs/Coldfire v0.0.0-20210817224707-ed9e88190bc7 + github.com/savaki/jq v0.0.0-20161209013833-0e6baecebbf8 + github.com/taion809/haikunator v0.0.0-20150324135039-4e414e676fd1 +) + +require ( + github.com/anvie/port-scanner v0.0.0-20180225151059-8159197d3770 // indirect + github.com/google/gopacket v1.1.19 // indirect + github.com/jackpal/gateway v1.0.7 // indirect + github.com/matishsiao/goInfo v0.0.0-20200404012835-b5f882ee2288 // indirect + github.com/mattn/go-colorable v0.1.8 // indirect + github.com/mattn/go-isatty v0.0.13 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/mattn/go-tty v0.0.3 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/go-ps v1.0.0 // indirect + github.com/pkg/term v1.2.0-beta.2 // indirect + github.com/rivo/uniseg v0.2.0 // indirect + golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..a101d4b --- /dev/null +++ b/go.sum @@ -0,0 +1,76 @@ +github.com/akamensky/argparse v1.3.1 h1:kP6+OyvR0fuBH6UhbE6yh/nskrDEIQgEA1SUXDPjx4g= +github.com/akamensky/argparse v1.3.1/go.mod h1:S5kwC7IuDcEr5VeXtGPRVZ5o/FdhcMlQz4IZQuw64xA= +github.com/anvie/port-scanner v0.0.0-20180225151059-8159197d3770 h1:1KEvfMGAjISVzk3Ti6pfaOgtoC3naoU0LfiJooZDNO8= +github.com/anvie/port-scanner v0.0.0-20180225151059-8159197d3770/go.mod h1:QGzdstKeoHmMWwi9oNHZ7DQzEj9pi7H42171pkj9htk= +github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= +github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= +github.com/c-bata/go-prompt v0.2.6 h1:POP+nrHE+DfLYx370bedwNhsqmpCUynWPxuHi0C5vZI= +github.com/c-bata/go-prompt v0.2.6/go.mod h1:/LMAke8wD2FsNu9EXNdHxNLbd9MedkPnCdfpU9wwHfY= +github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be h1:J5BL2kskAlV9ckgEsNQXscjIaLiOYiZ75d4e94E6dcQ= +github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be/go.mod h1:mk5IQ+Y0ZeO87b858TlA645sVcEcbiX6YqP98kt+7+w= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc= +github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= +github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= +github.com/jackpal/gateway v1.0.7 h1:7tIFeCGmpyrMx9qvT0EgYUi7cxVW48a0mMvnIL17bPM= +github.com/jackpal/gateway v1.0.7/go.mod h1:aRcO0UFKt+MgIZmRmvOmnejdDT4Y1DNiNOsSd1AcIbA= +github.com/matishsiao/goInfo v0.0.0-20200404012835-b5f882ee2288 h1:cdM7et8/VlNnSBpq3KbyQWsYLCY0WsB7tvV8Fr0DUNE= +github.com/matishsiao/goInfo v0.0.0-20200404012835-b5f882ee2288/go.mod h1:yLZrFIhv+Z20hxHvcZpEyKVQp9HMsOJkXAxx7yDqtvg= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA= +github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-tty v0.0.3 h1:5OfyWorkyO7xP52Mq7tB36ajHDG5OHrmBGIS/DtakQI= +github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= +github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/pkg/term v1.2.0-beta.2 h1:L3y/h2jkuBVFdWiJvNfYfKmzcCnILw7mJWm2JQuMppw= +github.com/pkg/term v1.2.0-beta.2/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw= +github.com/redcode-labs/Coldfire v0.0.0-20210817224707-ed9e88190bc7 h1:rfN4lS4OcJg/+Vn372wVNcf8phs7eYVIpk/tYcgjGec= +github.com/redcode-labs/Coldfire v0.0.0-20210817224707-ed9e88190bc7/go.mod h1:buh7ehR7oHyb5Ytiu/nfWtVdCxTXkDzcTgE/Gz6P9P4= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/savaki/jq v0.0.0-20161209013833-0e6baecebbf8 h1:ajJQhvqPSQFJJ4aV5mDAMx8F7iFi6Dxfo6y62wymLNs= +github.com/savaki/jq v0.0.0-20161209013833-0e6baecebbf8/go.mod h1:Nw/CCOXNyF5JDd6UpYxBwG5WWZ2FOJ/d5QnXL4KQ6vY= +github.com/taion809/haikunator v0.0.0-20150324135039-4e414e676fd1 h1:Othyd9BE5Cc1J1FhMKEcZo732qwHjxU1+qFAy9qxyMI= +github.com/taion809/haikunator v0.0.0-20150324135039-4e414e676fd1/go.mod h1:YN59p3Qc11j61wypGtx03FU7uXUpuNfn29TmeCkg9ys= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200918174421-af09f7315aff h1:1CPUrky56AcgSpxz/KfgzQWzfG09u5YOL8MvPYBlrL8= +golang.org/x/sys v0.0.0-20200918174421-af09f7315aff/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf h1:2ucpDCmfkl8Bd/FsLtiD653Wf96cW37s+iGx93zsu4k= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/godspeed.go b/godspeed.go index 6f9d2fc..c8294de 100644 --- a/godspeed.go +++ b/godspeed.go @@ -4,36 +4,23 @@ import ( "fmt" "io" "net" + "net/http" "os" "strconv" "strings" "time" - "io/ioutil" - "net/http" - "github.com/akamensky/argparse" - "github.com/savaki/jq" - "github.com/olekukonko/tablewriter" "github.com/atotto/clipboard" "github.com/c-bata/go-prompt" "github.com/common-nighthawk/go-figure" "github.com/fatih/color" - . "github.com/redcode-labs/Coldfire" + tw "github.com/olekukonko/tablewriter" + cf "github.com/redcode-labs/Coldfire" + "github.com/savaki/jq" "github.com/taion809/haikunator" ) -var red = color.New(color.FgRed).SprintFunc() -var green = color.New(color.FgGreen).SprintFunc() -var cyan = color.New(color.FgCyan).SprintFunc() -var bold = color.New(color.Bold).SprintFunc() -var yellow = color.New(color.FgYellow).SprintFunc() -var magenta = color.New(color.FgMagenta).SprintFunc() - -var implants []*Implant -var active_ids []int -var base_id = 0 - type Implant struct { name string id int @@ -42,6 +29,19 @@ type Implant struct { conn net.Conn } +var ( + red = color.New(color.FgRed).SprintFunc() + green = color.New(color.FgGreen).SprintFunc() + cyan = color.New(color.FgCyan).SprintFunc() + bold = color.New(color.Bold).SprintFunc() + yellow = color.New(color.FgYellow).SprintFunc() + magenta = color.New(color.FgMagenta).SprintFunc() +) + +var implants []*Implant +var active_ids []int +var base_id = 0 + func f(s string, arg ...interface{}) string { return fmt.Sprintf(s, arg...) } @@ -106,11 +106,11 @@ func update_prompt_prefix() (string, bool) { func SendData(data string) { for _, implant := range implants { - if Contains(active_ids, implant.id) { + if cf.Contains(active_ids, implant.id) { _, err := io.WriteString(implant.conn, data+"\n") if err != nil { p() - PrintError(f("Unable to send data to ID:%d: %s", implant.id, red(err.Error()))) + cf.PrintError(f("Unable to send data to ID:%d: %s", implant.id, red(err.Error()))) p() } } @@ -167,10 +167,10 @@ func StartCommandPrompt() { word := "" remove := false interact_all := false - if ContainsAny("*", elements) { + if cf.ContainsAny("*", elements) { interact_all = true } - if ContainsAny("-r", elements) { + if cf.ContainsAny("-r", elements) { remove = true } if l == 1 { @@ -182,22 +182,22 @@ func StartCommandPrompt() { p() } else { ids := elements[1:] - ids = RemoveStr(ids, "*") - ids = RemoveStr(ids, "-r") + ids = cf.RemoveStr(ids, "*") + ids = cf.RemoveStr(ids, "-r") if remove { word = f("%d", len(ids)) if interact_all { word = "all" } for _, id := range ids { - i := StrToInt(id) - active_ids = RemoveInt(active_ids, i) + i := cf.StrToInt(id) + active_ids = cf.RemoveInt(active_ids, i) } if interact_all { active_ids = []int{} } p() - PrintInfo(f("Removed %s implants from active pool", red(word))) + cf.PrintInfo(f("Removed %s implants from active pool", red(word))) p() } else { active_ids = []int{} @@ -210,14 +210,14 @@ func StartCommandPrompt() { ids = []string{} } for _, id := range ids { - i := StrToInt(id) + i := cf.StrToInt(id) active_ids = append(active_ids, i) } p() - PrintInfo(f("Added %s agents to active pool", green(word))) + cf.PrintInfo(f("Added %s agents to active pool", green(word))) p() } - active_ids = RemoveDuplicatesInt(active_ids) + active_ids = cf.RemoveDuplicatesInt(active_ids) } case "list": parser := argparse.NewParser("list", "Show available implants") //, usage_prologue) @@ -225,54 +225,54 @@ func StartCommandPrompt() { err := parser.Parse(elements) if err != nil { p() - PrintError(parser.Usage(err)) + cf.PrintError(parser.Usage(err)) p() - } else if ! ContainsAny(cmd, []string{"-h"}) { + } else if !cf.ContainsAny(cmd, []string{"-h"}) { if len(implants) != 0 { p() - PrintInfo(bold(green(len(implants))) + " implants connected") + cf.PrintInfo(bold(green(len(implants))) + " implants connected") p() sep := "==================================================" if *vertical { fmt.Println(sep) } - table := tablewriter.NewWriter(os.Stdout) - table.SetHeader([]string{"ID", "STATUS", "NAME", "TIME", "IP"}) - table.SetCenterSeparator("|") - table.SetRowSeparator("-") - table.SetAlignment(tablewriter.ALIGN_CENTER) + tb := tw.NewWriter(os.Stdout) + tb.SetHeader([]string{"ID", "STATUS", "NAME", "TIME", "IP"}) + tb.SetCenterSeparator("|") + tb.SetRowSeparator("-") + tb.SetAlignment(tw.ALIGN_CENTER) for _, implant := range implants { status := red(bold("(x)")) - if Contains(active_ids, implant.id) { + if cf.Contains(active_ids, implant.id) { status = green(bold("(+)")) } if implant.id != -1 { if *vertical { - fmt.Println("ID -> " + cyan(IntToStr(implant.id))) + fmt.Println("ID -> " + cyan(cf.IntToStr(implant.id))) fmt.Println("NAME -> " + red(implant.name)) fmt.Println("STATUS -> " + status) fmt.Println("TIME -> " + implant.time) fmt.Println("IP -> " + implant.ip) fmt.Println(sep) } else { - data := [][]string{[]string{cyan(implant.id), status, magenta(implant.name), implant.time, implant.ip}} + data := [][]string{{cyan(implant.id), status, magenta(implant.name), implant.time, implant.ip}} for v := range data { - table.Append(data[v]) + tb.Append(data[v]) } } } } - table.Render() + tb.Render() p() } else { p() - PrintError("No implants connected") + cf.PrintError("No implants connected") p() } } case "exit": - PrintInfo("Exiting...") - CmdBlind("pkill -9 ngrok") + cf.PrintInfo("Exiting...") + cf.CmdBlind("pkill -9 ngrok") os.Exit(0) case "check": parser := argparse.NewParser("check", "Check connectivity of active hosts") //, usage_prologue) @@ -282,52 +282,52 @@ func StartCommandPrompt() { err := parser.Parse(elements) if err != nil { p() - PrintError(err.Error()) + cf.PrintError(err.Error()) p() - } else if !ContainsAny(cmd, []string{"-h"}) { + } else if !cf.ContainsAny(cmd, []string{"-h"}) { header := []string{"--ID--", "--NAME--", "--STATUS--"} data := [][]string{} num_errors := 0 if len(implants) != 0 { for _, implant := range implants { status := "" - for i := 0; i < *num; i++{ + for i := 0; i < *num; i++ { err := SendDataConn(implant.conn, "echo aa > /dev/null") - if err != nil{ + if err != nil { num_errors += 1 } - } + } if num_errors != 0 { - // print_info(f("Implant #%d (%s) is %s", implant.id, magenta(implant.name), red("UNREACHABLE"))) + // print_info(f("Implant #%d (%s) is %s", implant.id, magenta(implant.name), red("UNREACHABLE"))) status = red("UNREACHABLE") SendDataConn(implant.conn, "exit:") if *remove { - active_ids = RemoveInt(active_ids, implant.id) + active_ids = cf.RemoveInt(active_ids, implant.id) implants = RemoveImplant(implants, implant) } } else { status = green("CONNECTED") //print_info(f("Implant #%d (%s) is %s", implant.id, magenta(implant.name), green("CONNECTED"))) } - data = append(data, []string{cyan(implant.id), - magenta(implant.name), - status}) + data = append(data, []string{cyan(implant.id), + magenta(implant.name), + status}) } - table := tablewriter.NewWriter(os.Stdout) - table.SetHeader(header) - table.SetCenterSeparator("*") - table.SetRowSeparator("-") - table.SetAlignment(tablewriter.ALIGN_CENTER) + tb := tw.NewWriter(os.Stdout) + tb.SetHeader(header) + tb.SetCenterSeparator("*") + tb.SetRowSeparator("-") + tb.SetAlignment(tw.ALIGN_CENTER) for v := range data { - table.Append(data[v]) + tb.Append(data[v]) } p() - PrintInfo(f("Checking connectivity of %d implants...", len(implants))) - table.Render() + cf.PrintInfo(f("Checking connectivity of %d implants...", len(implants))) + tb.Render() p() } else { p() - PrintError("No implants connected") + cf.PrintError("No implants connected") p() } } @@ -340,18 +340,18 @@ func StartCommandPrompt() { func StartTunnel(port string) (string, string) { //regions := []string{"us", "eu", "ap", "au", "sa", "jp", "in"} //selected_region := RandomSelectStr(regions) - go CmdBlind("ngrok tcp "+port) + go cf.CmdBlind("ngrok tcp " + port) time.Sleep(2 * time.Second) local_url := "http://localhost:4040/api/tunnels" resp, err := http.Get(local_url) if err != nil { - PrintError("Cannot obtain tunnel's address -> "+err.Error()) + cf.PrintError("Cannot obtain tunnel's address -> " + err.Error()) os.Exit(0) } defer resp.Body.Close() - json, err := ioutil.ReadAll(resp.Body) + json, err := io.ReadAll(resp.Body) if err != nil { - PrintError("Cannot obtain tunnel's address -> "+err.Error()) + cf.PrintError("Cannot obtain tunnel's address -> " + err.Error()) os.Exit(0) } jq_op_1, _ := jq.Parse(".tunnels") @@ -364,10 +364,10 @@ func StartTunnel(port string) (string, string) { main_url = strings.Replace(main_url, `tcp://`, "", -1) tunnel_addr := strings.Split(main_url, ":")[0] tunnel_port := strings.Split(main_url, ":")[1] - t_ip, err := DnsLookup(tunnel_addr) + t_ip, err := cf.DnsLookup(tunnel_addr) tunnel_ip := t_ip[0] if err != nil { - PrintError(F("Cannot perform DNS lookup for %s: %s", Red(tunnel_ip), err.Error())) + cf.PrintError(cf.F("Cannot perform DNS lookup for %s: %s", cf.Red(tunnel_ip), err.Error())) } return tunnel_ip, tunnel_port } @@ -378,14 +378,14 @@ func StartServer(proto, port string) { for { connection, err := listener.Accept() fmt.Println("") - ExitOnError(err) + cf.ExitOnError(err) //fmt.Println("[*] Connection from: ", green(bold(conn.RemoteAddr()))) n := Haikunate() dt := time.Now() t := dt.Format("15:04") addr := strings.Split(connection.RemoteAddr().String(), ":")[0] p() - PrintGood(fmt.Sprintf("Received connection from: %s (%s)", green(bold(addr)), magenta(n))) + cf.PrintGood(fmt.Sprintf("Received connection from: %s (%s)", green(bold(addr)), magenta(n))) p() implant := &Implant{ conn: connection, @@ -413,19 +413,19 @@ func main() { var clip *bool = parser.Flag("c", "clip", &argparse.Options{Required: false, Help: "Copy listening C2 address to clipboard"}) var tunnel *bool = parser.Flag("t", "tunnel", &argparse.Options{Required: false, Help: "Expose C2 server using Ngrok tunnel"}) err := parser.Parse(os.Args) - ExitOnError(err) - c2_addr := GetLocalIp() + ":" + *port - if *tunnel{ + cf.ExitOnError(err) + c2_addr := cf.GetLocalIp() + ":" + *port + if *tunnel { t_addr, t_port := StartTunnel(*port) c2_addr = t_addr + ":" + t_port - PrintInfo("Started tunnel") + cf.PrintInfo("Started tunnel") } p() - PrintInfo(F("Started reverse handler %s", cyan(bold("["+c2_addr+"]")))) + cf.PrintInfo(cf.F("Started reverse handler %s", cyan(bold("["+c2_addr+"]")))) p() if *clip { clipboard.WriteAll(c2_addr) - PrintInfo("Copied server address to clipboard") + cf.PrintInfo("Copied server address to clipboard") p() } StartServer("tcp", *port)