mirror of
https://github.com/projectdiscovery/httpx.git
synced 2024-08-17 05:20:29 +03:00
adding server basic fingerprint based on server header
This commit is contained in:
parent
20d9d2f685
commit
4ab7aa2c79
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
2
go.mod
@ -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
4
go.sum
@ -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=
|
||||
|
Loading…
Reference in New Issue
Block a user