Skip to content

Commit

Permalink
go mod tidy
Browse files Browse the repository at this point in the history
  • Loading branch information
thinkoaa committed Sep 11, 2024
1 parent dcb2fdb commit 74ef5ab
Show file tree
Hide file tree
Showing 8 changed files with 227 additions and 97 deletions.
28 changes: 15 additions & 13 deletions config.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
[listener]#******非特殊情况,默认即可******本地监听端口,其他工具中的SOCKS5代理指定为该IP:PORT,即可轮询使用其他代理
IP='127.0.0.1'
PORT='10086'
PORT=10086
userName=''#用户名和密码都不为空时,会进行认证,防止部署到vps上时,被其他人使用
password=''

[checkSocks]#******非特殊情况,默认即可******
#通过访问实际url来验证代理的可用性
checkURL='https://www.baidu.com'#可以配置为要访问的目标地址,确保所有代理都能访问到目标地址
checkRspKeywords='百度一下'#上面地址原始响应中的某个字符串,用来验证通过代理访问目标时有无因某种原因被ban掉。
maxConcurrentReq='15'#同时最多N个并发通过代理访问上面的地址,检测socks5代理是否可用,可根据网络环境调整。云主机的话开500、1000都可以,本机的话,开三五十差不多。
timeout='6'#单位秒,验证socks5代理的超时时间,建议保持在5或6,检查及使用代理访问上面的地址时,超过这个时间,判定无效
maxConcurrentReq=500 #同时最多N个并发通过代理访问上面的地址,检测socks5代理是否可用,可根据网络环境调整。云主机的话开500、1000都可以,本机的话,开三五十差不多。
timeout=6 #单位秒,验证socks5代理的超时时间,建议保持在5或6,检查及使用代理访问上面的地址时,超过这个时间,判定无效

[checkSocks.checkGeolocate]##******非特殊情况,默认即可******通过访问返回IP归属地信息的URL和关键字判断,来排除某些代理,如:某些情况下,真正要访问的系统限制只有大陆地区IP可以访问
switch='close' #open:启用,非open:禁用
Expand All @@ -19,21 +21,21 @@ includeKeywords=['中国']#格式如:['中国','北京']则只获取中国北
[FOFA]
switch = 'close' #open:启用,非open:禁用
apiUrl='https://fofa.info/api/v1/search/all'
email = 'xxxxx@xxx.com'
key = '54eddce1xxxxxxxxxxxxxxxx49836612'
queryString = 'protocol=="socks5" && country="CN" && banner="Method:No Authentication"'#官方语法
resultSize='500' #此处最大为10000,需小于等于从官网web界面看到的结果数量
email = 'xxxx@xxx.com'
key = '54eddxxxxxx8axxxxxxxxdfb4xxxxxx612'
queryString = 'protocol=="socks5" && country="CN" && banner="Method:No Authentication"'
resultSize=300 #此处最大为10000,需小于等于从官网web界面看到的结果数量

[QUAKE]
switch = 'close'
apiUrl='https://quake.360.net/api/v3/search/quake_service'
key = '962xxx36-xxxxxxxxxxxxxxxx-5efxxxxfc90b0a'
queryString = 'service:socks5 AND country: "CN" AND response:"No authentication"'#官方语法
resultSize='500' #此处最大为10000,需小于等于从官网web界面看到的结果数量
key = '9621xxx6-2xxxxxx-8c98-xxxxxxx90b0a'
queryString = 'service:socks5 AND country: "CN" AND response:"No authentication"'
resultSize=300 #此处最大为10000,需小于等于从官网web界面看到的结果数量

[HUNTER]
switch = 'close'
apiUrl='https://hunter.qianxin.com/openApi/search'
key = '9c1698e0xxxxxxxxxxxxxxxxa6e90758edcxxxx23533f9xxxxxxxxxxxxxxxx9ce18'
queryString = 'protocol=="socks5"&&protocol.banner="No authentication"&&ip.country="CN"'#官方语法
resultSize='300' #最小为100,按100条/每页翻页,最大值需小于从官网web界面看到的结果数量,值需为100的整倍数,如200、300、1000、2000等
key = '9c1698e044xxxa6e90xxxxdc2xxxxx2048f7xxxxx8'
queryString = 'protocol=="socks5"&&protocol.banner="No authentication"&&ip.country="CN"'
resultSize=300 #最小为100,按100条/每页翻页,最大值需小于从官网web界面看到的结果数量,值需为100的整倍数,如200、300、1000、2000等
11 changes: 9 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
module Deadpool

