-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcupscheck.go
130 lines (111 loc) · 3.23 KB
/
cupscheck.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
package main
/*
cups_browsed CVE-2024-47176 vulnerability checker.
Based off the writeup from Simone Margaritelli
on the vulnerability he identified.
His blog is here: https://www.evilsocket.net/2024/09/26/Attacking-UNIX-systems-via-CUPS-Part-I/
*/
import (
"flag"
"fmt"
"log"
"net"
"net/http"
"os"
"os/user"
"strings"
"time"
)
var vulnerableMachines []string
func startHTTPListener() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
log.Printf("Received connection from %s\n", r.RemoteAddr)
// Log headers
for key, value := range r.Header {
log.Printf("%s Header: %s -> %s\n", r.RemoteAddr, key, strings.Join(value, ", "))
}
vulnerableMachines = append(vulnerableMachines, r.RemoteAddr) // Add to vulnerable machines
})
log.Println("Starting HTTP listener on port 9180...")
if err := http.ListenAndServe(":9180", nil); err != nil {
log.Fatalf("Failed to start listener: %v", err)
}
}
func parseIPRange(cidr string) ([]net.IP, error) {
ip, ipnet, err := net.ParseCIDR(cidr)
if err != nil {
return nil, err
}
var ips []net.IP
for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); incIP(ip) {
ipCopy := make(net.IP, len(ip))
copy(ipCopy, ip)
ips = append(ips, ipCopy)
}
if len(ips) > 2 {
return ips[1 : len(ips)-1], nil
}
return ips, nil
}
func incIP(ip net.IP) {
for j := len(ip) - 1; j >= 0; j-- {
ip[j]++
if ip[j] > 0 {
break
}
}
}
func sendUDPPacket(ip net.IP, localIP string) {
conn, err := net.Dial("udp", fmt.Sprintf("%s:631", ip.String()))
if err != nil {
log.Printf("Error connecting to %s: %v\n", ip, err)
return
}
defer conn.Close()
msg := fmt.Sprintf("0 3 http://%s:9180/printer/", localIP)
if _, err := conn.Write([]byte(msg)); err != nil {
log.Printf("Error sending packet to %s: %v\n", ip, err)
}
log.Printf("Sent request packet to %s.\n", ip)
}
func checkIfRunningAsRoot() {
currentUser, err := user.Current()
if err != nil {
log.Fatalf("Failed to get current user: %v", err)
}
if currentUser.Uid != "0" {
fmt.Println("This program must be run as root/administrator.")
os.Exit(1)
}
}
func main() {
log.Println("Cups_Browsed Vulnerability Check Script - Nicholas Albright (@nma-io)")
log.Println("Based off of the great research by Simone Margaritelli.")
checkIfRunningAsRoot()
localIP := flag.String("l", "", "Local IP address to use in the packet")
targetRange := flag.String("t", "", "Target IP range in CIDR format (e.g., 192.168.1.0/24)")
flag.Parse()
if *localIP == "" || *targetRange == "" {
fmt.Printf("Usage: sudo %s <local IP> -t <target CIDR>\n", os.Args[0])
os.Exit(1)
}
go startHTTPListener()
ips, err := parseIPRange(*targetRange)
if err != nil {
log.Fatalf("Failed to parse IP range: %v", err)
}
for _, ip := range ips {
go sendUDPPacket(ip, *localIP) // No need to worry here - we can just blast each ip on the network. The CUPS server will ignore the packets if it's not vulnerable.
}
log.Println("Waiting 60 seconds for all hosts to respond...")
time.Sleep(60 * time.Second)
if len(vulnerableMachines) > 0 {
log.Println("Vulnerable machines detected:")
for _, machine := range vulnerableMachines {
log.Println(machine)
}
} else {
log.Println("No vulnerable machines detected.")
}
log.Println("Shutting down.")
}