Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/js/libs/redis/redis.go
2070 views
1
package redis
2
3
import (
4
"context"
5
"fmt"
6
"time"
7
8
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
9
"github.com/redis/go-redis/v9"
10
11
"github.com/praetorian-inc/fingerprintx/pkg/plugins"
12
pluginsredis "github.com/praetorian-inc/fingerprintx/pkg/plugins/services/redis"
13
)
14
15
// GetServerInfo returns the server info for a redis server
16
// @example
17
// ```javascript
18
// const redis = require('nuclei/redis');
19
// const info = redis.GetServerInfo('acme.com', 6379);
20
// ```
21
func GetServerInfo(ctx context.Context, host string, port int) (string, error) {
22
executionId := ctx.Value("executionId").(string)
23
return memoizedgetServerInfo(executionId, host, port)
24
}
25
26
// @memo
27
func getServerInfo(executionId string, host string, port int) (string, error) {
28
if !protocolstate.IsHostAllowed(executionId, host) {
29
// host is not valid according to network policy
30
return "", protocolstate.ErrHostDenied.Msgf(host)
31
}
32
// create a new client
33
client := redis.NewClient(&redis.Options{
34
Addr: fmt.Sprintf("%s:%d", host, port),
35
Password: "", // no password set
36
DB: 0, // use default DB
37
})
38
defer func() {
39
_ = client.Close()
40
}()
41
42
// Ping the Redis server
43
_, err := client.Ping(context.TODO()).Result()
44
if err != nil {
45
return "", err
46
}
47
48
// Get Redis server info
49
infoCmd := client.Info(context.TODO())
50
if infoCmd.Err() != nil {
51
return "", infoCmd.Err()
52
}
53
54
return infoCmd.Val(), nil
55
}
56
57
// Connect tries to connect redis server with password
58
// @example
59
// ```javascript
60
// const redis = require('nuclei/redis');
61
// const connected = redis.Connect('acme.com', 6379, 'password');
62
// ```
63
func Connect(ctx context.Context, host string, port int, password string) (bool, error) {
64
executionId := ctx.Value("executionId").(string)
65
return memoizedconnect(executionId, host, port, password)
66
}
67
68
// @memo
69
func connect(executionId string, host string, port int, password string) (bool, error) {
70
if !protocolstate.IsHostAllowed(executionId, host) {
71
// host is not valid according to network policy
72
return false, protocolstate.ErrHostDenied.Msgf(host)
73
}
74
// create a new client
75
client := redis.NewClient(&redis.Options{
76
Addr: fmt.Sprintf("%s:%d", host, port),
77
Password: password, // no password set
78
DB: 0, // use default DB
79
})
80
defer func() {
81
_ = client.Close()
82
}()
83
84
_, err := client.Ping(context.TODO()).Result()
85
if err != nil {
86
return false, err
87
}
88
// Get Redis server info
89
infoCmd := client.Info(context.TODO())
90
if infoCmd.Err() != nil {
91
return false, infoCmd.Err()
92
}
93
94
return true, nil
95
}
96
97
// GetServerInfoAuth returns the server info for a redis server
98
// @example
99
// ```javascript
100
// const redis = require('nuclei/redis');
101
// const info = redis.GetServerInfoAuth('acme.com', 6379, 'password');
102
// ```
103
func GetServerInfoAuth(ctx context.Context, host string, port int, password string) (string, error) {
104
executionId := ctx.Value("executionId").(string)
105
return memoizedgetServerInfoAuth(executionId, host, port, password)
106
}
107
108
// @memo
109
func getServerInfoAuth(executionId string, host string, port int, password string) (string, error) {
110
if !protocolstate.IsHostAllowed(executionId, host) {
111
// host is not valid according to network policy
112
return "", protocolstate.ErrHostDenied.Msgf(host)
113
}
114
// create a new client
115
client := redis.NewClient(&redis.Options{
116
Addr: fmt.Sprintf("%s:%d", host, port),
117
Password: password, // no password set
118
DB: 0, // use default DB
119
})
120
defer func() {
121
_ = client.Close()
122
}()
123
124
// Ping the Redis server
125
_, err := client.Ping(context.TODO()).Result()
126
if err != nil {
127
return "", err
128
}
129
130
// Get Redis server info
131
infoCmd := client.Info(context.TODO())
132
if infoCmd.Err() != nil {
133
return "", infoCmd.Err()
134
}
135
136
return infoCmd.Val(), nil
137
}
138
139
// IsAuthenticated checks if the redis server requires authentication
140
// @example
141
// ```javascript
142
// const redis = require('nuclei/redis');
143
// const isAuthenticated = redis.IsAuthenticated('acme.com', 6379);
144
// ```
145
func IsAuthenticated(ctx context.Context, host string, port int) (bool, error) {
146
executionId := ctx.Value("executionId").(string)
147
return memoizedisAuthenticated(executionId, host, port)
148
}
149
150
// @memo
151
func isAuthenticated(executionId string, host string, port int) (bool, error) {
152
plugin := pluginsredis.REDISPlugin{}
153
timeout := 5 * time.Second
154
dialer := protocolstate.GetDialersWithId(executionId)
155
if dialer == nil {
156
return false, fmt.Errorf("dialers not initialized for %s", executionId)
157
}
158
159
conn, err := dialer.Fastdialer.Dial(context.TODO(), "tcp", fmt.Sprintf("%s:%d", host, port))
160
if err != nil {
161
return false, err
162
}
163
defer func() {
164
_ = conn.Close()
165
}()
166
167
_, err = plugin.Run(conn, timeout, plugins.Target{Host: host})
168
if err != nil {
169
return false, err
170
}
171
return true, nil
172
}
173
174
// RunLuaScript runs a lua script on the redis server
175
// @example
176
// ```javascript
177
// const redis = require('nuclei/redis');
178
// const result = redis.RunLuaScript('acme.com', 6379, 'password', 'return redis.call("get", KEYS[1])');
179
// ```
180
func RunLuaScript(ctx context.Context, host string, port int, password string, script string) (interface{}, error) {
181
executionId := ctx.Value("executionId").(string)
182
if !protocolstate.IsHostAllowed(executionId, host) {
183
// host is not valid according to network policy
184
return false, protocolstate.ErrHostDenied.Msgf(host)
185
}
186
// create a new client
187
client := redis.NewClient(&redis.Options{
188
Addr: fmt.Sprintf("%s:%d", host, port),
189
Password: password,
190
DB: 0, // use default DB
191
})
192
defer func() {
193
_ = client.Close()
194
}()
195
196
// Ping the Redis server
197
_, err := client.Ping(context.TODO()).Result()
198
if err != nil {
199
return "", err
200
}
201
202
// Get Redis server info
203
infoCmd := client.Eval(context.Background(), script, []string{})
204
205
if infoCmd.Err() != nil {
206
return "", infoCmd.Err()
207
}
208
209
return infoCmd.Val(), nil
210
}
211
212