Skip to content

Instantly share code, notes, and snippets.

@elico
Created January 27, 2016 17:54
Show Gist options
  • Select an option

  • Save elico/ec9768dfb62e8530c130 to your computer and use it in GitHub Desktop.

Select an option

Save elico/ec9768dfb62e8530c130 to your computer and use it in GitHub Desktop.
shadowd_con.go
package main
import (
"crypto/hmac"
"crypto/sha256"
"fmt"
"github.com/elico/mux"
"io/ioutil"
"net"
"net/http"
"encoding/hex"
"encoding/json"
"strings"
)
const (
SHADOWD_CONNECTOR_VERSION = "2.0.1-go"
SHADOWD_CONNECTOR_CONFIG = "/etc/shadowd/go-connector.ini"
SHADOWD_CONNECTOR_CONFIG_SECTION = "shadowd_go"
SHADOWD_LOG = "/var/log/shadowd.log"
STATUS_OK = 1
STATUS_BAD_REQUEST = 2
STATUS_BAD_SIGNATURE = 3
STATUS_BAD_JSON = 4
STATUS_ATTACK = 5
STATUS_CRITICAL_ATTACK = 6
)
var VERSION = "2.0.1"
func escapeKey(key string)string{
newstr := strings.Replace(key, "/", "\\/" ,-1)
newstr = strings.Replace(newstr, "|", "\\|",-1)
return newstr
}
func unescapeKey(key string)string{
newstr := strings.Replace(key,"\\\\","\\",-1)
newstr = strings.Replace(newstr, "\\|","|",-1)
return newstr
}
func httpHandlerToHandlerShadowd(next http.Handler) http.Handler {
return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
newmap := make(map[string]interface{})
inputmap := make(map[string]string)
newmap["version"] = SHADOWD_CONNECTOR_VERSION
newmap["client-ip"] = strings.Split(req.RemoteAddr, ":")[0]
newmap["caller"] = escapeKey(req.URL.Path)
newmap["resource"] = escapeKey(req.URL.Path)
for k, v := range req.URL.Query() {
for _, s := range v {
inputmap[req.Method+"|"+k] = escapeKey(s)
}
}
coockie := req.Cookies()
for _, v := range coockie {
inputmap["COOKIE|" + strings.Replace(strings.ToUpper(v.Name), "-","_", -1)] = v.Value
}
inputmap["SERVER|HTTP_COOKIE"] = ""
for _, v := range coockie {
inputmap["SERVER|HTTP_COOKIE"] = inputmap["SERVER|HTTP_COOKIE"] + v.Name +"="+v.Value+"; "
}
headers := req.Header
for k, v := range headers {
inputmap["SERVER|HTTP_" + strings.Replace(strings.ToUpper(k), "-","_", -1)] = escapeKey(strings.Join(v, ""))
}
if req.Method != "GET" {
contents, err := ioutil.ReadAll(req.Body)
if err != nil {
fmt.Println(err)
} else {
inputmap["DATA|raw"] = string(contents)
}
}
host, port, _ := net.SplitHostPort(req.Host)
inputmap["SERVER|HTTP_HOST"] = host
inputmap["SERVER|HTTP_PORT"] = port
newmap["input"] = inputmap
//fmt.Println(inputmap)
//inputmap["DATA|raw"] = // Request body string
jsonData, _ := json.Marshal(inputmap)
//jsonData, _ := json.MarshalIndent(inputmap, "", " ")
// fmt.Println(string(jsonData))
mac := hmac.New(sha256.New, nil)
mac.Write([]byte(unescapeKey(string(jsonData))))
hash := make(map[string]string)
expectedMAC := hex.EncodeToString(mac.Sum(nil))
hash["sha256"] = expectedMAC
newmap["hashes"] = hash
//fmt.Println(expectedMAC)
jsonData, _ = json.Marshal(newmap)
mac = hmac.New(sha256.New, nil)
newjson := []byte(unescapeKey(string(jsonData)))
mac.Write(newjson)
expectedMAC = hex.EncodeToString(mac.Sum(nil))
fmt.Printf("2\n%v\n%v\n", expectedMAC, string(newjson))
//json_data = json.dumps(input_data)
// json_hmac = self.sign(key, json_data)
// connection.sendall(str(profile) + "\n" + json_hmac + "\n" + json_data + "\n")
//send the fomratted string into the shadowd server at port 9115
servAddr := "192.168.10.194:9115"
tcpAddr, err := net.ResolveTCPAddr("tcp", servAddr)
if err != nil {
println("ResolveTCPAddr failed:", err.Error())
}
conn, err := net.DialTCP("tcp", nil, tcpAddr)
fmt.Fprintf(conn, "2\n%s\n%s\n", expectedMAC, string(jsonData))
reply := make([]byte, 2048)
_, err = conn.Read(reply)
if err != nil {
println("Write to server failed:", err.Error())
}
//fmt.Println(returned)
fmt.Println("reply from server=", string(reply))
conn.Close()
next.ServeHTTP(res, req)
return
})
}
func main() {
router := mux.NewRouter().StrictSlash(true)
router.PathPrefixWithName("/").Handler((http.StripPrefix("/", http.FileServer(http.Dir("fs/")))))
err := http.ListenAndServe(":8090", httpHandlerToHandlerShadowd(router))
if strings.Contains(err.Error(), "resource temporarily unavailable") {
fmt.Println("### unavaliable ###")
fmt.Println(err)
return
}
if err != nil {
panic(err.Error())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment