mirror of
https://github.com/SleepingBag945/dddd.git
synced 2025-06-08 05:57:10 +00:00
289 lines
7.4 KiB
Go
Executable File
289 lines
7.4 KiB
Go
Executable File
package gopocs
|
||
|
||
import (
|
||
"bytes"
|
||
"crypto/aes"
|
||
"crypto/cipher"
|
||
"dddd/common/report"
|
||
"dddd/structs"
|
||
"dddd/utils"
|
||
"encoding/base64"
|
||
"net"
|
||
"os"
|
||
"strings"
|
||
"sync"
|
||
)
|
||
|
||
var PluginList = map[string]interface{}{
|
||
"NetBios-GetHostInfo": NetBIOS,
|
||
"RPC-GetHostInfo": Findnet,
|
||
"SSH-Crack": SshScan,
|
||
"FTP-Crack": FtpScan,
|
||
"Mysql-Crack": MysqlScan,
|
||
"Mssql-Crack": MssqlScan,
|
||
"Oracle-Crack": OracleScan,
|
||
"MongoDB-Crack": MongodbScan,
|
||
"RDP-Crack": RdpScan,
|
||
"Redis-Crack": RedisScan,
|
||
"SMB-MS17-010": MS17010,
|
||
"PostgreSQL-Crack": PostgresScan,
|
||
"SMB-Crack": SmbScan,
|
||
"Telnet-Crack": TelnetScan,
|
||
"Memcache-Crack": MemcachedScan,
|
||
"JDWP-Scan": JDWPScan,
|
||
"Shiro-Key-Crack": ShiroKeyCheck,
|
||
"ADB-Scan": ADBScan,
|
||
}
|
||
|
||
var WriteResultLock sync.Mutex
|
||
|
||
func ReadBytes(conn net.Conn) (result []byte, err error) {
|
||
size := 4096
|
||
buf := make([]byte, size)
|
||
for {
|
||
count, err := conn.Read(buf)
|
||
if err != nil {
|
||
break
|
||
}
|
||
result = append(result, buf[0:count]...)
|
||
if count < size {
|
||
break
|
||
}
|
||
}
|
||
if len(result) > 0 {
|
||
err = nil
|
||
}
|
||
return result, err
|
||
}
|
||
|
||
var key = "0123456789abcdef"
|
||
|
||
func AesEncrypt(orig string, key string) string {
|
||
// 转成字节数组
|
||
origData := []byte(orig)
|
||
k := []byte(key)
|
||
// 分组秘钥
|
||
// NewCipher该函数限制了输入k的长度必须为16, 24或者32
|
||
block, _ := aes.NewCipher(k)
|
||
// 获取秘钥块的长度
|
||
blockSize := block.BlockSize()
|
||
// 补全码
|
||
origData = PKCS7Padding(origData, blockSize)
|
||
// 加密模式
|
||
blockMode := cipher.NewCBCEncrypter(block, k[:blockSize])
|
||
// 创建数组
|
||
cryted := make([]byte, len(origData))
|
||
// 加密
|
||
blockMode.CryptBlocks(cryted, origData)
|
||
return base64.StdEncoding.EncodeToString(cryted)
|
||
}
|
||
func AesDecrypt(cryted string, key string) string {
|
||
// 转成字节数组
|
||
crytedByte, _ := base64.StdEncoding.DecodeString(cryted)
|
||
k := []byte(key)
|
||
// 分组秘钥
|
||
block, _ := aes.NewCipher(k)
|
||
// 获取秘钥块的长度
|
||
blockSize := block.BlockSize()
|
||
// 加密模式
|
||
blockMode := cipher.NewCBCDecrypter(block, k[:blockSize])
|
||
// 创建数组
|
||
orig := make([]byte, len(crytedByte))
|
||
// 解密
|
||
blockMode.CryptBlocks(orig, crytedByte)
|
||
// 去补全码
|
||
orig = PKCS7UnPadding(orig)
|
||
return string(orig)
|
||
}
|
||
|
||
// 补码
|
||
// AES加密数据块分组长度必须为128bit(byte[16]),密钥长度可以是128bit(byte[16])、192bit(byte[24])、256bit(byte[32])中的任意一个。
|
||
func PKCS7Padding(ciphertext []byte, blocksize int) []byte {
|
||
padding := blocksize - len(ciphertext)%blocksize
|
||
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
|
||
return append(ciphertext, padtext...)
|
||
}
|
||
|
||
// 去码
|
||
func PKCS7UnPadding(origData []byte) []byte {
|
||
length := len(origData)
|
||
unpadding := int(origData[length-1])
|
||
return origData[:(length - unpadding)]
|
||
}
|
||
|
||
func generateKeys(key string) []string {
|
||
var results []string
|
||
results = append(results, strings.ToLower(key))
|
||
results = append(results, strings.ToUpper(key))
|
||
results = append(results, strings.ToUpper(strings.ToUpper(key[:1])+key[1:]))
|
||
return results
|
||
}
|
||
|
||
func splitUserPass(userPasswd string) (user string, oriPass string) {
|
||
sp := strings.Split(userPasswd, " : ")
|
||
user = ""
|
||
oriPass = ""
|
||
if len(sp) != 2 {
|
||
user = sp[0]
|
||
oriPass = ""
|
||
} else {
|
||
user = sp[0]
|
||
oriPass = sp[1]
|
||
}
|
||
user = strings.TrimSuffix(user, "\r")
|
||
oriPass = strings.TrimSuffix(oriPass, "\r")
|
||
return user, oriPass
|
||
}
|
||
|
||
func sortUserPassword(info *structs.HostInfo, UserPasswdDict string, DefaultKeys []string) []structs.UserPasswd {
|
||
var userPasswdList []structs.UserPasswd
|
||
var upList []string
|
||
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 {
|
||
upList = info.UserPass
|
||
// 兼容Windows
|
||
UserPasswdDict = strings.ReplaceAll(UserPasswdDict, "\r\n", "\n")
|
||
for _, v := range strings.Split(UserPasswdDict, "\n") {
|
||
upList = append(upList, v)
|
||
}
|
||
}
|
||
upList = utils.RemoveDuplicateElement(upList)
|
||
|
||
// 统计变形后的字典
|
||
for _, userPasswd := range upList {
|
||
user, oriPass := splitUserPass(userPasswd)
|
||
|
||
if strings.Contains(oriPass, "{{key}}") {
|
||
for _, sKey := range info.InfoStr {
|
||
newKeys := generateKeys(sKey)
|
||
for _, nKey := range newKeys {
|
||
newPass := strings.Replace(oriPass, "{{key}}", nKey, -1)
|
||
userPasswdList = append(userPasswdList, structs.UserPasswd{UserName: user, Password: newPass})
|
||
}
|
||
|
||
}
|
||
for _, dk := range DefaultKeys {
|
||
newKeys := generateKeys(dk)
|
||
for _, nKey := range newKeys {
|
||
newPass := strings.Replace(oriPass, "{{key}}", nKey, -1)
|
||
userPasswdList = append(userPasswdList, structs.UserPasswd{UserName: user, Password: newPass})
|
||
}
|
||
}
|
||
|
||
} else {
|
||
userPasswdList = append(userPasswdList, structs.UserPasswd{UserName: user, Password: oriPass})
|
||
}
|
||
}
|
||
return RemoveDuplicateUserPass(userPasswdList)
|
||
}
|
||
|
||
func RemoveDuplicateUserPass(input []structs.UserPasswd) []structs.UserPasswd {
|
||
temp := map[structs.UserPasswd]struct{}{}
|
||
var result []structs.UserPasswd
|
||
for _, item := range input {
|
||
if _, ok := temp[item]; !ok {
|
||
temp[item] = struct{}{}
|
||
result = append(result, item)
|
||
}
|
||
}
|
||
return result
|
||
}
|
||
|
||
func CheckErrs(err error) bool {
|
||
if err == nil {
|
||
return false
|
||
}
|
||
errs := []string{
|
||
"closed by the remote host", "too many connections",
|
||
"i/o timeout", "EOF", "A connection attempt failed",
|
||
"established connection failed", "connection attempt failed",
|
||
"Unable to read", "is not allowed to connect to this",
|
||
"no pg_hba.conf entry",
|
||
"No connection could be made",
|
||
"invalid packet size",
|
||
"bad connection",
|
||
}
|
||
for _, key := range errs {
|
||
if strings.Contains(strings.ToLower(err.Error()), strings.ToLower(key)) {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
func GoPocWriteResult(result structs.GoPocsResultType) {
|
||
WriteResultLock.Lock()
|
||
report.AddResultByGoPocResult(result)
|
||
WriteResultLock.Unlock()
|
||
}
|
||
|
||
func readDict(name string) string {
|
||
bt, err := os.ReadFile(name)
|
||
if err != nil {
|
||
return ""
|
||
}
|
||
return string(bt)
|
||
}
|
||
|
||
func fileExists(filePath string) bool {
|
||
_, err := os.Stat(filePath)
|
||
if err != nil {
|
||
if os.IsNotExist(err) {
|
||
return false
|
||
}
|
||
}
|
||
return true
|
||
}
|
||
|
||
// initDic 初始化用于爆破的字典
|
||
func initDic() {
|
||
basePath := "config/dict/"
|
||
|
||
if fileExists(basePath + "ftp.txt") {
|
||
ftpUserPasswdDict = readDict(basePath + "ftp.txt")
|
||
}
|
||
if fileExists(basePath + "") {
|
||
mssqlUserPasswdDict = readDict(basePath + "mssql.txt")
|
||
}
|
||
if fileExists(basePath + "") {
|
||
mysqlUserPasswdDict = readDict(basePath + "mysql.txt")
|
||
}
|
||
if fileExists(basePath + "") {
|
||
oracleUserPasswdDict = readDict(basePath + "oracle.txt")
|
||
}
|
||
if fileExists(basePath + "") {
|
||
postgreSQLUserPasswdDict = readDict(basePath + "postgresql.txt")
|
||
}
|
||
if fileExists(basePath + "") {
|
||
rdpUserPasswdDict = readDict(basePath + "rdp.txt")
|
||
}
|
||
if fileExists(basePath + "") {
|
||
redisUserPasswdDict = readDict(basePath + "redis.txt")
|
||
}
|
||
if fileExists(basePath + "") {
|
||
smbUserPasswdDict = readDict(basePath + "smb.txt")
|
||
}
|
||
if fileExists(basePath + "") {
|
||
sshUserPasswdDict = readDict(basePath + "ssh.txt")
|
||
}
|
||
if fileExists(basePath + "") {
|
||
telnetUserPasswdDict = readDict(basePath + "telnet.txt")
|
||
}
|
||
if fileExists(basePath + "") {
|
||
ShiroKeys = readDict(basePath + "shirokeys.txt")
|
||
}
|
||
|
||
}
|