This repository has been archived by the owner on Dec 21, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
proxy.go
233 lines (156 loc) · 5.66 KB
/
proxy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/*
maryo/proxy.go
the proxy that makes this program a reverse proxy
made by that magical 3ds person
written by superwhiskers, licensed under gnu gplv3.
if you want a copy, go to http://www.gnu.org/licenses/
*/
package main
import (
// internals
"fmt"
"log"
"net/http"
"strings"
"time"
"net/http/httputil"
// externals
"github.com/elazarl/goproxy"
)
//"os"
// set this over here for no issues
var config map[string]interface{}
func startProxy(configName string, logging bool) {
// set the terminal title
ttitle("maryo -> proxy")
// get the config data
config = readJSONFile(configName)
// check if we decrypt all connections
decryptAll := config["config"].(map[string]interface{})["decryptOutgoing"].(string)
// check if log file exists
if doesFileExist("maryo-data/proxy.log") == false {
// make it then
createFile("maryo-data/proxy.log")
}
// write current timestamp to log
t := time.Now().Format("20060102150405")
writeFile("maryo-data/proxy.log", fmt.Sprintf("-> started log [%s]\n", t))
// get ip
ip := getIP()
// start the console log
fmt.Printf("-- proxy log --\n")
consoleSequence(fmt.Sprintf("-> local IP address is %s%s%s\n", code("green"), ip, code("reset")))
consoleSequence(fmt.Sprintf("-> hosting proxy on %s:9437%s\n", code("green"), code("reset")))
writeFile("maryo-data/proxy.log", fmt.Sprintf("-> got local ip as %s, hosting on port :9437", ip))
// load that proxy
proxy := goproxy.NewProxyHttpServer()
// set some settings
// http client for use when performing POST requests
httpClient := &http.Client{}
// add the ninty cert and key to the proxy for decrypting
setCA(nintyCert, nintyKey)
// verbose mode can be a little... too verbose
proxy.Verbose = logging
// set up the proxy
// make it always MITM
proxy.OnRequest().HandleConnect(goproxy.AlwaysMitm)
// request handler
proxy.OnRequest().DoFunc(
func(r *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
// log the request
consoleSequence(fmt.Sprintf("-> request to %s%s%s\n", code("green"), r.URL.Host, code("reset")))
writeFile("maryo-data/proxy.log", fmt.Sprintf("-> got request to %s\n", r.URL.Host))
// get prettified request
// define these variables so no errors
var reqData []byte
var err error
// no errors for post requests
if r.Method == "POST" {
// if it is, then tell the dumper it is
reqData, err = httputil.DumpRequest(r, true)
} else {
// otherwise, don't
reqData, err = httputil.DumpRequest(r, false)
}
if err != nil {
// output error
fmt.Printf("[err]: error occurred while dumping http request\n")
fmt.Printf("%s\n", err.Error())
}
// if it is said to be verbose with logging, print request data
if logging == true {
// log the request data, then
fmt.Printf("\n-- request data\n")
fmt.Printf("%s", string(reqData[:]))
fmt.Printf("\n\n")
}
// always log to file
writeFile("maryo-data/proxy.log", fmt.Sprintf("-> request data to %s\n", r.URL.Host))
writeFile("maryo-data/proxy.log", fmt.Sprintf("%s", string(reqData[:])))
writeFile("maryo-data/proxy.log", fmt.Sprintf("\n\n"))
// attempt to proxy it to the servers listed in config
// check if it is in it in the first place
// also, strip the URL of the port
if redirTo, isItIn := config["endpoints"].(map[string]interface{})[strings.Split(r.URL.Host, ":")[0]].(string); isItIn {
// check if we decrypt all outgoing connections
if decryptAll == "true" {
// if protocol is HTTPS
if r.URL.Scheme == "https" {
// let the user know
fmt.Printf("-> switching protocol to http\n")
// set it to HTTP
r.URL.Scheme = "http"
}
}
// log the redirect
consoleSequence(fmt.Sprintf("-> proxying %s%s%s to %s%s%s\n", code("green"), r.URL.Host, code("reset"), code("green"), redirTo, code("reset")))
writeFile("maryo-data/proxy.log", fmt.Sprintf("-> proxying %s to %s", r.URL.Host, redirTo))
// redirect it
r.URL.Host = redirTo
}
// here is a fancy workaround for POST requests
if r.Method == "POST" {
// show the user that we performed a POST request
fmt.Printf("-> performing %s request to %s%s://%s%s%s\n", r.Method, code("green"), r.URL.Scheme, r.URL.Host, r.URL.Path, code("reset"))
// clone the request
newReq := cloneReq(r)
// perform the request
resp, err := httpClient.Do(newReq)
// error handling
if err != nil {
// return a response
return r, goproxy.NewResponse(newReq, goproxy.ContentTypeText, http.StatusBadGateway, strings.Join([]string{"no worries, this is an error in maryo\n", err.Error()}, ""))
}
// dump response
// make these variables earlier on so no errors
var fmtResp []byte
// check if the request is a post request
if r.Method == "POST" {
// if so, tell the dumper that it is one
fmtResp, err = httputil.DumpResponse(resp, true)
} else {
// otherwise, don't
fmtResp, err = httputil.DumpResponse(resp, false)
}
// error handling
if err != nil {
// log the error
fmt.Printf("[err]: error while dumping response")
fmt.Printf("%s\n", err.Error())
}
// make sure the user wants to log response data
if logging == true {
// log it if they do
fmt.Printf("\n-- response data\n")
fmt.Printf("%s\n", string(fmtResp[:]))
fmt.Printf("\n\n")
}
// return the processed response
return r, resp
}
// just return nil for response, since we aren't modifying it
return r, nil
})
// start the proxy
log.Fatal(http.ListenAndServe(":9437", proxy))
}