WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit bb1ccc4

Browse files
authored
Merge pull request #486 from projectdiscovery/dev
v1.1.5 Release
2 parents 3a67d1e + 064fbd1 commit bb1ccc4

File tree

12 files changed

+405
-72
lines changed

12 files changed

+405
-72
lines changed

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM golang:1.17.3-alpine AS builder
1+
FROM golang:1.17.6-alpine AS builder
22
RUN apk add --no-cache git
33
RUN go install -v github.com/projectdiscovery/httpx/cmd/httpx@latest
44

README.md

Lines changed: 101 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
<p align="center">
99
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-_red.svg"></a>
10-
<a href="https://github.com/projectdiscovery/httpx/issues"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat"></a>
1110
<a href="https://goreportcard.com/badge/github.com/projectdiscovery/httpx"><img src="https://goreportcard.com/badge/github.com/projectdiscovery/httpx"></a>
1211
<a href="https://github.com/projectdiscovery/httpx/releases"><img src="https://img.shields.io/github/release/projectdiscovery/httpx"></a>
1312
<a href="https://hub.docker.com/r/projectdiscovery/httpx"><img src="https://img.shields.io/docker/pulls/projectdiscovery/httpx.svg"></a>
@@ -43,18 +42,22 @@ httpx is a fast and multi-purpose HTTP toolkit allow to run multiple probers usi
4342

4443
### Supported probes:-
4544

46-
| Probes | Default check | Probes | Default check |
47-
|--------------------|-----------------|--------------------|-----------------|
48-
| URL | true | IP | true |
49-
| Title | true | CNAME | true |
50-
| Status Code | true | Raw HTTP | false |
51-
| Content Length | true | HTTP2 | false |
52-
| TLS Certificate | true | HTTP 1.1 Pipeline | false |
53-
| CSP Header | true | Virtual host | false |
54-
| Location Header | true | CDN | false |
55-
| Web Server | true | Path | false |
56-
| Web Socket | true | Ports | false |
57-
| Response Time | true | Request method | false |
45+
| Probes | Default check | Probes | Default check |
46+
| --------------- | ------------- | ----------------- | ------------- |
47+
| URL | true | IP | true |
48+
| Title | true | CNAME | true |
49+
| Status Code | true | Raw HTTP | false |
50+
| Content Length | true | HTTP2 | false |
51+
| TLS Certificate | true | HTTP Pipeline | false |
52+
| CSP Header | true | Virtual host | false |
53+
| Line Count | true | Word Count | true |
54+
| Location Header | true | CDN | false |
55+
| Web Server | true | Paths | false |
56+
| Web Socket | true | Ports | false |
57+
| Response Time | true | Request Method | true |
58+
| Favicon Hash | false | Probe Status | false |
59+
| Body Hash | true | Header Hash | true |
60+
| Redirect chain | false | URL Scheme | true |
5861

5962

6063
# Installation Instructions
@@ -87,6 +90,8 @@ PROBES:
8790
-sc, -status-code Display Status Code
8891
-td, -tech-detect Display wappalyzer based technology detection
8992
-cl, -content-length Display Content-Length
93+
-lc, -line-count Display Response body line count
94+
-wc, -word-count Display Response body word count
9095
-server, -web-server Display Server header
9196
-ct, -content-type Display Content-Type header
9297
-rt, -response-time Display the response time
@@ -105,18 +110,25 @@ MATCHERS:
105110
-ms, -match-string string Match response with given string
106111
-mr, -match-regex string Match response with specific regex
107112
-er, -extract-regex string Display response content with matched regex
113+
-mlc, -match-line-count string Match Response body line count
114+
-mwc, -match-word-count string Match Response body word count
115+
-mfc, -match-favicon string[] Match response with specific favicon
108116

109117
FILTERS:
110118
-fc, -filter-code string Filter response with given status code (-fc 403,401)
111119
-fl, -filter-length string Filter response with given content length (-fl 23,33)
112120
-fs, -filter-string string Filter response with specific string
113121
-fe, -filter-regex string Filter response with specific regex
122+
-flc, -filter-line-count string Filter Response body line count
123+
-fwc, -filter-word-count string Filter Response body word count
124+
-ffc, -filter-favicon string[] Filter response with specific favicon
114125

115126
RATE-LIMIT:
116127
-t, -threads int Number of threads (default 50)
117128
-rl, -rate-limit int Maximum requests to send per second (default 150)
118129

119130
MISCELLANEOUS:
131+
-favicon Probes for favicon ("favicon.ico" as path) and display phythonic hash
120132
-tls-grab Perform TLS(SSL) data grabbing
121133
-tls-probe Send HTTP probes on the extracted TLS domains
122134
-csp-probe Send HTTP probes on the extracted CSP domains
@@ -128,16 +140,17 @@ MISCELLANEOUS:
128140
-paths string File or comma separated paths to request (deprecated)
129141

