Skip to content

Commit aaf66b9

Browse files
committed
use config file instead of arguments
1 parent a6903a0 commit aaf66b9

File tree

10 files changed

+98
-72
lines changed

10 files changed

+98
-72
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
.idea/
22
*.log
33
dist/
4+
*.dev.toml

.goreleaser.yaml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,18 @@ nfpms:
5959
- apk
6060
- deb
6161
contents:
62+
- src: reverssh.toml
63+
dst: /etc/reverssh/reverssh.toml
64+
type: config|noreplace
65+
packager: apk
6266
- src: openrc/reverssh
6367
dst: /etc/init.d/reverssh
64-
type: config|noreplace
6568
packager: apk
69+
70+
- src: reverssh.toml
71+
dst: /etc/reverssh/reverssh.toml
72+
type: config|noreplace
73+
packager: deb
6674
- src: systemd/reverssh.service
6775
dst: /lib/systemd/system/reverssh.service
68-
type: config|noreplace
6976
packager: deb

README.md

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Reversing SSH Tarpit.
44

55
This tool makes SSH bots brute-force themselves.
6-
By using argument `-p` you can specify port numbers (e.g., `-p 22,2222`) to instruct
6+
By using key `remoteports` in the config you can specify port numbers to instruct
77
`reverssh` attempt connections on each of the specified ports of the SSH client.
88
If any connection is successful, it forwards all incoming traffic back to the open port,
99
causing bots to interact with their own servers.
@@ -12,9 +12,9 @@ If no ports are specified, or if all provided ports are closed, `reverssh` behav
1212
sending one random byte per second.
1313

1414
Other features:
15-
- linux packages(apk, deb) include services(openrc, systemd) which you might want to adjust
16-
- argument `-b` can be provided few times to listen on few addresses
15+
- linux packages(apk, deb) include services(openrc, systemd)
1716
- JSON structured logs
17+
- ability to bind to few addresses
1818
- ability to watch active connections
1919

