一个简单的时序图如下:
原版Js-Forward地址:
https://github.com/G-Security-Team/JS-Forward/
class ForwardRequestHandler(BaseHTTPRequestHandler):
def do_POST(self):
content_length = int(self.headers.get('content-length', 0))
self.send_response(200)
self.send_header('Access-Control-Allow-Origin','*')
self.end_headers()
data = self.rfile.read(content_length)
if str(self.path) == "/REQUEST":
r = requests.request('REQUEST', 'http://127.0.0.1:{}/'.format(ECHO_PORT),
proxies={'http': 'http://127.0.0.1:{}'.format(BURP_PORT)},
data=data)
new_data = r.text
self.wfile.write(new_data.encode('utf8'))
else:
try:
r = requests.request('RESPONSE', 'http://127.0.0.1:{}/'.format(ECHO_PORT),
proxies={'http': 'http://127.0.0.1:{}'.format(BURP_PORT)},
data=data)
new_data = r.text
self.wfile.write(new_data.encode('utf8'))
except:
self.wfile.write(data)
class RequestHandler(BaseHTTPRequestHandler):
def do_REQUEST(self):
content_length = int(self.headers.get('content-length', 0))
self.send_response(200)
self.end_headers()
self.wfile.write(self.rfile.read(content_length))
do_RESPONSE = do_REQUEST
httpserver.Serve("127.0.0.1", 18888, httpserver.handler(func(w, req) {
w.WriteHeader(200)
rawRequest = http.dump(req)~ // 获取完整的请求数据包
body = poc.GetHTTPPacketBody(rawRequest) // 获取请求体
if len(body) > 0{
w.Write(body)
}
}))
varname = cli.String("varname", cli.setVerboseName("参数名"), cli.setRequired(true), cli.setHelp("要转发的参数名"))
vartyp = cli.StringSlice("vartyp", cli.setVerboseName("变量类型"), cli.setRequired(true), cli.setSelectOption("字符串", "string"), cli.setSelectOption("Json", "json"))
yakit_port = cli.Int("yakit_port", cli.setVerboseName("Yakit MITM端口"), cli.setDefault(8083))
cli.check()
vartyp = vartyp[0]
port = os.GetRandomAvailableTCPPort()
echo_port = os.GetRandomAvailableTCPPort()
jsCode = f`var xhr = new XMLHttpRequest();xhr.open('POST', 'http://127.0.0.1:${port}', false);xhr.send(${varname});${varname}=xhr.responseText;`
if vartyp == "json" {
jsCode = f`var xhr = new XMLHttpRequest();xhr.open('POST', 'http://127.0.0.1:${port}', false);xhr.send(JSON.stringify(${varname}));${varname}=JSON.parse(xhr.responseText);`
}
yakit.Info("将上述代码复制到找到的加密函数开头,变量定义之后(需要注意的是变量是否为常量,如果是常量则要改成变量)")
yakit.Code(jsCode)
getbody = func(req) {
r = req.Body
body, _ = io.ReadAll(r)
return body
}
go httpserver.Serve("127.0.0.1", echo_port, httpserver.handler(func(w, req) {
w.WriteHeader(200)
body = getbody(req)
if len(body) > 0{
w.Write(body)
}
}))
go httpserver.Serve("127.0.0.1", port, httpserver.handler(func(w, req) {
opts = []
body = getbody(req)
opts.Append(poc.replaceBody(body, false), poc.proxy(f"http://127.0.0.1:${yakit_port}"))
rsp, _, err = poc.Post(f`http://127.0.0.1:${echo_port}`, opts...)
if err != nil {
yakit.Error(err.Error())
return
}
origin = req.Header["Origin"]
if len(origin) > 0 {
w.Header().Set("Access-Control-Allow-Origin", origin[0])
}
w.WriteHeader(200)
w.Write(rsp.GetBody())
}))
ch = make(chan any)
<-ch
使用cli库我们可以很轻松地获取用户的输入
需要判断变量类型来对变量进行额外处理(JSON.Parse/JSON.stringify)
http服务器要额外处理CORS的问题,将origin原封不动写回去即可,否则响应会被浏览器的CORS策略拦截。
END
YAK官方资源
Yak 语言官方教程:
https://yaklang.com/docs/intro/
Yakit 视频教程:
https://space.bilibili.com/437503777
Github下载地址:
https://github.com/yaklang/yakit
Yakit官网下载地址:
https://yaklang.com/
Yakit安装文档:
https://yaklang.com/products/download_and_install
Yakit使用文档:
https://yaklang.com/products/intro/
常见问题速查:
https://yaklang.com/products/FAQ