Skip to content

Commit b9b19b7

Browse files
committed
add AutoCert flag to main.go, improve check configuration.
1 parent c158933 commit b9b19b7

File tree

4 files changed

+71
-27
lines changed

4 files changed

+71
-27
lines changed

autocert.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ import (
88
"golang.org/x/crypto/acme/autocert"
99
)
1010

11-
func TestAutoCert(domain string) (*tls.Certificate, error) {
11+
// autoSignCert use a ACME client to send a request to Let's Encrypt.
12+
// Your Config.Hostname must be domain name, and this program running
13+
// at the server that IP address will be resolved.
14+
func autoSignCert(domain string) (*tls.Certificate, error) {
1215
const certDir = "autocert"
1316

1417
err := os.MkdirAll(certDir, 0700)

autocert_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func TestNewListener(t *testing.T) {
2929

3030
buf := make([]byte, 4096)
3131
n, err := conn.Read(buf)
32-
fmt.Println("asdasdads", err)
32+
fmt.Println("err:", err)
3333
fmt.Println(string(buf[:n]))
3434

3535
fmt.Println(conn.RemoteAddr())

cmd/main.go

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"crypto/tls"
45
"flag"
56
"fmt"
67
"log"
@@ -26,6 +27,7 @@ func init() {
2627
flag.StringVar(&cfg.HTTPAddress, "http-addr", ":8080", "http server address")
2728
flag.StringVar(&cfg.LDAPNetwork, "ldap-net", "tcp", "ldap server network")
2829
flag.StringVar(&cfg.LDAPAddress, "ldap-addr", ":3890", "ldap server address")
30+
flag.BoolVar(&cfg.AutoCert, "auto-cert", false, "use ACME to sign certificate")
2931
flag.BoolVar(&cfg.EnableTLS, "tls-server", false, "enable ldaps and https server")
3032
flag.StringVar(&crt, "tls-cert", "cert.pem", "tls certificate file path")
3133
flag.StringVar(&key, "tls-key", "key.pem", "tls private key file path")
@@ -47,24 +49,11 @@ func banner() {
4749
}
4850

4951
func main() {
50-
// check configuration
51-
if cfg.Hostname == "" {
52-
log.Fatalln("[error]", "empty host name")
53-
}
54-
fi, err := os.Stat(cfg.PayloadDir)
55-
checkError(err)
56-
if !fi.IsDir() {
57-
log.Fatalf("[error] \"%s\" is not a directory", cfg.PayloadDir)
58-
}
5952
// load tls certificate
6053
if cfg.EnableTLS {
61-
tlsCert, err := log4shell.TestAutoCert(cfg.Hostname)
54+
cert, err := tls.LoadX509KeyPair(crt, key)
6255
checkError(err)
63-
cfg.TLSCert = *tlsCert
64-
fmt.Println("Let's Encrypt sign certificate successfully")
65-
66-
// cfg.TLSCert, err = tls.LoadX509KeyPair(crt, key)
67-
// checkError(err)
56+
cfg.TLSCert = cert
6857
}
6958
cfg.LogOut = os.Stdout
7059

log4shell.go

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"log"
88
"net"
99
"net/http"
10+
"os"
1011
"sync"
1112
"time"
1213

@@ -18,16 +19,30 @@ import (
1819
type Config struct {
1920
LogOut io.Writer
2021

21-
Hostname string
22+
// Hostname can be set IP address or domain name,
23+
// If enable AutoCert, must set domain name.
24+
Hostname string
25+
26+
// PayloadDir contains Java class files.
2227
PayloadDir string
2328

29+
// about servers network and address.
2430
HTTPNetwork string
2531
HTTPAddress string
2632
LDAPNetwork string
2733
LDAPAddress string
2834

35+
// AutoCert is used to ACME client to sign
36+
// certificate automatically, don't need to
37+
// set EnableTLS true again.
38+
AutoCert bool
39+
40+
// EnableTLS is used to enable ldaps and
41+
// https server, must set TLS certificate.
2942
EnableTLS bool
30-
TLSCert tls.Certificate
43+
44+
// TLSCert is used to for ldaps and https.
45+
TLSCert tls.Certificate
3146
}
3247

3348
// Server is used to create an exploit server that contain
@@ -37,6 +52,8 @@ type Server struct {
3752
logger *log.Logger
3853
enableTLS bool
3954

55+
secret string
56+
4057
httpListener net.Listener
4158
httpHandler *httpHandler
4259
httpServer *http.Server
@@ -51,18 +68,46 @@ type Server struct {
5168

5269
// New is used to create a new log4shell server.
5370
func New(cfg *Config) (*Server, error) {
71+
// check configuration
72+
if cfg.LogOut == nil {
73+
panic("log4shell: Config.LogOut can not be nil")
74+
}
75+
if cfg.Hostname == "" {
76+
return nil, errors.New("empty host name")
77+
}
78+
fi, err := os.Stat(cfg.PayloadDir)
79+
if err != nil {
80+
return nil, errors.WithStack(err)
81+
}
82+
if !fi.IsDir() {
83+
return nil, errors.Errorf("\"%s\" is not a directory", cfg.PayloadDir)
84+
}
85+
86+
// set logger
5487
logger := log.New(cfg.LogOut, "", log.LstdFlags)
5588
ldapserver.Logger = logger
5689

5790
// initial tls config
5891
var tlsConfig *tls.Config
59-
if cfg.EnableTLS {
92+
enableTLS := cfg.EnableTLS
93+
if cfg.AutoCert {
94+
// hostname must be a domain name
95+
cert, err := autoSignCert(cfg.Hostname)
96+
if err != nil {
97+
return nil, err
98+
}
99+
tlsConfig = &tls.Config{
100+
Certificates: []tls.Certificate{*cert},
101+
}
102+
enableTLS = true
103+
} else if enableTLS {
60104
tlsConfig = &tls.Config{
61105
Certificates: []tls.Certificate{cfg.TLSCert},
62106
}
63107
}
64108

65-
// for generate random http handler
109+
// generate random string and add it to the http handler
110+
// for prevent some http spider or exploit server scanner
66111
secret := randString(8)
67112

68113
// initialize http server
@@ -90,7 +135,7 @@ func New(cfg *Config) (*Server, error) {
90135
return nil, errors.Wrap(err, "failed to create ldap listener")
91136
}
92137
var scheme string
93-
if cfg.EnableTLS {
138+
if enableTLS {
94139
scheme = "https"
95140
} else {
96141
scheme = "http"
@@ -117,7 +162,8 @@ func New(cfg *Config) (*Server, error) {
117162
// create log4shell server
118163
server := Server{
119164
logger: logger,
120-
enableTLS: cfg.EnableTLS,
165+
enableTLS: enableTLS,
166+
secret: secret,
121167
httpListener: httpListener,
122168
httpHandler: &httpHandler,
123169
httpServer: &httpServer,
@@ -134,6 +180,7 @@ func (srv *Server) Start() error {
134180
defer srv.mu.Unlock()
135181

136182
errCh := make(chan error, 2)
183+
137184
// start http server
138185
srv.wg.Add(1)
139186
go func() {
@@ -182,18 +229,23 @@ func (srv *Server) Stop() error {
182229
srv.mu.Lock()
183230
defer srv.mu.Unlock()
184231

232+
// close ldap server
233+
srv.ldapServer.Stop()
234+
srv.logger.Println("[info]", "ldap server is stopped")
235+
185236
// close http server
186237
err := srv.httpServer.Close()
187238
if err != nil {
188239
return errors.Wrap(err, "failed to close http server")
189240
}
190241
srv.logger.Println("[info]", "http server is stopped")
191242

192-
// close ldap server
193-
srv.ldapServer.Stop()
194-
srv.logger.Println("[info]", "ldap server is stopped")
195-
196243
srv.wg.Wait()
197244
srv.logger.Println("[info]", "log4shell server is stopped")
198245
return nil
199246
}
247+
248+
// Secret is used to get the generated secret about url.
249+
func (srv *Server) Secret() string {
250+
return srv.secret
251+
}

0 commit comments

Comments
 (0)