2020
## Installation
@@ -27,23 +27,25 @@ See [Releases](https://github.com/jackcvr/reverssh/releases)
2727
Usage of reverssh:
2828
-active
2929
Show active connections info
30-
-b value
31-
Local address to listen on
32-
-f string
33-
Log file (default stdout)
34-
-p value
35-
Remote ports to connect to, e.g. '22,2222'
36-
-q Do not print anything
37-
-v Verbose mode
30+
-c string
31+
Path to TOML config file (default "/etc/reverssh/reverssh.toml")
32+
```
33+
34+
### reverssh.toml sample
35+
```toml
36+
tz = "Europe/Vilnius"
37+
verbose = false
38+
quiet = false
39+
bind = ["0.0.0.0:22"]
40+
remoteports = [22]
3841
```
3942

4043
## Examples
4144

42-
Start reversing tarpit on 2222 and 2223 ports (redirecting clients back to 22 port):
45+
Start reversing tarpit on 2222 port (redirecting clients back to 22 port):
4346

4447
```shell
45-
$ sudo reverssh -b 0.0.0.0:2222 -b 0.0.0.0:2223 -p 22
46-
{"time":"2024-09-18T15:17:08.854818805+03:00","level":"INFO","msg":"listening","addr":"0.0.0.0:2223"}
48+
$ sudo reverssh -c reverssh.toml
4749
{"time":"2024-09-18T15:17:08.854929365+03:00","level":"INFO","msg":"listening","addr":"0.0.0.0:2222"}
4850
{"time":"2024-09-18T15:17:08.854953224+03:00","level":"INFO","msg":"listening","addr":"/var/run/reverssh.sock"}
4951
{"time":"2024-09-18T15:17:13.053926647+03:00","level":"INFO","msg":"accepted","laddr":{"IP":"127.0.0.1","Port":2222,"Zone":""},"raddr":{"IP":"127.0.0.1","Port":60988,"Zone":""}}
@@ -56,16 +58,6 @@ $ sudo reverssh -b 0.0.0.0:2222 -b 0.0.0.0:2223 -p 22
5658
{"time":"2024-09-18T15:17:19.239013755+03:00","level":"INFO","msg":"closed","laddr":{"IP":"127.0.0.1","Port":2223,"Zone":""},"raddr":{"IP":"127.0.0.1","Port":60370,"Zone":""},"lifetime":2,"reversed":true}
5759
```
5860

59-
Start normal tarpit on 2222 port:
60-
61-
```shell
62-
$ sudo reverssh -b 0.0.0.0:2222
63-
{"time":"2024-09-18T15:17:56.23333367+03:00","level":"INFO","msg":"listening","addr":"0.0.0.0:2222"}
64-
{"time":"2024-09-18T15:17:56.233464484+03:00","level":"INFO","msg":"listening","addr":"/var/run/reverssh.sock"}
65-
{"time":"2024-09-18T15:17:57.933792016+03:00","level":"INFO","msg":"accepted","laddr":{"IP":"127.0.0.1","Port":2222,"Zone":""},"raddr":{"IP":"127.0.0.1","Port":53866,"Zone":""}}
66-
{"time":"2024-09-18T15:18:04.937012135+03:00","level":"INFO","msg":"closed","laddr":{"IP":"127.0.0.1","Port":2222,"Zone":""},"raddr":{"IP":"127.0.0.1","Port":53866,"Zone":""},"lifetime":6,"reversed":false}
67-
```
68-
6961
Show current activity:
7062

7163
```shell

app.go

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,31 +12,29 @@ import (
1212
)
1313

1414
type App struct {
15-
quiet bool
16-
bindAddress StringList
17-
remotePorts Ports
15+
config Config
1816
}
1917

2018
func (app App) Error(format string, args ...any) {
21-
if !app.quiet {
19+
if !app.config.Quiet {
2220
fmt.Fprintf(os.Stderr, format+"\n", args...)
2321
}
2422
}
2523

2624
func (app App) LogInfo(format string, args ...any) {
27-
if !app.quiet {
25+
if !app.config.Quiet {
2826
slog.Info(format, args...)
2927
}
3028
}
3129

3230
func (app App) LogDebug(format string, args ...any) {
33-
if !app.quiet {
31+
if !app.config.Quiet {
3432
slog.Debug(format, args...)
3533
}
3634
}
3735

3836
func (app App) LogError(format string, args ...any) {
39-
if !app.quiet {
37+
if !app.config.Quiet {
4038
slog.Error(format, args...)
4139
}
4240
}
@@ -46,18 +44,18 @@ func (app App) Run() error {
4644
stats := Stats{}
4745
go stats.RunServer(ctx)
4846

49-
if len(app.bindAddress) > 1 {
47+
if len(app.config.Bind) > 1 {
5048
var g *errgroup.Group
5149
g, ctx = errgroup.WithContext(ctx)
52-
for _, addr := range app.bindAddress {
50+
for _, addr := range app.config.Bind {
5351
g.Go(func() error {
5452
return app.Listen(ctx, addr, stats)
5553
})
5654
}
5755
return g.Wait()
5856
}
5957

60-
return app.Listen(ctx, app.bindAddress[0], stats)
58+
return app.Listen(ctx, app.config.Bind[0], stats)
6159
}
6260

6361
func (app App) Listen(ctx context.Context, addr string, stats Stats) error {
@@ -110,7 +108,7 @@ func (app App) HandleConnection(localConn net.Conn, info *ConnInfo) {
110108
"reversed", info.IsReversed)
111109
}()
112110

113-
for _, port := range app.remotePorts {
111+
for _, port := range app.config.RemotePorts {
114112
if err := app.ConnectRemote(localConn, port, info); err != nil {
115113
app.LogDebug("error", "reason", err.Error())
116114
} else {

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ module github.com/jackcvr/reverssh
33
go 1.23.0
44

55
require golang.org/x/sync v0.8.0
6+
7+
require github.com/pelletier/go-toml/v2 v2.2.3

go.sum

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,12 @@
1+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
2+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3+
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
4+
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
5+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
6+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
7+
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
8+
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
19
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
210
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
11+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
12+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

main.go

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,71 +3,78 @@ package main
33
import (
44
"flag"
55
"fmt"
6+
"github.com/pelletier/go-toml/v2"
67
"io"
78
"log"
89
"log/slog"
910
"os"
1011
"runtime/debug"
12+
"time"
13+
_ "time/tzdata"
1114
)
1215

16+
var configPath = "/etc/reverssh/reverssh.toml"
17+
18+
type Config struct {
19+
TZ string
20+
Verbose bool
21+
Quiet bool
22+
Bind []string
23+
RemotePorts []int
24+
}
25+
26+
var config = Config{
27+
TZ: "Europe/Vilnius",
28+
Verbose: false,
29+
Quiet: false,
30+
Bind: []string{"0.0.0.0:22"},
31+
RemotePorts: []int{22},
32+
}
33+
1334
func init() {
1435
debug.SetGCPercent(25)
1536
flag.CommandLine.SetOutput(os.Stderr)
1637
}
1738

1839
func main() {
19-
var verbose bool
20-
var logFile string
2140
var showActive bool
22-
var app App
2341

24-
flag.BoolVar(&verbose, "v", false, "Verbose mode")
25-
flag.StringVar(&logFile, "f", "", "Log file (default stdout)")
42+
flag.StringVar(&configPath, "c", configPath, "Path to TOML config file")
2643
flag.BoolVar(&showActive, "active", false, "Show active connections info")
27-
flag.BoolVar(&app.quiet, "q", false, "Do not print anything")
28-
flag.Var(&app.bindAddress, "b", "Local address to listen on")
29-
flag.Var(&app.remotePorts, "p", "Remote ports to connect to, e.g. '22,2222'")
3044
flag.Parse()
3145

32-
if len(app.bindAddress) == 0 {
33-
app.bindAddress = StringList{"0.0.0.0:22"}
34-
}
35-
3646
if showActive {
3747
data, err := ReadStats()
3848
if err != nil && err != io.EOF {
39-
app.Error(err.Error())
49+
panic(err)
4050
} else {
4151
fmt.Print(string(data))
4252
}
4353
return
4454
}
4555

56+
if data, err := os.ReadFile(configPath); err != nil {
57+
panic(err)
58+
} else if err = toml.Unmarshal(data, &config); err != nil {
59+
panic(err)
60+
}
61+
62+
if loc, err := time.LoadLocation(config.TZ); err != nil {
63+
panic(err)
64+
} else {
65+
time.Local = loc
66+
}
67+
4668
log.SetFlags(log.LstdFlags | log.Lmicroseconds)
4769
level := slog.LevelInfo
48-
if verbose {
70+
if config.Verbose {
4971
level = slog.LevelDebug
5072
}
51-
logger, err := NewLogger(logFile, level)
52-
if err != nil {
53-
app.Error(err.Error())
54-
return
55-
}
73+
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: level}))
5674
slog.SetDefault(logger)
5775

58-
if err = app.Run(); err != nil {
76+
app := App{config: config}
77+
if err := app.Run(); err != nil {
5978
app.Error(err.Error())
6079
}
6180
}
62-
63-
func NewLogger(file string, level slog.Level) (*slog.Logger, error) {
64-
w := os.Stdout
65-
if file != "" {
66-
var err error
67-
w, err = os.OpenFile(file, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
68-
if err != nil {
69-
return nil, err
70-
}
71-
}
72-
return slog.New(slog.NewJSONHandler(w, &slog.HandlerOptions{Level: level})), nil
73-
}

openrc/reverssh

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22

33
supervisor=supervise-daemon
44

5-
command="/usr/local/bin/reverssh"
6-
command_args="-b 0.0.0.0:22 -p 22,2222 -f /var/log/reverssh.log"
75
description="Reversing SSH tarpit"
6+
command="/usr/local/bin/reverssh"
7+
command_args="-c /etc/reverssh/reverssh.toml"
8+
command_background=true
9+
pidfile="/run/${RC_SVCNAME}.pid"
10+
output_log="/var/log/${RC_SVCNAME}.log"
11+
error_log="/var/log/${RC_SVCNAME}.log"
812

913
depend() {
1014
need net

reverssh.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
tz = "Europe/Vilnius"
2+
verbose = false
3+
quiet = false
4+
bind = ["0.0.0.0:22"]
5+
remoteports = [22]

systemd/reverssh.service

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Description=Reversing SSH tarpit
33
After=network.target
44

55
[Service]
6-
ExecStart=/usr/local/bin/reverssh -b 0.0.0.0:22 -p 22,2222
6+
ExecStart=/usr/local/bin/reverssh -c /etc/reverssh/reverssh.toml
77
Restart=always
88

99
[Install]

0 commit comments

Comments
 (0)