Skip to content

Commit d70d482

Browse files
authored
Merge pull request #74 from projectdiscovery/dev
0.0.5 Release
2 parents f59aafd + 6f8863d commit d70d482

20 files changed

+358
-108
lines changed

.github/workflows/codeql-analysis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323

2424
steps:
2525
- name: Checkout repository
26-
uses: actions/checkout@v2
26+
uses: actions/checkout@v3
2727

2828
# Initializes the CodeQL tools for scanning.
2929
- name: Initialize CodeQL

.github/workflows/dockerhub-push.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
steps:
1212
-
1313
name: Checkout
14-
uses: actions/checkout@v2
14+
uses: actions/checkout@v3
1515
-
1616
name: Set up QEMU
1717
uses: docker/setup-qemu-action@v1

.github/workflows/lint-test.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
- name: Checkout code
1313
uses: actions/checkout@v3
1414
- name: Run golangci-lint
15-
uses: golangci/golangci-lint-action@v3
15+
uses: golangci/golangci-lint-action@v3.1.0
1616
with:
1717
version: latest
1818
args: --timeout 5m

README.md

+15-1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ This will display help for the tool. Here are all the switches it supports.
6161
| `-max-file-size` | Max Upload File Size (default 50 MB) | `simplehttpserver -max-file-size 100` |
6262
| `-sandbox` | Enable sandbox mode | `simplehttpserver -sandbox` |
6363
| `-https` | Enable HTTPS in case of http server | `simplehttpserver -https` |
64+
| `-http1` | Enable only HTTP1 | `simplehttpserver -http1` |
6465
| `-cert` | HTTPS/TLS certificate (self generated if not specified) | `simplehttpserver -cert cert.pem` |
6566
| `-key` | HTTPS/TLS certificate private key | `simplehttpserver -key cert.key` |
6667
| `-domain` | Domain name to use for the self-generated certificate | `simplehttpserver -domain projectdiscovery.io` |
@@ -128,7 +129,9 @@ simplehttpserver -rule rules.yaml -tcp -tls -domain localhost
128129
The rules are written as follows:
129130
```yaml
130131
rules:
131-
- match: regex
132+
- match: regex-match
133+
match-contains: literal-match
134+
name: rule-name
132135
response: response data
133136
```
134137
@@ -137,6 +140,7 @@ For example to handle two different paths simulating an HTTP server or SMTP comm
137140
rules:
138141
# HTTP Requests
139142
- match: GET /path1
143+
name: redirect
140144
response: |
141145
HTTP/1.0 200 OK
142146
Server: httpd/2.0
@@ -149,13 +153,15 @@ rules:
149153
<HTML><HEAD><script>top.location.href='/Main_Login.asp';</script>
150154
</HEAD></HTML>
151155
- match: GET /path2
156+
name: "404"
152157
response: |
153158
HTTP/1.0 404 OK
154159
Server: httpd/2.0
155160
156161
<HTML><HEAD></HEAD><BODY>Not found</BODY></HTML>
157162
# SMTP Commands
158163
- match: "EHLO example.com"
164+
name: smtp
159165
response: |
160166
250-localhost Nice to meet you, [127.0.0.1]
161167
250-PIPELINING
@@ -167,6 +173,14 @@ rules:
167173
response: 250 Accepted
168174
- match: "RCPT TO: <test@example.com>"
169175
response: 250 Accepted
176+
177+
- match-contains: !!binary |
178+
MAwCAQFgBwIBAwQAgAA=
179+
name: "ldap"
180+
# Request: 300c 0201 0160 0702 0103 0400 8000 0....`........
181+
# Response: 300c 0201 0161 070a 0100 0400 0400 0....a........
182+
response: !!binary |
183+
MAwCAQFhBwoBAAQABAA=
170184
```
171185
172186
## Note

go.mod

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/projectdiscovery/simplehttpserver
33
go 1.17
44

55
require (
6+
github.com/fsnotify/fsnotify v1.5.1
67
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2
78
github.com/projectdiscovery/gologger v1.1.4
89
github.com/projectdiscovery/sslcert v0.0.0-20210416140253-8f56bec1bb5e
@@ -14,4 +15,5 @@ require (
1415
github.com/logrusorgru/aurora v2.0.3+incompatible // indirect
1516
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
1617
github.com/modern-go/reflect2 v1.0.1 // indirect
18+
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
1719
)

go.sum

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
22
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
33
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
44
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
5+
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
6+
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
57
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
68
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
79
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@@ -31,6 +33,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
3133
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
3234
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
3335
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
36+
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
37+
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
3438
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
3539
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
3640
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=

internal/runner/banner.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ const banner = `
88
\__ \/ / __ -__ \/ __ \/ / _ \/ /_/ / / / / / / /_/ / ___/ _ \/ ___/ | / / _ \/ ___/
99
___/ / / / / / / / /_/ / / __/ __ / / / / / / ____(__ ) __/ / | |/ / __/ /
1010
/____/_/_/ /_/ /_/ .___/_/\___/_/ /_/ /_/ /_/ /_/ /____/\___/_/ |___/\___/_/
11-
/_/ - v0.0.4
11+
/_/ - v0.0.5
1212
`
1313

1414
// Version is the current version
15-
const Version = `0.0.4`
15+
const Version = `0.0.5`
1616

1717
// showBanner is used to show the banner to the user
1818
func showBanner() {

internal/runner/options.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ type Options struct {
3131
Silent bool
3232
Sandbox bool
3333
MaxFileSize int
34+
HTTP1Only bool
35+
MaxDumpBodySize int
3436
}
3537

3638
// ParseOptions parses the command line options for application
@@ -56,8 +58,9 @@ func ParseOptions() *Options {
5658
flag.BoolVar(&options.Version, "version", false, "Show version of the software")
5759
flag.BoolVar(&options.Silent, "silent", false, "Show only results in the output")
5860
flag.BoolVar(&options.Sandbox, "sandbox", false, "Enable sandbox mode")
61+
flag.BoolVar(&options.HTTP1Only, "http1", false, "Enable only HTTP1")
5962
flag.IntVar(&options.MaxFileSize, "max-file-size", 50, "Max Upload File Size")
60-
63+
flag.IntVar(&options.MaxDumpBodySize, "max-dump-body-size", -1, "Max Dump Body Size")
6164
flag.Parse()
6265

6366
// Read the inputs and configure the logging

internal/runner/runner.go

+13
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"github.com/projectdiscovery/simplehttpserver/pkg/binder"
66
"github.com/projectdiscovery/simplehttpserver/pkg/httpserver"
77
"github.com/projectdiscovery/simplehttpserver/pkg/tcpserver"
8+
"github.com/projectdiscovery/simplehttpserver/pkg/unit"
89
)
910

1011
// Runner is a client for running the enumeration process.
@@ -41,6 +42,12 @@ func New(options *Options) (*Runner, error) {
4142
if err != nil {
4243
return nil, err
4344
}
45+
watcher, err := watchFile(r.options.RulesFile, serverTCP.LoadTemplate)
46+
if err != nil {
47+
return nil, err
48+
}
49+
defer watcher.Close()
50+
4451
r.serverTCP = serverTCP
4552
return &r, nil
4653
}
@@ -59,6 +66,8 @@ func New(options *Options) (*Runner, error) {
5966
Verbose: r.options.Verbose,
6067
Sandbox: r.options.Sandbox,
6168
MaxFileSize: r.options.MaxFileSize,
69+
HTTP1Only: r.options.HTTP1Only,
70+
MaxDumpBodySize: unit.ToMb(r.options.MaxDumpBodySize),
6271
})
6372
if err != nil {
6473
return nil, err
@@ -71,6 +80,10 @@ func New(options *Options) (*Runner, error) {
7180
// Run logic
7281
func (r *Runner) Run() error {
7382
if r.options.EnableTCP {
83+
if r.options.TCPWithTLS {
84+
gologger.Print().Msgf("Serving TCP rule based tls server on tcp://%s", r.options.ListenAddress)
85+
return r.serverTCP.ListenAndServeTLS()
86+
}
7487
gologger.Print().Msgf("Serving TCP rule based server on tcp://%s", r.options.ListenAddress)
7588
return r.serverTCP.ListenAndServe()
7689
}

internal/runner/watchdog.go

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package runner
2+
3+
import (
4+
"log"
5+
6+
"github.com/fsnotify/fsnotify"
7+
)
8+
9+
type WatchEvent func(fname string) error
10+
11+
func watchFile(fname string, callback WatchEvent) (watcher *fsnotify.Watcher, err error) {
12+
watcher, err = fsnotify.NewWatcher()
13+
if err != nil {
14+
return
15+
}
16+
go func() {
17+
for {
18+
select {
19+
case event, ok := <-watcher.Events:
20+
if !ok {
21+
continue
22+
}
23+
if event.Op&fsnotify.Write == fsnotify.Write {
24+
if err := callback(fname); err != nil {
25+
log.Println("err", err)
26+
}
27+
}
28+
case <-watcher.Errors:
29+
// ignore errors for now
30+
}
31+
}
32+
}()
33+
34+
err = watcher.Add(fname)
35+
return
36+
}

pkg/httpserver/authlayer.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"net/http"
66
)
77

8-
func (t *HTTPServer) basicauthlayer(handler http.Handler) http.HandlerFunc {
8+
func (t *HTTPServer) basicauthlayer(handler http.Handler) http.Handler {
99
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
1010
user, pass, ok := r.BasicAuth()
1111
if !ok || user != t.options.BasicAuthUsername || pass != t.options.BasicAuthPassword {

pkg/httpserver/httpserver.go

+36-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package httpserver
22

33
import (
4+
"crypto/tls"
45
"errors"
56
"net/http"
67
"os"
@@ -23,7 +24,9 @@ type Options struct {
2324
BasicAuthReal string
2425
Verbose bool
2526
Sandbox bool
27+
HTTP1Only bool
2628
MaxFileSize int // 50Mb
29+
MaxDumpBodySize int64
2730
}
2831

2932
// HTTPServer instance
@@ -32,6 +35,9 @@ type HTTPServer struct {
3235
layers http.Handler
3336
}
3437

38+
// LayerHandler is the interface of all layer funcs
39+
type Middleware func(http.Handler) http.Handler
40+
3541
// New http server instance with options
3642
func New(options *Options) (*HTTPServer, error) {
3743
var h HTTPServer
@@ -50,18 +56,44 @@ func New(options *Options) (*HTTPServer, error) {
5056
if options.Sandbox {
5157
dir = SandboxFileSystem{fs: http.Dir(options.Folder), RootFolder: options.Folder}
5258
}
53-
h.layers = h.loglayer(http.FileServer(dir))
59+
60+
httpHandler := http.FileServer(dir)
61+
addHandler := func(newHandler Middleware) {
62+
httpHandler = newHandler(httpHandler)
63+
}
64+
65+
// middleware
66+
if options.EnableUpload {
67+
addHandler(h.uploadlayer)
68+
}
69+
5470
if options.BasicAuthUsername != "" || options.BasicAuthPassword != "" {
55-
h.layers = h.loglayer(h.basicauthlayer(http.FileServer(dir)))
71+
addHandler(h.basicauthlayer)
5672
}
73+
74+
httpHandler = h.loglayer(httpHandler)
75+
76+
// add handler
77+
h.layers = httpHandler
5778
h.options = options
5879

5980
return &h, nil
6081
}
6182

83+
func (t *HTTPServer) makeHTTPServer(tlsConfig *tls.Config) *http.Server {
84+
httpServer := &http.Server{Addr: t.options.ListenAddress}
85+
if t.options.HTTP1Only {
86+
httpServer.TLSNextProto = make(map[string]func(*http.Server, *tls.Conn, http.Handler))
87+
}
88+
httpServer.TLSConfig = tlsConfig
89+
httpServer.Handler = t.layers
90+
return httpServer
91+
}
92+
6293
// ListenAndServe requests over http
6394
func (t *HTTPServer) ListenAndServe() error {
64-
return http.ListenAndServe(t.options.ListenAddress, t.layers)
95+
httpServer := t.makeHTTPServer(nil)
96+
return httpServer.ListenAndServe()
6597
}
6698

6799
// ListenAndServeTLS requests over https
@@ -73,11 +105,7 @@ func (t *HTTPServer) ListenAndServeTLS() error {
73105
if err != nil {
74106
return err
75107
}
76-
httpServer := &http.Server{
77-
Addr: t.options.ListenAddress,
78-
TLSConfig: tlsConfig,
79-
}
80-
httpServer.Handler = t.layers
108+
httpServer := t.makeHTTPServer(tlsConfig)
81109
return httpServer.ListenAndServeTLS("", "")
82110
}
83111
return http.ListenAndServeTLS(t.options.ListenAddress, t.options.Certificate, t.options.CertificateKey, t.layers)

0 commit comments

Comments
 (0)