go 1.20
go 1.21.0

require github.com/BurntSushi/toml v1.4.0
toolchain go1.23.0

require (
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5
github.com/pelletier/go-toml/v2 v2.2.3
)

require golang.org/x/net v0.29.0
16 changes: 14 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,2 +1,14 @@
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
58 changes: 34 additions & 24 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,39 @@ package main
import (
"Deadpool/utils"
"fmt"
"net"
"io"
"log"
"os"
"strconv"
"strings"
"time"

"github.com/BurntSushi/toml"
"github.com/armon/go-socks5"
)

func main() {

utils.Banner()
fmt.Println("By:thinkoaa GitHub:https://github.com/thinkoaa/Deadpool\n\n")
//读取配置文件
var config map[string]interface{}
if _, err := toml.DecodeFile("config.toml", &config); err != nil {
fmt.Println("读取config.toml失败,请检查配置,格式一定要正确", err)
os.Exit(1)
}
// 开启监听
listenerConfig := config["listener"].(map[string]interface{})
listener := listenerConfig["IP"].(string) + ":" + listenerConfig["PORT"].(string)
socketServer, err := net.Listen("tcp", listener)
config, err := utils.LoadConfig("config.toml")
if err != nil {
fmt.Printf("本地监听服务启动失败:%v\n", err)
fmt.Printf("读取config.toml失败,请检查配置,格式一定要正确%w\n", err)
os.Exit(1)
}

//从本地文件中取socks代理
fmt.Println("***直接使用fmt打印当前使用的代理,若高并发时,命令行打印可能会阻塞,不对打印做特殊处理,可忽略,不会影响实际的请求转发***\n")
utils.GetSocksFromFile(utils.LastDataFile)
//从fofa获取
utils.Wg.Add(1)
go utils.GetSocksFromFofa(config["FOFA"].(map[string]interface{}))
go utils.GetSocksFromFofa(config.FOFA)
//从hunter获取
utils.Wg.Add(1)
go utils.GetSocksFromHunter(config["HUNTER"].(map[string]interface{}))
go utils.GetSocksFromHunter(config.HUNTER)
//从quake中取
utils.Wg.Add(1)
go utils.GetSocksFromQuake(config["QUAKE"].(map[string]interface{}))
go utils.GetSocksFromQuake(config.QUAKE)
utils.Wg.Wait()
//等待所有 goroutine 完成
if len(utils.SocksList) == 0 {
Expand All @@ -52,7 +49,8 @@ func main() {

//开始检测代理存活性
startTime := time.Now()
utils.CheckSocks(config["checkSocks"].(map[string]interface{}))
utils.Timeout = config.CheckSocks.Timeout
utils.CheckSocks(config.CheckSocks)

sec := int(time.Since(startTime).Seconds())
if sec == 0 {
Expand All @@ -66,13 +64,25 @@ func main() {

utils.WriteLinesToFile() //存活代理写入硬盘,以备下次启动直接读取

fmt.Printf("======其他工具通过配置 socks5://%v 使用收集的代理,此处若提示0.0.0.0:xxxx,使用时需指定为具体地址======\n", listener)
for { //持续监听请求
reqFromClient, err := socketServer.Accept()
if err != nil {
fmt.Printf("本次客户端发起的请求出错:%v\n", err)
continue
}
go utils.TransmitReqFromClient(reqFromClient)
// 开启监听
conf := &socks5.Config{
Dial: utils.DefineDial,
Logger: log.New(io.Discard, "", log.LstdFlags),
}
userName := strings.TrimSpace(config.Listener.UserName)
password := strings.TrimSpace(config.Listener.Password)
if userName != "" && password != "" {
cator := socks5.UserPassAuthenticator{Credentials: socks5.StaticCredentials{
userName: password,
}}
conf.AuthMethods = []socks5.Authenticator{cator}
}
server, _ := socks5.New(conf)
listener := config.Listener.IP + ":" + strconv.Itoa(config.Listener.Port)
fmt.Printf("======其他工具通过配置 socks5://%v 使用收集的代理,如有账号密码,记得配置======\n", listener)
if err := server.ListenAndServe("tcp", listener); err != nil {
fmt.Printf("本地监听服务启动失败:%v\n", err)
os.Exit(1)
}

}
2 changes: 1 addition & 1 deletion utils/globals.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ var (
SocksList []string
EffectiveList []string
proxyIndex int
timeout int
Timeout int
LastDataFile = "lastData.txt"
Wg sync.WaitGroup
mu sync.Mutex
Expand Down
75 changes: 75 additions & 0 deletions utils/load_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package utils

import (
"os"

toml "github.com/pelletier/go-toml/v2"
)

type Config struct {
Listener ListenerConfig `toml:"listener"`
CheckSocks CheckSocksConfig `toml:"checkSocks"`
FOFA FOFAConfig `toml:"FOFA"`
QUAKE QUAKEConfig `toml:"QUAKE"`
HUNTER HUNTERConfig `toml:"HUNTER"`
}

type ListenerConfig struct {
IP string `toml:"IP"`
Port int `toml:"PORT"`
UserName string `toml:"userName"`
Password string `toml:"password"`
}

type CheckSocksConfig struct {
CheckURL string `toml:"checkURL"`
CheckRspKeywords string `toml:"checkRspKeywords"`
MaxConcurrentReq int `toml:"maxConcurrentReq"`
Timeout int `toml:"timeout"`
CheckGeolocate CheckGeolocateConfig `toml:"checkGeolocate"`
}

type CheckGeolocateConfig struct {
Switch string `toml:"switch"`
CheckURL string `toml:"checkURL"`
ExcludeKeywords []string `toml:"excludeKeywords"`
IncludeKeywords []string `toml:"includeKeywords"`
}

type FOFAConfig struct {
Switch string `toml:"switch"`
APIURL string `toml:"apiUrl"`
Email string `toml:"email"`
Key string `toml:"key"`
QueryString string `toml:"queryString"`
ResultSize int `toml:"resultSize"`
}

type QUAKEConfig struct {
Switch string `toml:"switch"`
APIURL string `toml:"apiUrl"`
Key string `toml:"key"`
QueryString string `toml:"queryString"`
ResultSize int `toml:"resultSize"`
}

type HUNTERConfig struct {
Switch string `toml:"switch"`
APIURL string `toml:"apiUrl"`
Key string `toml:"key"`
QueryString string `toml:"queryString"`
ResultSize int `toml:"resultSize"`
}

func LoadConfig(path string) (Config, error) {
var config Config
// 读取并解析 TOML 文件
data, err := os.ReadFile(path)
if err != nil {
return config, err
}

err = toml.Unmarshal(data, &config)

return config, err
}
62 changes: 37 additions & 25 deletions utils/netspace.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,18 @@ import (
)

// 从quake获取,结果为IP:PORT
func GetSocksFromQuake(config map[string]interface{}) {
func GetSocksFromQuake(quake QUAKEConfig) {
defer Wg.Done()
if config["switch"] != "open" {
if quake.Switch != "open" {
fmt.Println("---未开启quake---")
return
}

fmt.Println("***已开启quake,将根据配置条件从quake中获取" + config["resultSize"].(string) + "条数据,然后进行有效性检测***")
jsonCondition := "{\"query\": \"" + strings.Replace(config["queryString"].(string), `"`, `\"`, -1) + "\",\"start\": 0,\"size\": " + config["resultSize"].(string) + ",\"include\":[\"ip\",\"port\"]}"
fmt.Printf("***已开启quake,将根据配置条件从quake中获取%d条数据,然后进行有效性检测***\n", quake.ResultSize)
jsonCondition := "{\"query\": \"" + strings.Replace(quake.QueryString, `"`, `\"`, -1) + "\",\"start\": 0,\"size\": " + strconv.Itoa(quake.ResultSize) + ",\"include\":[\"ip\",\"port\"]}"
headers := map[string]string{
"X-QuakeToken": config["key"].(string),
"X-QuakeToken": quake.Key,
"Content-Type": "application/json"}
content, err := fetchContent(config["apiUrl"].(string), "POST", 1500, nil, headers, jsonCondition)
content, err := fetchContent(quake.APIURL, "POST", 60, nil, headers, jsonCondition)
if err != nil {
fmt.Println("quake异常", err)
return
Expand All @@ -47,21 +46,21 @@ func GetSocksFromQuake(config map[string]interface{}) {
}

// 从FOFA获取,结果为IP:PORT
func GetSocksFromFofa(config map[string]interface{}) {
func GetSocksFromFofa(fofa FOFAConfig) {
defer Wg.Done()
if config["switch"] != "open" {
if fofa.Switch != "open" {
fmt.Println("---未开启fofa---")
return
}
fmt.Println("***已开启fofa,将根据配置条件从fofa中获取" + config["resultSize"].(string) + "条数据,然后进行有效性检测***")
fmt.Printf("***已开启fofa,将根据配置条件从fofa中获取%d条数据,然后进行有效性检测***\n", fofa.ResultSize)

params := map[string]string{
"email": config["email"].(string),
"key": config["key"].(string),
"email": fofa.Email,
"key": fofa.Key,
"fields": "ip,port",
"qbase64": base64.StdEncoding.EncodeToString([]byte(config["queryString"].(string))),
"size": config["resultSize"].(string)}
content, err := fetchContent(config["apiUrl"].(string), "GET", 1500, params, nil, "")
"qbase64": base64.URLEncoding.EncodeToString([]byte(fofa.QueryString)),
"size": strconv.Itoa(fofa.ResultSize)}
content, err := fetchContent(fofa.APIURL, "GET", 60, params, nil, "")
if err != nil {
fmt.Println("访问fofa异常", err)
return
Expand All @@ -82,23 +81,24 @@ func GetSocksFromFofa(config map[string]interface{}) {
}

// 从鹰图获取,结果为IP:PORT
func GetSocksFromHunter(config map[string]interface{}) {
func GetSocksFromHunter(hunter HUNTERConfig) {
defer Wg.Done()
if config["switch"] != "open" {
if hunter.Switch != "open" {
fmt.Println("---未开启hunter---")
return
}
fmt.Println("***已开启hunter,将根据配置条件从hunter中获取" + config["resultSize"].(string) + "条数据,然后进行有效性检测***")
hunterResultSize, _ := strconv.Atoi(config["resultSize"].(string))
fmt.Printf("***已开启hunter,将根据配置条件从hunter中获取%d条数据,然后进行有效性检测***\n", hunter.ResultSize)

for i := 1; i <= hunterResultSize/100; i++ {
var exeData int //记录处理了几条
end := hunter.ResultSize / 100
for i := 1; i <= end; i++ {
params := map[string]string{
"api-key": config["key"].(string),
"search": base64.StdEncoding.EncodeToString([]byte(config["queryString"].(string))),
"api-key": hunter.Key,
"search": base64.URLEncoding.EncodeToString([]byte(hunter.QueryString)),
"page": strconv.Itoa(i),
"page_size": "100"}
fmt.Printf("HUNTER每页100条,正在查询第%v页\n", i)
content, err := fetchContent(config["apiUrl"].(string), "GET", 30, params, nil, "")
fmt.Printf("HUNTER:每页100条,正在查询第%v页\n", i)
content, err := fetchContent(hunter.APIURL, "GET", 60, params, nil, "")
if err != nil {
fmt.Println("访问hunter异常", err)
return
Expand All @@ -110,15 +110,27 @@ func GetSocksFromHunter(config map[string]interface{}) {
fmt.Println("HUNTER:", data["message"])
return
}

rsData := data["data"].(map[string]interface{})
total := rsData["total"].(float64)
if total == 0 {
fmt.Println("HUNTER:xxx根据配置语法,未取到数据xxx")
break
}
arr := rsData["arr"].([]interface{})
for _, item := range arr {
itemMap := item.(map[string]interface{})
ip := itemMap["ip"].(string)
port := itemMap["port"].(float64)
exeData++
addSocks(ip + ":" + strconv.FormatFloat(port, 'f', -1, 64))
}
time.Sleep(3 * time.Second) //防止hunter提示访问过快获取不到结果
if float64(exeData) >= total {
break
}
if end > 1 && i != end {
time.Sleep(3 * time.Second) //防止hunter提示访问过快获取不到结果
}
}
fmt.Println("+++hunter数据已取+++")
}
Expand Down
Loading

0 comments on commit 74ef5ab

Please sign in to comment.