Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: ensure that host:port joining is done correct for IPv6 addresses #526

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ linters:
# - nlreturn
# - noctx
- nolintlint
# - nosprintfhostport
- nosprintfhostport
# - perfsprint
# - prealloc
- predeclared
Expand Down
16 changes: 10 additions & 6 deletions detector/cve/cve202011978/cve202011978.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ import (
"fmt"
"io/fs"
"math/rand"
"net"
"net/http"
"os"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -226,7 +228,7 @@ func (d Detector) Scan(ctx context.Context, scanRoot *scalibrfs.ScanRoot, ix *in

// CheckAccessibility checks if the airflow server is accessible.
func CheckAccessibility(airflowIP string, airflowServerPort int) bool {
target := fmt.Sprintf("http://%s:%d/api/experimental/test", airflowIP, airflowServerPort)
target := fmt.Sprintf("http://%s/api/experimental/test", net.JoinHostPort(airflowIP, strconv.Itoa(airflowServerPort)))

client := &http.Client{Timeout: defaultTimeout}
resp, err := client.Get(target)
Expand All @@ -240,7 +242,7 @@ func CheckAccessibility(airflowIP string, airflowServerPort int) bool {

// CheckForBashTask checks if the airflow server has a bash task.
func CheckForBashTask(airflowIP string, airflowServerPort int) bool {
target := fmt.Sprintf("http://%s:%d/api/experimental/dags/example_trigger_target_dag/tasks/bash_task", airflowIP, airflowServerPort)
target := fmt.Sprintf("http://%s/api/experimental/dags/example_trigger_target_dag/tasks/bash_task", net.JoinHostPort(airflowIP, strconv.Itoa(airflowServerPort)))

client := &http.Client{Timeout: defaultTimeout}
resp, err := client.Get(target)
Expand Down Expand Up @@ -281,7 +283,7 @@ func CheckForBashTask(airflowIP string, airflowServerPort int) bool {

// CheckForPause checks if the airflow server has a paused dag.
func CheckForPause(airflowIP string, airflowServerPort int) bool {
target := fmt.Sprintf("http://%s:%d/api/experimental/dags/example_trigger_target_dag/paused/false", airflowIP, airflowServerPort)
target := fmt.Sprintf("http://%s/api/experimental/dags/example_trigger_target_dag/paused/false", net.JoinHostPort(airflowIP, strconv.Itoa(airflowServerPort)))

client := &http.Client{Timeout: defaultTimeout}
resp, err := client.Get(target)
Expand All @@ -295,7 +297,7 @@ func CheckForPause(airflowIP string, airflowServerPort int) bool {

// triggerAndWaitForDAG achieves command execution via DAG scheduling using the example bash task from above.
func triggerAndWaitForDAG(ctx context.Context, airflowIP string, airflowServerPort int) bool {
dagURL := fmt.Sprintf("http://%s:%d/api/experimental/dags/example_trigger_target_dag/dag_runs", airflowIP, airflowServerPort)
dagURL := fmt.Sprintf("http://%s/api/experimental/dags/example_trigger_target_dag/dag_runs", net.JoinHostPort(airflowIP, strconv.Itoa(airflowServerPort)))
payload := map[string]any{
"conf": map[string]string{
"message": fmt.Sprintf(`"; id > %s #`, randFilePath),
Expand Down Expand Up @@ -349,8 +351,10 @@ func triggerAndWaitForDAG(ctx context.Context, airflowIP string, airflowServerPo
return false
}

waitURL := fmt.Sprintf("http://%s:%d/api/experimental/dags/example_trigger_target_dag/dag_runs/%s/tasks/bash_task",
airflowIP, airflowServerPort, resBody["execution_date"])
waitURL := fmt.Sprintf(
"http://%s/api/experimental/dags/example_trigger_target_dag/dag_runs/%s/tasks/bash_task",
net.JoinHostPort(airflowIP, strconv.Itoa(airflowServerPort)), resBody["execution_date"],
)

log.Infof("Waiting for the scheduler to run the DAG... This might take a minute.")
log.Infof("If the bash task is never queued, then the scheduler might not be running.")
Expand Down
6 changes: 4 additions & 2 deletions detector/cve/cve202016846/cve202016846.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ import (
"fmt"
"io/fs"
"math/rand"
"net"
"net/http"
"os"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -192,7 +194,7 @@ func (d Detector) Scan(ctx context.Context, scanRoot *scalibrfs.ScanRoot, ix *in

// CheckForCherrypy checks for the presence of Cherrypy in the server headers.
func CheckForCherrypy(saltIP string, saltServerPort int) bool {
target := fmt.Sprintf("http://%s:%d", saltIP, saltServerPort)
target := fmt.Sprintf("http://%s", net.JoinHostPort(saltIP, strconv.Itoa(saltServerPort)))

client := &http.Client{Timeout: defaultTimeout}
resp, err := client.Get(target)
Expand All @@ -208,7 +210,7 @@ func CheckForCherrypy(saltIP string, saltServerPort int) bool {

// ExploitSalt attempts to exploit the Salt server if vulnerable.
func ExploitSalt(ctx context.Context, saltIP string, saltServerPort int) bool {
target := fmt.Sprintf("http://%s:%d/run", saltIP, saltServerPort)
target := fmt.Sprintf("http://%s/run", net.JoinHostPort(saltIP, strconv.Itoa(saltServerPort)))
data := map[string]any{
"client": "ssh",
"tgt": "*",
Expand Down
4 changes: 3 additions & 1 deletion detector/cve/cve202233891/cve202233891.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ import (
"fmt"
"io/fs"
"math/rand"
"net"
"net/http"
"os"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -165,7 +167,7 @@ func (d Detector) Scan(ctx context.Context, scanRoot *scalibrfs.ScanRoot, ix *in
func sparkUIHTTPQuery(ctx context.Context, sparkDomain string, sparkPort int, cmdExec string) int {
client := &http.Client{Timeout: defaultTimeout}

targetURL := fmt.Sprintf("http://%s:%d/?doAs=`%s`", sparkDomain, sparkPort, cmdExec)
targetURL := fmt.Sprintf("http://%s/?doAs=`%s`", net.JoinHostPort(sparkDomain, strconv.Itoa(sparkPort)), cmdExec)
req, _ := http.NewRequestWithContext(ctx, "GET", targetURL, nil)
req.Header.Add("Accept", "*/*")
resp, err := client.Do(req)
Expand Down
3 changes: 2 additions & 1 deletion detector/cve/cve20236019/cve20236019.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"fmt"
"io/fs"
"math/rand"
"net"
"net/http"
"os"
"strconv"
Expand Down Expand Up @@ -196,7 +197,7 @@ func attemptExploit(ctx context.Context) string {

// rayRequest sends an HTTP GET request to the Ray Dashboard and executes the provided command
func rayRequest(ctx context.Context, host string, port int, cmd string) int {
url := fmt.Sprintf("http://%s:%d/worker/cpu_profile?pid=3354&ip=127.0.0.1&duration=5&native=0&format=%s", host, port, cmd)
url := fmt.Sprintf("http://%s/worker/cpu_profile?pid=3354&ip=127.0.0.1&duration=5&native=0&format=%s", net.JoinHostPort(host, strconv.Itoa(port)), cmd)

// Create a new HTTP request
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
Expand Down
6 changes: 4 additions & 2 deletions detector/cve/cve20242912/cve20242912.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ import (
"encoding/base64"
"fmt"
"io/fs"
"net"
"net/http"
"os"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -106,7 +108,7 @@ func findBentomlVersions(ix *inventoryindex.InventoryIndex) (string, *extractor.

// CheckAccessibility checks if the BentoML server is reachable
func CheckAccessibility(ctx context.Context, ip string, port int) bool {
target := fmt.Sprintf("http://%s:%d/summarize", ip, port)
target := fmt.Sprintf("http://%s/summarize", net.JoinHostPort(ip, strconv.Itoa(port)))

req, err := http.NewRequestWithContext(ctx, "GET", target, nil)
if err != nil {
Expand All @@ -126,7 +128,7 @@ func CheckAccessibility(ctx context.Context, ip string, port int) bool {

// ExploitBentoml sends payload to the BentoML service
func ExploitBentoml(ctx context.Context, ip string, port int) bool {
target := fmt.Sprintf("http://%s:%d/summarize", ip, port)
target := fmt.Sprintf("http://%s/summarize", net.JoinHostPort(ip, strconv.Itoa(port)))

payload, err := base64.StdEncoding.DecodeString(string(pickledPayload))
if err != nil {
Expand Down
6 changes: 4 additions & 2 deletions detector/weakcredentials/filebrowser/filebrowser.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ import (
"errors"
"fmt"
"io"
"net"
"net/http"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -125,7 +127,7 @@ func isVulnerable(ctx context.Context, fileBrowserIP string, fileBrowserPort int
// checkAccessibility checks if the filebrowser instance is accessible given an IP and port.
func checkAccessibility(ctx context.Context, fileBrowserIP string, fileBrowserPort int) bool {
client := &http.Client{Timeout: requestTimeout}
targetURL := fmt.Sprintf("http://%s:%d/", fileBrowserIP, fileBrowserPort)
targetURL := fmt.Sprintf("http://%s/", net.JoinHostPort(fileBrowserIP, strconv.Itoa(fileBrowserPort)))

req, err := http.NewRequestWithContext(ctx, "GET", targetURL, nil)
if err != nil {
Expand Down Expand Up @@ -172,7 +174,7 @@ func checkAccessibility(ctx context.Context, fileBrowserIP string, fileBrowserPo
// checkLogin checks if the login with default credentials is successful.
func checkLogin(ctx context.Context, fileBrowserIP string, fileBrowserPort int) bool {
client := &http.Client{Timeout: requestTimeout}
targetURL := fmt.Sprintf("http://%s:%d/api/login", fileBrowserIP, fileBrowserPort)
targetURL := fmt.Sprintf("http://%s/api/login", net.JoinHostPort(fileBrowserIP, strconv.Itoa(fileBrowserPort)))

requestBody, _ := json.Marshal(map[string]string{
"username": "admin",
Expand Down