mirror of
https://github.com/j3ssie/osmedeus.git
synced 2026-09-27 20:14:54 +02:00
228 lines
5.7 KiB
Go
228 lines
5.7 KiB
Go
package execution
|
|
|
|
import (
|
|
"bufio"
|
|
"crypto/tls"
|
|
"encoding/base64"
|
|
"fmt"
|
|
"github.com/j3ssie/osmedeus/libs"
|
|
"github.com/j3ssie/osmedeus/utils"
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/go-resty/resty/v2"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
func SendGET(token string, url string) (libs.Response, error) {
|
|
client := BuildClient(token, 2)
|
|
res, err := JustSend(url, client)
|
|
return res, err
|
|
}
|
|
|
|
// BuildClient build base HTTP client
|
|
func BuildClient(token string, retry int) *resty.Client {
|
|
headers := map[string]string{
|
|
"UserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36",
|
|
"Content-Type": "application/json",
|
|
}
|
|
if token != "" {
|
|
headers["Authorization"] = fmt.Sprintf("Bearer %s", token)
|
|
}
|
|
|
|
timeout := 15
|
|
|
|
//if len(options.Headers) > 0 {
|
|
// for _, head := range options.Headers {
|
|
// if strings.Contains(head, ":") {
|
|
// data := strings.Split(head, ":")
|
|
// if len(data) < 2 {
|
|
// continue
|
|
// }
|
|
// headers[data[0]] = strings.Join(data[1:], "")
|
|
// }
|
|
// }
|
|
//}
|
|
|
|
// disable log when retry
|
|
logger := logrus.New()
|
|
logger.Out = io.Discard
|
|
|
|
client := resty.New()
|
|
client.SetLogger(logger)
|
|
client.SetTransport(&http.Transport{
|
|
MaxIdleConns: 100,
|
|
MaxConnsPerHost: 1000,
|
|
IdleConnTimeout: time.Duration(timeout) * time.Second,
|
|
ExpectContinueTimeout: time.Duration(timeout) * time.Second,
|
|
ResponseHeaderTimeout: time.Duration(timeout) * time.Second,
|
|
TLSHandshakeTimeout: time.Duration(timeout) * time.Second,
|
|
DisableCompression: true,
|
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
|
})
|
|
|
|
client.SetHeaders(headers)
|
|
client.SetCloseConnection(true)
|
|
client.SetRetryCount(retry)
|
|
client.SetTimeout(time.Duration(timeout) * time.Second)
|
|
client.SetRetryWaitTime(time.Duration(timeout/2) * time.Second)
|
|
client.SetRetryMaxWaitTime(time.Duration(timeout) * time.Second)
|
|
return client
|
|
}
|
|
|
|
// JustSend just sending request
|
|
func JustSend(url string, client *resty.Client) (res libs.Response, err error) {
|
|
method := "GET"
|
|
// redirect policy
|
|
|
|
var resp *resty.Response
|
|
// really sending things here
|
|
method = strings.ToLower(strings.TrimSpace(method))
|
|
switch method {
|
|
case "get":
|
|
resp, err = client.R().
|
|
Get(url)
|
|
break
|
|
case "post":
|
|
resp, err = client.R().
|
|
Post(url)
|
|
break
|
|
}
|
|
|
|
// in case we want to get redirect stuff
|
|
if res.StatusCode != 0 {
|
|
return res, nil
|
|
}
|
|
|
|
if err != nil || resp == nil {
|
|
utils.WarnF("%v %v", url, err)
|
|
return libs.Response{}, err
|
|
}
|
|
|
|
return ParseResponse(*resp), nil
|
|
}
|
|
|
|
// ParseResponse field to Response
|
|
func ParseResponse(resp resty.Response) (res libs.Response) {
|
|
// var res libs.Response
|
|
resLength := len(string(resp.Body()))
|
|
// format the headers
|
|
var resHeaders []map[string]string
|
|
for k, v := range resp.RawResponse.Header {
|
|
if k == "Content-Type" {
|
|
res.ContentType = strings.Join(v[:], "")
|
|
}
|
|
if k == "Location" {
|
|
res.Location = strings.Join(v[:], "")
|
|
}
|
|
element := make(map[string]string)
|
|
element[k] = strings.Join(v[:], "")
|
|
resLength += len(fmt.Sprintf("%s: %s\n", k, strings.Join(v[:], "")))
|
|
resHeaders = append(resHeaders, element)
|
|
}
|
|
// response time in second
|
|
resTime := float64(resp.Time()) / float64(time.Second)
|
|
resHeaders = append(resHeaders,
|
|
map[string]string{"Total Length": strconv.Itoa(resLength)},
|
|
map[string]string{"Response Time": fmt.Sprintf("%f", resTime)},
|
|
)
|
|
|
|
// set some variable
|
|
res.Headers = resHeaders
|
|
res.StatusCode = resp.StatusCode()
|
|
res.Status = fmt.Sprintf("%v %v", resp.Status(), resp.RawResponse.Proto)
|
|
res.Body = string(resp.Body())
|
|
res.ResponseTime = resTime
|
|
res.Length = resLength
|
|
// beautify
|
|
res.Beautify = BeautifyResponse(res)
|
|
res.BeautifyHeader = BeautifyHeaders(res)
|
|
return res
|
|
}
|
|
|
|
// BeautifyRequest beautify request
|
|
func BeautifyRequest(req libs.Request) string {
|
|
var beautifyReq string
|
|
// hardcoded HTTP/1.1 for now
|
|
beautifyReq += fmt.Sprintf("%v %v HTTP/1.1\n", req.Method, req.URL)
|
|
|
|
for _, header := range req.Headers {
|
|
for key, value := range header {
|
|
if key != "" && value != "" {
|
|
beautifyReq += fmt.Sprintf("%v: %v\n", key, value)
|
|
}
|
|
}
|
|
}
|
|
if req.Body != "" {
|
|
beautifyReq += fmt.Sprintf("\n%v\n", req.Body)
|
|
}
|
|
return beautifyReq
|
|
}
|
|
|
|
// BeautifyHeaders beautify headers
|
|
func BeautifyHeaders(res libs.Response) string {
|
|
beautifyHeader := fmt.Sprintf("< %v \n", res.Status)
|
|
for _, header := range res.Headers {
|
|
for key, value := range header {
|
|
beautifyHeader += fmt.Sprintf("< %v: %v\n", key, value)
|
|
}
|
|
}
|
|
return beautifyHeader
|
|
}
|
|
|
|
// BeautifyResponse beautify response
|
|
func BeautifyResponse(res libs.Response) string {
|
|
var beautifyRes string
|
|
beautifyRes += fmt.Sprintf("%v \n", res.Status)
|
|
|
|
for _, header := range res.Headers {
|
|
for key, value := range header {
|
|
beautifyRes += fmt.Sprintf("%v: %v\n", key, value)
|
|
}
|
|
}
|
|
|
|
beautifyRes += fmt.Sprintf("\n%v\n", res.Body)
|
|
return beautifyRes
|
|
}
|
|
|
|
// ParseBurpRequest parse burp style request
|
|
func ParseBurpRequest(raw string) string {
|
|
rawDecoded, err := base64.StdEncoding.DecodeString(raw)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
|
|
var realReq libs.Request
|
|
reader := bufio.NewReader(strings.NewReader(string(rawDecoded)))
|
|
parsedReq, err := http.ReadRequest(reader)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
realReq.Method = parsedReq.Method
|
|
// URL part
|
|
if parsedReq.URL.Host == "" {
|
|
realReq.Host = parsedReq.Host
|
|
parsedReq.URL.Host = parsedReq.Host
|
|
}
|
|
if parsedReq.URL.Scheme == "" {
|
|
if parsedReq.Referer() == "" {
|
|
realReq.Scheme = "https"
|
|
parsedReq.URL.Scheme = "https"
|
|
} else {
|
|
u, err := url.Parse(parsedReq.Referer())
|
|
if err == nil {
|
|
realReq.Scheme = u.Scheme
|
|
parsedReq.URL.Scheme = u.Scheme
|
|
}
|
|
}
|
|
}
|
|
realReq.URL = parsedReq.URL.String()
|
|
realReq.Path = parsedReq.RequestURI
|
|
|
|
return realReq.URL
|
|
}
|