Merge pull request #19 from projectdiscovery/feature-server-fingerprint

adding server basic fingerprint based on server header
This commit is contained in:
bauthard 2020-06-06 16:02:11 +05:30 committed by GitHub
commit 6b52546be4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 56 additions and 30 deletions

View File

@ -54,6 +54,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 != "." {
@ -79,7 +80,7 @@ func main() {
defer f.Close()
}
for r := range output {
if r.Error != nil {
if r.err != nil {
continue
}
row := r.str
@ -176,6 +177,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) {
@ -188,7 +190,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
}
@ -196,7 +198,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"
@ -236,6 +238,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 {
@ -251,7 +258,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
@ -261,8 +268,9 @@ type Result struct {
StatusCode int `json:"status-code"`
Title string `json:"title"`
str string
Error error `json:"error"`
err error
VHost bool `json:"vhost"`
WebServer string `json:"webserver"`
}
// JSON the result

View File

@ -36,6 +36,7 @@ type Options struct {
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 ""
}