130142
OUTPUT:
131-
-o, -output string File to write output
132-
-sr, -store-response Store HTTP responses
133-
-srd, -store-response-dir string Custom directory to store HTTP responses (default "output")
134-
-json Output in JSONL(ines) format
135-
-irr, -include-response Include HTTP request/response in JSON output (-json only)
136-
-include-chain Include redirect HTTP Chain in JSON output (-json only)
137-
-store-chain Include HTTP redirect chain in responses (-sr only)
138-
-csv Output in CSV format
143+
-o, -output string file to write output
144+
-sr, -store-response store http response to output directory
145+
-srd, -store-response-dir string store http response to custom directory (default "output")
146+
-csv store output in CSV format
147+
-json store output in JSONL(ines) format
148+
-irr, -include-response include http request/response in JSON output (-json only)
149+
-include-chain include redirect http chain in JSON output (-json only)
150+
-store-chain include http redirect chain in responses (-sr only)
139151

140152
CONFIGURATIONS:
153+
-r, -resolvers string[] List of custom resolvers (file or comma separated)
141154
-allow string[] Allowed list of IP/CIDR's to process (file or comma separated)
142155
-deny string[] Denied list of IP/CIDR's to process (file or comma separated)
143156
-random-agent Enable Random User-Agent to use (default true)
@@ -178,7 +191,7 @@ OPTIMIZATIONS:
178191

179192
# Running httpX
180193

181-
### Running httpx with stdin
194+
### URL Probe
182195

183196
This will run the tool against all the hosts and subdomains in `hosts.txt` and returns URLs running HTTP webserver.
184197

@@ -207,7 +220,7 @@ https://api.hackerone.com
207220
https://support.hackerone.com
208221
```
209222

210-
### Running httpx with file input
223+
### File Input
211224

212225
This will run the tool with the `probe` flag against all of the hosts in **hosts.txt** and return URLs with probed status.
213226

@@ -236,7 +249,7 @@ http://a.ns.hackerone.com [FAILED]
236249
http://b.ns.hackerone.com [FAILED]
237250
```
238251

239-
### Running httpx with CIDR input
252+
### CIDR Input
240253

241254
```console
242255
echo 173.0.84.0/24 | httpx -silent
@@ -262,7 +275,7 @@ https://173.0.84.34
262275
```
263276

264277

265-
### Running httpx with subfinder
278+
### Tool Chain
266279

267280

268281
```console
@@ -287,7 +300,65 @@ https://support.hackerone.com [301,302,301,200] [HackerOne] [Cloudflare,Ruby on
287300
https://resources.hackerone.com [301,301,404] [Sorry, no Folders found.]
288301
```
289302

290-
### Running httpx with docker
303+
### Favicon Hash
304+
305+
306+
```console
307+
subfinder -d hackerone.com -silent | httpx -favicon
308+
309+
__ __ __ _ __
310+
/ /_ / /_/ /_____ | |/ /
311+
/ __ \/ __/ __/ __ \| /
312+
/ / / / /_/ /_/ /_/ / |
313+
/_/ /_/\__/\__/ .___/_/|_|
314+
/_/ v1.1.5
315+
316+
projectdiscovery.io
317+
318+
Use with caution. You are responsible for your actions.
319+
Developers assume no liability and are not responsible for any misuse or damage.
320+
https://docs.hackerone.com/favicon.ico [595148549]
321+
https://hackerone.com/favicon.ico [595148549]
322+
https://mta-sts.managed.hackerone.com/favicon.ico [-1700323260]
323+
https://mta-sts.forwarding.hackerone.com/favicon.ico [-1700323260]
324+
https://support.hackerone.com/favicon.ico [-1279294674]
325+
https://gslink.hackerone.com/favicon.ico [1506877856]
326+
https://resources.hackerone.com/favicon.ico [-1840324437]
327+
https://api.hackerone.com/favicon.ico [566218143]
328+
https://mta-sts.hackerone.com/favicon.ico [-1700323260]
329+
https://www.hackerone.com/favicon.ico [778073381]
330+
```
331+
332+
### Path Probe
333+
334+
335+
```console
336+
httpx -l urls.txt -path /v1/api -sc
337+
338+
__ __ __ _ __
339+
/ /_ / /_/ /_____ | |/ /
340+
/ __ \/ __/ __/ __ \| /
341+
/ / / / /_/ /_/ /_/ / |
342+
/_/ /_/\__/\__/ .___/_/|_|
343+
/_/ v1.1.5
344+
345+
projectdiscovery.io
346+
347+
Use with caution. You are responsible for your actions.
348+
Developers assume no liability and are not responsible for any misuse or damage.
349+
https://mta-sts.managed.hackerone.com/v1/api [404]
350+
https://mta-sts.hackerone.com/v1/api [404]
351+
https://mta-sts.forwarding.hackerone.com/v1/api [404]
352+
https://docs.hackerone.com/v1/api [404]
353+
https://api.hackerone.com/v1/api [401]
354+
https://hackerone.com/v1/api [302]
355+
https://support.hackerone.com/v1/api [404]
356+
https://resources.hackerone.com/v1/api [301]
357+
https://gslink.hackerone.com/v1/api [404]
358+
http://www.hackerone.com/v1/api [301]
359+
```
360+
361+
### Docker Run
291362

