dddd/gopocs/redis.go

249 lines
6.0 KiB
Go
Raw Normal View History

2023-08-18 08:55:46 +02:00
package gopocs
import (
"dddd/common"
2024-04-03 06:32:26 +02:00
"dddd/ddout"
2023-08-18 08:55:46 +02:00
"dddd/structs"
"dddd/utils"
_ "embed"
2024-01-02 14:50:55 +01:00
"encoding/hex"
2023-08-18 08:55:46 +02:00
"fmt"
"github.com/projectdiscovery/gologger"
"net"
2024-04-03 06:32:26 +02:00
"os"
2023-08-18 08:55:46 +02:00
"strings"
"time"
)
2024-04-03 06:32:26 +02:00
//go:embed dict/redis.txt
2023-08-18 08:55:46 +02:00
var redisUserPasswdDict string
func RedisScan(info *structs.HostInfo) (tmperr error) {
starttime := time.Now().Unix()
flagA, errA := RedisUnauth(info)
if flagA == true && errA == nil {
return errA
}
2024-06-07 19:17:14 +08:00
if structs.GlobalConfig.NoServiceBruteForce {
return errA
}
2023-08-18 08:55:46 +02:00
var upList []string
2024-04-03 06:32:26 +02:00
if structs.GlobalConfig.Password != "" {
upList = append(upList, structs.GlobalConfig.Password)
} else if structs.GlobalConfig.PasswordFile != "" {
b, err := os.ReadFile(structs.GlobalConfig.PasswordFile)
if err == nil {
t := strings.ReplaceAll(string(b), "\r\n", "\n")
for _, v := range strings.Split(t, "\n") {
if !strings.Contains(v, " : ") {
continue
}
upList = append(upList, v)
}
}
} else {
for _, v := range info.UserPass {
_, p := splitUserPass(v)
upList = append(upList, p)
}
for _, v := range strings.Split(strings.ReplaceAll(redisUserPasswdDict, "\r\n", "\n"), "\n") {
upList = append(upList, v)
}
2023-08-18 08:55:46 +02:00
}
2024-04-03 06:32:26 +02:00
2023-08-18 08:55:46 +02:00
upList = utils.RemoveDuplicateElement(upList)
var passwdList []string
// 统计变形后的字典
for _, oriPass := range upList {
oriPass = strings.TrimSuffix(oriPass, "\r")
if strings.Contains(oriPass, "{{key}}") {
for _, sKey := range info.InfoStr {
newKeys := generateKeys(sKey)
for _, nKey := range newKeys {
newPass := strings.Replace(oriPass, "{{key}}", nKey, -1)
passwdList = append(passwdList, newPass)
}
}
newKeys := generateKeys("redis")
for _, nKey := range newKeys {
newPass := strings.Replace(oriPass, "{{key}}", nKey, -1)
passwdList = append(passwdList, newPass)
}
} else {
passwdList = append(passwdList, oriPass)
}
}
passwdList = utils.RemoveDuplicateElement(passwdList)
for _, pass := range passwdList {
2024-01-02 14:50:55 +01:00
gologger.AuditTimeLogger("[Go] [Redis-Brute] try %s:%v Pass:%s", info.Host, info.Ports, pass)
2023-08-18 08:55:46 +02:00
flag, err := RedisConn(info, pass)
if flag == true && err == nil {
return err
} else {
tmperr = err
if CheckErrs(err) {
return err
}
if time.Now().Unix()-starttime > (int64(len(passwdList)) * 6) {
2024-01-02 14:50:55 +01:00
gologger.AuditTimeLogger("[Go] [Redis-Brute] Timeout,break! %s:%v", info.Host, info.Ports)
2023-08-18 08:55:46 +02:00
return err
}
}
}
2024-01-02 14:50:55 +01:00
gologger.AuditTimeLogger("[Go] [Redis-Brute] RedisScan return! %s:%v", info.Host, info.Ports)
2023-08-18 08:55:46 +02:00
return tmperr
}
func RedisConn(info *structs.HostInfo, pass string) (flag bool, err error) {
flag = false
realhost := fmt.Sprintf("%s:%v", info.Host, info.Ports)
conn, err := common.WrapperTcpWithTimeout("tcp", realhost, time.Duration(6)*time.Second)
defer func() {
if conn != nil {
conn.Close()
}
}()
if err != nil {
return flag, err
}
err = conn.SetReadDeadline(time.Now().Add(time.Duration(6) * time.Second))
if err != nil {
return flag, err
}
_, err = conn.Write([]byte(fmt.Sprintf("auth %s\r\n", pass)))
if err != nil {
return flag, err
}
reply, err := readreply(conn)
if err != nil {
return flag, err
}
if strings.Contains(reply, "+OK") {
flag = true
result := fmt.Sprintf("Redis:%s %s", realhost, pass)
2024-04-03 06:32:26 +02:00
// gologger.Silent().Msg("[GoPoc] " + result)
2023-08-18 08:55:46 +02:00
showData := fmt.Sprintf("Host: %v\nPassword: %v\n", realhost, pass)
2024-04-03 06:32:26 +02:00
ddout.FormatOutput(ddout.OutputMessage{
Type: "GoPoc",
IP: "",
IPs: nil,
Port: "",
Protocol: "",
Web: ddout.WebInfo{},
Finger: nil,
Domain: "",
GoPoc: ddout.GoPocsResultType{PocName: "Redis-Login",
Security: "HIGH",
Target: realhost,
InfoLeft: showData,
InfoRight: reply,
Description: "Redis未授权/弱口令",
ShowMsg: result},
AdditionalMsg: "",
})
2023-08-18 08:55:46 +02:00
GoPocWriteResult(structs.GoPocsResultType{
PocName: "Redis-Login",
Security: "HIGH",
Target: realhost,
InfoLeft: showData,
InfoRight: reply,
Description: "Redis未授权/弱口令",
})
}
return flag, err
}
func RedisUnauth(info *structs.HostInfo) (flag bool, err error) {
flag = false
realhost := fmt.Sprintf("%s:%v", info.Host, info.Ports)
conn, err := common.WrapperTcpWithTimeout("tcp", realhost, time.Duration(6)*time.Second)
defer func() {
if conn != nil {
conn.Close()
}
}()
if err != nil {
return flag, err
}
err = conn.SetReadDeadline(time.Now().Add(time.Duration(6) * time.Second))
if err != nil {
return flag, err
}
_, err = conn.Write([]byte("info\r\n"))
2024-01-02 14:50:55 +01:00
gologger.AuditTimeLogger("[GoPoc] [Redis-Unauth] Dumped TCP request for %s\n\n%s\n", realhost, hex.Dump([]byte("info\r\n")))
2023-08-18 08:55:46 +02:00
if err != nil {
return flag, err
}
reply, err := readreply(conn)
if err != nil {
return flag, err
}
2024-01-02 14:50:55 +01:00
gologger.AuditTimeLogger("[GoPoc] [Redis-Unauth] Dumped TCP response for %s\n\n%s\n", realhost, hex.Dump([]byte(reply)))
2023-08-18 08:55:46 +02:00
if strings.Contains(reply, "redis_version") {
flag = true
result := fmt.Sprintf("Redis:%s %s", realhost, "Unauthorized")
2024-04-03 06:32:26 +02:00
// gologger.Silent().Msg("[GoPoc] " + result)
2023-08-18 08:55:46 +02:00
showData := fmt.Sprintf("Host: %v\nUnauthorized\n", realhost)
2024-04-03 06:32:26 +02:00
ddout.FormatOutput(ddout.OutputMessage{
Type: "GoPoc",
IP: "",
IPs: nil,
Port: "",
Protocol: "",
Web: ddout.WebInfo{},
Finger: nil,
Domain: "",
GoPoc: ddout.GoPocsResultType{PocName: "Redis-Login",
Security: "HIGH",
Target: realhost,
InfoLeft: showData,
InfoRight: reply,
Description: "Redis未授权/弱口令",
ShowMsg: result},
AdditionalMsg: "",
})
2023-08-18 08:55:46 +02:00
GoPocWriteResult(structs.GoPocsResultType{
PocName: "Redis-Login",
Security: "HIGH",
Target: realhost,
InfoLeft: showData,
InfoRight: reply,
Description: "Redis未授权/弱口令",
})
}
return flag, err
}
func readreply(conn net.Conn) (result string, err error) {
size := 5 * 1024
buf := make([]byte, size)
for {
count, err := conn.Read(buf)
if err != nil {
break
}
result += string(buf[0:count])
if count < size {
break
}
}
return result, err
}