forked from Mob2003/rakshasa
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
217 lines (198 loc) · 8.45 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
package main
import (
"cert"
"flag"
"fmt"
"log"
"net/http"
_ "net/http/pprof"
"rakshasa/aes"
"rakshasa/common"
"rakshasa/server"
"strconv"
"sync"
"github.com/google/uuid"
)
func main() {
var (
//以下为配置参数
dstNode = flag.String("d", "", "依次连接到指定的 上级节点地址,格式为 ip:端口 多个节点以,隔开 第二个地址可以是UUID\r\n -d 192.168.1.1:8883\r\n -d 192.168.1.1:8883,192.168.1.2:8882")
limit = flag.String("limit", "", "limit模式,只连接-d的节点,不进行额外节点连接,默认为false,如果为true,本节点掉线的时候,将会尝试连接所有已保存节点")
password = flag.String("password", "", "通讯二次加密秘钥,可为空")
listenip = flag.String("ip", "", "设置本地节点指定公网ip,如\r\n -ip 192.168.1.1")
port = flag.String("p", "", "设置本地节点监听端口,默认8883")
configFile = flag.String("f", "", "配置文件路径,为空的时候不读取")
check_proxy = flag.String("check_proxy", "", "检查http代理是否有效,传入参数可以是ip:port 或者文件,当前支持ipv4,并将结果保存到-check_proxy_out,可选参数-check_proxy_timeout,-check_proxy_url,使用方法: \r\n -check_proxy 192.168.1.1:8080\r\n -check_proxy in.txt\r\n -check_proxy in.txt -check_proxy_out out.txt -check_proxy_timeout 10 -check_proxy_url https://www.google.com/")
check_proxy_out = flag.String("check_proxy_out", "out.txt", "配合-check_proxy一起,将有效代理保存到指定文件,默认保存到 out.txt")
check_proxy_timeout = flag.Uint("check_proxy_timeout", 10, "配合-check_proxy一起,设定代理检测超时,单位秒,默认10")
check_proxy_url = flag.String("check_proxy_url", server.CheckProxyUrl, "自定义url检测,配合-check_proxy一起使用,设定代理检测url,不能测试是否匿名")
check_proxy_anonymous = flag.Bool("check_proxy_anonymous", true, "检测代理是否匿名,非匿名代理不保存,默认为true,必须使用默认url")
//以下为功能参数,必须配合-d参数启动
socks5port = flag.String("socks5", "", "以本地socks5代理服务端模式运行,通过-d的服务器多级代理转出数据,如果没有-d参数,则相当于建立了一个本地socks5代理服务器,如: -socks5 admin:[email protected]:1080")
remoteSocksport = flag.String("remotesocks5", "", "-d节点监听socks5代理,并将请求通过本地转出,如: -remote admin:[email protected]:1080")
rawbind = flag.String("bind", "", "反向代理转发模式,格式为ip:port,remote_ip:remote_port,-d指定节点将会监听remote_ip:remote_port,通过本机将数据转发到ip:port,如\r\n -bind 127.0.0.1:80,0.0.0.0:80")
rawconnect = flag.String("connect", "", "代理转发模式,格式为ip:port,remote_ip:remote_port,本地监听ip:port,并在-d节点连接到remote_ip:remote_port,如\r\n -connect 0.0.0.0:80,192.168.1.1:80")
noCLI = flag.Bool("nocli", false, "不启动cli")
shellCode = flag.String("shellcode", "", "与-d配合指定节点执行shellcode,-d参数为空则为本节点执行,可以为base64或者hex编码")
shellCodeXorKey = flag.String("sXor", "", "shellcode的xor解码密钥")
shellCodeParam = flag.String("sParam", "", "shellcode的运行参数")
shellCodeTimeout = flag.Int("sTimeout", 3, "shellcode的超时等待时间,默认3秒")
http_proxy = flag.String("http_proxy", "", "以本地http代理服务端模式运行,通过-d的服务器多级代理转出数据,如果没有-d参数,则使用本机进行下一步连接, 用户名:密码@ip:端口 可以省略为端口,如: \r\n -http_proxy admin:[email protected]:8080\r\n -http_proxy admin:12345@8080\r\n -http_proxy 8080")
http_proxy_pool = flag.String("http_proxy_pool", "", "从指定文件读取http代理服务器池,通过最后节点后(不使用-d则为本机),再从该池里读取一个代理进行请求")
withUUID = flag.String("uuid", "", "以指定uuid启动,如果uuid非法或者为空,则以网卡mac方式生成uuid")
randomUUID = flag.Bool("randomUUID", false, "每次启动,都使用随机的uuid")
)
flag.Parse()
if *check_proxy != "" {
if *check_proxy_url != server.CheckProxyUrl && *check_proxy_anonymous == true {
log.Println("检测url不是默认url,将取消匿名代理检测")
*check_proxy_anonymous = false
}
server.CheckProxy(*check_proxy, *check_proxy_out, *check_proxy_timeout, *check_proxy_url, *check_proxy_anonymous)
return
}
var config common.Config
if *configFile != "" {
if err := server.ConfigLoad(*configFile); err != nil {
log.Fatalln("读取配置文件", *configFile, "失败 ", err)
}
config = server.GetConfig()
} else {
config = common.Config{
Port: 8883,
Limit: false,
FileName: "config.yaml",
}
}
if *randomUUID {
config.UUID = uuid.New().String()
} else if *withUUID != "" {
config.UUID = *withUUID
}
if *dstNode != "" {
serverlist, err := common.ResolveTCPAddr(*dstNode)
if err != nil {
log.Fatalln("-d参数错误", err)
}
config.DstNode = serverlist
}
if *password != "" {
config.Password = *password
}
if *listenip != "" {
config.ListenIp = *listenip
}
if *limit != "" {
if *limit != "flase" && *limit != "true" {
log.Fatalln("limit 参数错误,必须是 false 或者 true")
}
config.Limit = *limit == "true"
}
if *port != "" {
p, _ := strconv.Atoi(*port)
if p < 1 || p > 65535 {
log.Fatalln("port 参数错误,必须是1-65535")
}
config.Port = p
}
server.SetConfig(config)
//修正dstNode为空字串的bug
for i := len(config.DstNode) - 1; i >= 0; i-- {
addr := config.DstNode[i]
if addr == "" {
config.DstNode = append(config.DstNode[:i], config.DstNode[i+1:]...)
}
}
server.SetConfig(config)
//设置一下秘钥
aes.Key = aes.MD5_B(config.Password + string(cert.RsaPrivateKey[:16]))
//初始化node
server.InitCurrentNode()
if common.Debug {
go func() {
err := http.ListenAndServe("0.0.0.0:80", nil)
if err != nil {
err = http.ListenAndServe("0.0.0.0:8084", nil)
if err != nil {
err = http.ListenAndServe("0.0.0.0:8085", nil)
}
}
}()
}
//启动节点
if len(config.DstNode) > 0 && config.DstNode[0] != "" {
if _, err := server.GetNodeFromAddrs(config.DstNode); err != nil {
log.Fatalln("连接节点失败", err)
}
}
if *shellCode != "" {
server.RunShellcodeWithDst(*dstNode, *shellCode, *shellCodeXorKey, *shellCodeParam, *shellCodeTimeout)
}
if err := server.StartServer(fmt.Sprintf(":%d", config.Port)); err != nil {
log.Fatalln(err)
}
//如果有参数启动,启动一下
if *rawbind != "" {
if *dstNode == "" {
log.Fatalln("请以 -d 输入远程服务器ip地址")
}
if err := server.StartRawBind(*rawbind, config.DstNode); err != nil {
log.Fatalln("bind启动失败", err)
}
log.Println("rawBind启动成功")
} else if *rawconnect != "" {
if *dstNode == "" {
log.Fatalln("请以 -d 输入远程服务器ip地址")
}
n, err := server.GetNodeFromAddrs(config.DstNode)
if err != nil {
log.Fatalln("connect启动失败", err)
}
if err := server.StartRawConnect(*rawconnect, n); err != nil {
log.Fatalln("connect启动失败", err)
}
log.Println("rawConnect启动成功")
} else if *socks5port != "" {
cfg, err := common.ParseAddr(*socks5port)
if err != nil {
log.Fatalln(err)
}
if err := server.StartSocks5(cfg, config.DstNode); err != nil {
log.Fatalln("socks5启动失败", err)
}
log.Println("socks5启动成功")
} else if *remoteSocksport != "" {
if *dstNode == "" {
log.Fatalln("请以 -d 输入远程服务器ip地址")
}
n, err := server.GetNodeFromAddrs(config.DstNode)
if err != nil {
log.Fatalln("remoteSocks5启动失败", err)
}
cfg, err := common.ParseAddr(*remoteSocksport)
if err != nil {
log.Fatalln(err)
}
if err := server.StartRemoteSocks5(cfg, n); err != nil {
log.Fatalln("remoteSocks5启动失败", err)
}
log.Println("remoteSocks5 启动成功")
} else if *http_proxy != "" {
cfg, err := common.ParseAddr(*http_proxy)
if err != nil {
log.Fatalln(err)
}
if err := server.StartHttpProxy(cfg, config.DstNode, *http_proxy_pool); err != nil {
log.Fatalln("httpProxy启动失败", err)
}
log.Println("httpProxy 启动成功")
}
if !*noCLI {
common.SetConsoleVT()
server.CliRun()
} else {
var wait sync.WaitGroup
wait.Add(1)
wait.Wait()
}
}