292363
```console
293364
cat sub_domains.txt | docker run -i projectdiscovery/httpx
@@ -320,10 +391,11 @@ https://support.hackerone.com
320391
- As default, **httpx** checks for `HTTPS` probe and fall-back to `HTTP` only if `HTTPS` is not reachable.
321392
- For printing both HTTP/HTTPS results, `no-fallback` flag can be used.
322393
- Custom scheme for ports can be defined, for example `-ports http:443,http:80,https:8443`
323-
- `vhost`, `http2`, `pipeline`, `ports`, `csp-probe`, `tls-probe` and `path` are unique flag with different probes.
324-
- Unique flags should be used for specific use cases instead of running them as default with other flags.
394+
- `favicon`,`vhost`, `http2`, `pipeline`, `ports`, `csp-probe`, `tls-probe` and `path` are unique flag with different probes.
395+
- Unique flags should be used for specific use cases instead of running them as default with other probes.
325396
- When using `json` flag, all the information (default probes) included in the JSON output.
326-
397+
- Custom resolver supports multiple protocol (**doh|tcp|udp**) in form of `protocol:resolver:port` (eg **udp:127.0.0.1:53**)
398+
- Invalid custom resolvers/files are ignored.
327399

328400
# Acknowledgement
329401

cmd/integration-test/http.go

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,19 @@ import (
1212
)
1313

1414
var httpTestcases = map[string]testutils.TestCase{
15-
"Standard HTTP GET Request": &standardHttpGet{},
16-
"Standard HTTPS GET Request": &standardHttpGet{tls: true},
17-
"Raw HTTP GET Request": &standardHttpGet{unsafe: true},
18-
"Raw request with non standard rfc path via stdin": &standardHttpGet{unsafe: true, stdinPath: "/%invalid"},
19-
"Raw request with non standard rfc path via cli flag": &standardHttpGet{unsafe: true, path: "/%invalid"},
20-
"Regression test for: https://github.com/projectdiscovery/httpx/issues/363": &issue363{}, // infinite redirect
21-
"Regression test for: https://github.com/projectdiscovery/httpx/issues/276": &issue276{}, // full path with port in output
22-
"Regression test for: https://github.com/projectdiscovery/httpx/issues/277": &issue277{}, // scheme://host:port via stdin
23-
"Regression test for: https://github.com/projectdiscovery/httpx/issues/303": &issue303{}, // misconfigured gzip header with uncompressed body
24-
"Regression test for: https://github.com/projectdiscovery/httpx/issues/400": &issue400{}, // post operation with body
25-
"Regression test for: https://github.com/projectdiscovery/httpx/issues/414": &issue414{}, // stream mode with path
26-
"Regression test for: https://github.com/projectdiscovery/httpx/issues/433": &issue433{}, // new line scanning with title flag
15+
"Standard HTTP GET Request": &standardHttpGet{},
16+
"Standard HTTPS GET Request": &standardHttpGet{tls: true},
17+
"Raw HTTP GET Request": &standardHttpGet{unsafe: true},
18+
"Raw request with non standard rfc path via stdin": &standardHttpGet{unsafe: true, stdinPath: "/%invalid"},
19+
"Raw request with non standard rfc path via cli flag": &standardHttpGet{unsafe: true, path: "/%invalid"},
20+
"Regression test for: https://github.com/projectdiscovery/httpx/issues/363": &issue363{}, // infinite redirect
21+
"Regression test for: https://github.com/projectdiscovery/httpx/issues/276": &issue276{}, // full path with port in output
22+
"Regression test for: https://github.com/projectdiscovery/httpx/issues/277": &issue277{}, // scheme://host:port via stdin
23+
"Regression test for: https://github.com/projectdiscovery/httpx/issues/303": &issue303{}, // misconfigured gzip header with uncompressed body
24+
"Regression test for: https://github.com/projectdiscovery/httpx/issues/400": &issue400{}, // post operation with body
25+
"Regression test for: https://github.com/projectdiscovery/httpx/issues/414": &issue414{}, // stream mode with path
26+
"Regression test for: https://github.com/projectdiscovery/httpx/issues/433": &issue433{}, // new line scanning with title flag
27+
"Request URI to existing file - https://github.com/projectdiscovery/httpx/issues/480": &issue480{}, // request uri pointing to existing file
2728
}
2829

2930
type standardHttpGet struct {
@@ -264,3 +265,25 @@ func (h *issue433) Execute() error {
264265
}
265266
return nil
266267
}
268+
269+
type issue480 struct{}
270+
271+
func (h *issue480) Execute() error {
272+
var ts *httptest.Server
273+
router := httprouter.New()
274+
uriPath := "////////////////../../../../../../../../etc/passwd"
275+
router.GET(uriPath, httprouter.Handle(func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
276+
htmlResponse := "<html><body>ok from uri</body></html>"
277+
fmt.Fprint(w, htmlResponse)
278+
}))
279+
ts = httptest.NewServer(router)
280+
defer ts.Close()
281+
results, err := testutils.RunHttpxAndGetResults(ts.URL, debug, "-path", "////////////////../../../../../../../../etc/passwd")
282+
if err != nil {
283+
return err
284+
}
285+
if !strings.Contains(results[0], uriPath) {
286+
return errIncorrectResultsCount(results)
287+
}
288+
return nil
289+
}

common/httpx/httpx.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ func New(options *Options) (*HTTPX, error) {
4444
fastdialerOpts.Deny = options.Deny
4545
fastdialerOpts.Allow = options.Allow
4646
fastdialerOpts.WithDialerHistory = true
47+
if len(options.Resolvers) > 0 {
48+
fastdialerOpts.BaseResolvers = options.Resolvers
49+
}
4750
dialer, err := fastdialer.NewDialer(fastdialerOpts)
4851
if err != nil {
4952
return nil, fmt.Errorf("could not create resolver cache: %s", err)

common/httpx/option.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ type Options struct {
3636
MaxResponseBodySizeToSave int64
3737
MaxResponseBodySizeToRead int64
3838
UnsafeURI string
39+
Resolvers []string
3940
}
4041

4142
// DefaultOptions contains the default options

common/slice/slice.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@ func IntSliceContains(sl []int, v int) bool {
1010
return false
1111
}
1212

13+
// UIntSliceContains check if a slice contains the specified uint value
14+
func UInt32SliceContains(sl []uint32, v uint32) bool {
15+
for _, vv := range sl {
16+
if vv == v {
17+
return true
18+
}
19+
}
20+
return false
21+
}
22+
1323
// ToSlice creates a slice with all string keys from a map
1424
func ToSlice(m map[string]struct{}) (s []string) {
1525
for k := range m {

common/stringz/stringz.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package stringz
22

33
import (
4+
"bytes"
5+
"encoding/base64"
46
"net/url"
57
"strconv"
68
"strings"
79

810
"github.com/projectdiscovery/urlutil"
11+
"github.com/spaolacci/murmur3"
912
)
1013

1114
// TrimProtocol removes the HTTP scheme from an URI
@@ -39,6 +42,24 @@ func StringToSliceInt(s string) ([]int, error) {
3942
return r, nil
4043
}
4144

45+
// StringToSliceUInt converts string to slice of ints
46+
func StringToSliceUInt32(s string) ([]uint32, error) {
47+
var r []uint32
48+
if s == "" {
49+
return r, nil
50+
}
51+
for _, v := range strings.Split(s, ",") {
52+
vTrim := strings.TrimSpace(v)
53+
if i, err := strconv.ParseUint(vTrim, 10, 64); err == nil {
54+
r = append(r, uint32(i))
55+
} else {
56+
return r, err
57+
}
58+
}
59+
60+
return r, nil
61+
}
62+
4263
// SplitByCharAndTrimSpace splits string by a character and remove spaces
4364
func SplitByCharAndTrimSpace(s, splitchar string) (result []string) {
4465
for _, token := range strings.Split(s, splitchar) {
@@ -84,3 +105,25 @@ func GetInvalidURI(rawURL string) (bool, string) {
84105

85106
return false, ""
86107
}
108+
109+
func FaviconHash(data []byte) int32 {
110+
stdBase64 := base64.StdEncoding.EncodeToString(data)
111+
stdBase64 = InsertInto(stdBase64, 76, '\n')
112+
hasher := murmur3.New32WithSeed(0)
113+
hasher.Write([]byte(stdBase64))
114+
return int32(hasher.Sum32())
115+
}
116+
117+
func InsertInto(s string, interval int, sep rune) string {
118+
var buffer bytes.Buffer
119+
before := interval - 1
120+
last := len(s) - 1
121+
for i, char := range s {
122+
buffer.WriteRune(char)
123+
if i%interval == before && i != last {
124+
buffer.WriteRune(sep)
125+
}
126+
}
127+
buffer.WriteRune(sep)
128+
return buffer.String()
129+
}

0 commit comments

Comments
 (0)