adding server basic fingerprint based on server header

This commit is contained in:
Mzack9999 2020-06-05 20:45:48 +02:00
parent 20d9d2f685
commit 4ab7aa2c79
6 changed files with 59 additions and 33 deletions

View File

@ -53,6 +53,7 @@ func main() {
scanopts.StoreResponse = options.StoreResponse
scanopts.StoreResponseDirectory = options.StoreResponseDir
scanopts.Method = options.Method
scanopts.OutputServerHeader = options.OutputServerHeader
// Try to create output folder if it doesnt exist
if options.StoreResponse && options.StoreResponseDir != "" && options.StoreResponseDir != "." {
@ -78,7 +79,7 @@ func main() {
defer f.Close()
}
for r := range output {
if r.Error != nil {
if r.err != nil {
continue
}
row := r.str
@ -152,6 +153,7 @@ type scanOptions struct {
OutputContentLength bool
StoreResponse bool
StoreResponseDirectory string
OutputServerHeader bool
}
func analyze(hp *httpx.HTTPX, protocol string, domain string, port int, scanopts *scanOptions, output chan Result) {
@ -164,7 +166,7 @@ retry:
req, err := hp.NewRequest(scanopts.Method, URL)
if err != nil {
output <- Result{URL: URL, Error: err}
output <- Result{URL: URL, err: err}
return
}
@ -172,7 +174,7 @@ retry:
resp, err := hp.Do(req)
if err != nil {
output <- Result{URL: URL, Error: err}
output <- Result{URL: URL, err: err}
if !retried {
if protocol == "https" {
protocol = "http"
@ -212,6 +214,11 @@ retry:
builder.WriteString(fmt.Sprintf(" [%s]", title))
}
serverHeader := resp.GetHeader("Server")
if scanopts.OutputServerHeader {
builder.WriteString(fmt.Sprintf(" [%s]", serverHeader))
}
// check for virtual host
isvhost := false
if scanopts.VHost {
@ -227,7 +234,7 @@ retry:
ioutil.WriteFile(responsePath, []byte(resp.Raw), 0644)
}
output <- Result{URL: fullURL, ContentLength: resp.ContentLength, StatusCode: resp.StatusCode, Title: title, str: builder.String(), VHost: isvhost}
output <- Result{URL: fullURL, ContentLength: resp.ContentLength, StatusCode: resp.StatusCode, Title: title, str: builder.String(), VHost: isvhost, WebServer: serverHeader}
}
// Result of a scan
@ -237,8 +244,9 @@ type Result struct {
StatusCode int `json:"status-code"`
Title string `json:"title"`
str string
Error error `json:"error"`
VHost bool `json:"vhost"`
err error
VHost bool `json:"vhost"`
WebServer string `json:"webserver"`
}
// JSON the result

View File

@ -12,30 +12,31 @@ import (
// Options contains configuration options for chaos client.
type Options struct {
RawRequestFile string
VHost bool
Smuggling bool
ExtractTitle bool
StatusCode bool
ContentLength bool
Retries int
Threads int
Timeout int
CustomHeaders customheader.CustomHeaders
CustomPorts customport.CustomPorts
Output string
FollowRedirects bool
StoreResponse bool
StoreResponseDir string
HttpProxy string
SocksProxy string
JSONOutput bool
InputFile string
Method string
Silent bool
Version bool
Verbose bool
NoColor bool
RawRequestFile string
VHost bool
Smuggling bool
ExtractTitle bool
StatusCode bool
ContentLength bool
Retries int
Threads int
Timeout int
CustomHeaders customheader.CustomHeaders
CustomPorts customport.CustomPorts
Output string
FollowRedirects bool
StoreResponse bool
StoreResponseDir string
HttpProxy string
SocksProxy string
JSONOutput bool
InputFile string
Method string
Silent bool
Version bool
Verbose bool
NoColor bool
OutputServerHeader bool
}
// ParseOptions parses the command line options for application
@ -63,6 +64,7 @@ func ParseOptions() *Options {
flag.BoolVar(&options.Version, "version", false, "Show version of httpx")
flag.BoolVar(&options.Verbose, "verbose", false, "Verbose Mode")
flag.BoolVar(&options.NoColor, "no-color", false, "No Color")
flag.BoolVar(&options.OutputServerHeader, "web-server", false, "Prints out the Server header content")
flag.Parse()
// Read the inputs and configure the logging

View File

@ -85,6 +85,8 @@ func (h *HTTPX) Do(req *retryablehttp.Request) (*Response, error) {
return nil, err
}
resp.Headers = httpresp.Header.Clone()
rawresp, err := httputil.DumpResponse(httpresp, true)
if err != nil {
return nil, err

View File

@ -1,5 +1,9 @@
package httpx
import (
"strings"
)
// Response contains the response to a server
type Response struct {
StatusCode int
@ -10,3 +14,13 @@ type Response struct {
Words int
Lines int
}
// GetHeader value
func (r *Response) GetHeader(name string) string {
v, ok := r.Headers[name]
if ok {
return strings.Join(v, " ")
}
return ""
}

2
go.mod
View File

@ -12,5 +12,5 @@ require (
github.com/projectdiscovery/retryablehttp-go v1.0.1
github.com/remeh/sizedwaitgroup v1.0.0
github.com/rs/xid v1.2.1
golang.org/x/net v0.0.0-20200528225125-3c3fba18258b
golang.org/x/net v0.0.0-20200602114024-627f9648deb9
)

4
go.sum
View File

@ -32,8 +32,8 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200528225125-3c3fba18258b h1:IYiJPiJfzktmDAO1HQiwjMjwjlYKHAL7KzeD544RJPs=
golang.org/x/net v0.0.0-20200528225125-3c3fba18258b/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM=
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=