Skip to content

Commit 5fcdd1d

Browse files
Merge branch 'main' into dotnetdeserialization-2
2 parents 20c5071 + f4c82f1 commit 5fcdd1d

File tree

13 files changed

+1689
-0
lines changed

13 files changed

+1689
-0
lines changed

.golangci.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,11 @@ linters:
101101
- staticcheck
102102
path: cli/commandline_test.go
103103
text: SA1019
104+
- linters:
105+
- gocognit
106+
- gocyclo
107+
- cyclop
108+
path: protocol/sip/helper_test.go
104109
paths:
105110
- protocol/mikrotik/msg.go
106111
- third_party$

go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.24.1
55
require (
66
github.com/Masterminds/semver v1.5.0
77
github.com/antchfx/htmlquery v1.3.4
8+
github.com/emiago/sipgo v0.33.0
89
github.com/lor00x/goldap v0.0.0-20240304151906-8d785c64d1c8
910
github.com/vjeantet/ldapserver v1.0.2-0.20240305064909-a417792e2906
1011
golang.org/x/crypto v0.40.0
@@ -16,8 +17,12 @@ require (
1617
require (
1718
github.com/antchfx/xpath v1.3.3 // indirect
1819
github.com/dustin/go-humanize v1.0.1 // indirect
20+
github.com/gobwas/httphead v0.1.0 // indirect
21+
github.com/gobwas/pool v0.2.1 // indirect
22+
github.com/gobwas/ws v1.3.2 // indirect
1923
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
2024
github.com/google/uuid v1.6.0 // indirect
25+
github.com/icholy/digest v1.1.0 // indirect
2126
github.com/mattn/go-isatty v0.0.20 // indirect
2227
github.com/ncruces/go-strftime v0.1.9 // indirect
2328
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect

go.sum

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,41 @@ github.com/antchfx/htmlquery v1.3.4 h1:Isd0srPkni2iNTWCwVj/72t7uCphFeor5Q8nCzj1j
44
github.com/antchfx/htmlquery v1.3.4/go.mod h1:K9os0BwIEmLAvTqaNSua8tXLWRWZpocZIH73OzWQbwM=
55
github.com/antchfx/xpath v1.3.3 h1:tmuPQa1Uye0Ym1Zn65vxPgfltWb/Lxu2jeqIGteJSRs=
66
github.com/antchfx/xpath v1.3.3/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
7+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
8+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
79
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
810
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
11+
github.com/emiago/sipgo v0.33.0 h1:UxPKCoPREffSjrRE6oesG/RPz5/ZSp8tA8Jc6YvYUsk=
12+
github.com/emiago/sipgo v0.33.0/go.mod h1:gbOLw/kZHZ3wS/5PIa9qVjpdil/IKLdigbZFIYFpHTs=
13+
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
14+
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
15+
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
16+
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
17+
github.com/gobwas/ws v1.3.2 h1:zlnbNHxumkRvfPWgfXu8RBwyNR1x8wh9cf5PTOCqs9Q=
18+
github.com/gobwas/ws v1.3.2/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=
919
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
1020
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
21+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
1122
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
1223
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
1324
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
1425
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
1526
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
27+
github.com/icholy/digest v1.1.0 h1:HfGg9Irj7i+IX1o1QAmPfIBNu/Q5A5Tu3n/MED9k9H4=
28+
github.com/icholy/digest v1.1.0/go.mod h1:QNrsSGQ5v7v9cReDI0+eyjsXGUoRSUZQHeQ5C4XLa0Y=
1629
github.com/lor00x/goldap v0.0.0-20180618054307-a546dffdd1a3/go.mod h1:37YR9jabpiIxsb8X9VCIx8qFOjTDIIrIHHODa8C4gz0=
1730
github.com/lor00x/goldap v0.0.0-20240304151906-8d785c64d1c8 h1:z9RDOBcFcf3f2hSfKuoM3/FmJpt8M+w0fOy4wKneBmc=
1831
github.com/lor00x/goldap v0.0.0-20240304151906-8d785c64d1c8/go.mod h1:37YR9jabpiIxsb8X9VCIx8qFOjTDIIrIHHODa8C4gz0=
1932
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
2033
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
2134
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
2235
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
36+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
37+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
2338
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
2439
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
40+
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
41+
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
2542
github.com/vjeantet/ldapserver v1.0.2-0.20240305064909-a417792e2906 h1:qHFp1iRg6qE8xYel3bQT9x70pyxsdPLbJnM40HG3Oig=
2643
github.com/vjeantet/ldapserver v1.0.2-0.20240305064909-a417792e2906/go.mod h1:YvUqhu5vYhmbcLReMLrm/Tq3S7Yj43kSVFvvol6Lh6k=
2744
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
@@ -105,6 +122,10 @@ golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxb
105122
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
106123
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
107124
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
125+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
126+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
127+
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
128+
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
108129
modernc.org/cc/v4 v4.26.1 h1:+X5NtzVBn0KgsBCBe+xkDC7twLb/jNVj9FPgiwSQO3s=
109130
modernc.org/cc/v4 v4.26.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
110131
modernc.org/ccgo/v4 v4.28.0 h1:rjznn6WWehKq7dG4JtLRKxb52Ecv8OUGah8+Z/SfpNU=

protocol/sip/examples/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# SIP examples
2+
3+
## Usage
4+
5+
Start the local Asterisk server and run a example.
6+
7+
```sh
8+
cd protocol/sip/examples
9+
docker compose up -d
10+
go run ping/main.go
11+
# go run tcp/main.go
12+
# go run call/main.go
13+
```

protocol/sip/examples/call/main.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// This example registers an endpoint (user authentication) in a server
2+
// and starts a call (only the SIP related part).
3+
package main
4+
5+
import (
6+
sipgo "github.com/emiago/sipgo/sip"
7+
"github.com/icholy/digest"
8+
"github.com/vulncheck-oss/go-exploit/output"
9+
"github.com/vulncheck-oss/go-exploit/protocol"
10+
"github.com/vulncheck-oss/go-exploit/protocol/sip"
11+
)
12+
13+
const (
14+
host = "127.0.0.1"
15+
fromUser = "john.doe"
16+
pass = "password"
17+
toUser = "dembele"
18+
)
19+
20+
func main() {
21+
port := sip.DefaultPorts[sip.UDP]
22+
conn, ok := protocol.UDPConnect(host, port)
23+
if !ok {
24+
output.PrintfFrameworkError("Connecting to server %s:%d", host, port)
25+
26+
return
27+
}
28+
defer conn.Close()
29+
reqOpts := sip.NewSipRequestOpts{
30+
Port: port,
31+
User: fromUser,
32+
ToUser: fromUser,
33+
}
34+
req, ok := sip.NewSipRequest(sipgo.REGISTER, host, &reqOpts)
35+
if !ok {
36+
output.PrintfFrameworkError("Creating REGISTER request to %s with options %+v", host, reqOpts)
37+
38+
return
39+
}
40+
resp, ok := sip.SendAndReceiveUDP(conn, req)
41+
if !ok {
42+
output.PrintfFrameworkError("Sending REGISTER request %s", req.String())
43+
44+
return
45+
}
46+
if resp.StatusCode != sipgo.StatusUnauthorized {
47+
output.PrintfFrameworkError("Unexpected response %d (%s) to REGISTER request", resp.StatusCode, resp.Reason)
48+
49+
return
50+
}
51+
wwwAuth := resp.GetHeader("WWW-Authenticate")
52+
chal, err := digest.ParseChallenge(wwwAuth.Value())
53+
if err != nil {
54+
output.PrintfFrameworkError("Parsing WWW-Authenticate header: %s", err)
55+
56+
return
57+
}
58+
cred, _ := digest.Digest(chal, digest.Options{
59+
Method: req.Method.String(),
60+
URI: host,
61+
Username: fromUser,
62+
Password: pass,
63+
})
64+
newReq := req.Clone()
65+
authHeader := sipgo.NewHeader("Authorization", cred.String())
66+
newReq.AppendHeader(authHeader)
67+
cseqHeader := sipgo.CSeqHeader{SeqNo: uint32(2), MethodName: sipgo.REGISTER}
68+
newReq.ReplaceHeader(&cseqHeader)
69+
resp, ok = sip.SendAndReceiveUDP(conn, newReq)
70+
if !ok {
71+
output.PrintfFrameworkError("Sending REGISTER request with Authorization header %s", newReq.String())
72+
73+
return
74+
}
75+
if resp.StatusCode != sipgo.StatusOK {
76+
output.PrintfFrameworkError("Unexpected response %d (%s) to REGISTER request with Authorization header", resp.StatusCode, resp.Reason)
77+
78+
return
79+
}
80+
reqOpts = sip.NewSipRequestOpts{
81+
Port: port,
82+
ToUser: toUser,
83+
User: fromUser,
84+
}
85+
req, ok = sip.NewSipRequest(sipgo.INVITE, host, &reqOpts)
86+
if !ok {
87+
output.PrintfFrameworkError("Creating INVITE request to %s with options %+v", host, reqOpts)
88+
89+
return
90+
}
91+
cred, _ = digest.Digest(chal, digest.Options{
92+
Method: sipgo.INVITE.String(),
93+
URI: host,
94+
Username: fromUser,
95+
Password: pass,
96+
})
97+
authHeader = sipgo.NewHeader("Authorization", cred.String())
98+
req.AppendHeader(authHeader)
99+
resp, ok = sip.SendAndReceiveUDP(conn, req)
100+
if !ok {
101+
output.PrintfFrameworkError("Sending INVITE request %s", req.String())
102+
103+
return
104+
}
105+
// Not found is expected here, as we are not actually calling a real user.
106+
if resp.StatusCode == sipgo.StatusNotFound {
107+
output.PrintfFrameworkSuccess("Response (INVITE): %s", resp.String())
108+
} else {
109+
output.PrintfFrameworkError("Unexpected response (INVITE): %s", resp.String())
110+
}
111+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: go-exploit-examples
2+
3+
services:
4+
asterisk:
5+
image: mlan/asterisk
6+
network_mode: bridge # For testing
7+
cap_add:
8+
- sys_ptrace # For testing
9+
ports:
10+
- "5060:5060/udp" # SIP UDP
11+
- "5060:5060" # SIP TCP
12+
- "5061:5061" # SIP TLS
13+
- "10000-10099:10000-10099/udp" # RTP
14+
environment:
15+
- HOSTNAME=asterisk.${DOMAIN-docker.localhost}

protocol/sip/examples/ping/main.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// This example checks if a UDP server is up.
2+
//
3+
// The OPTION method is used to discover the server capabilities:
4+
// - https://datatracker.ietf.org/doc/html/rfc3261#section-11
5+
package main
6+
7+
import (
8+
sipgo "github.com/emiago/sipgo/sip"
9+
"github.com/vulncheck-oss/go-exploit/output"
10+
"github.com/vulncheck-oss/go-exploit/protocol"
11+
"github.com/vulncheck-oss/go-exploit/protocol/sip"
12+
)
13+
14+
const (
15+
host = "127.0.0.1"
16+
// Most of the times the servers answer without them.
17+
fromUser = "bob"
18+
toUser = "alice"
19+
)
20+
21+
func main() {
22+
port := sip.DefaultPorts[sip.UDP]
23+
conn, ok := protocol.UDPConnect(host, port)
24+
if !ok {
25+
output.PrintfFrameworkError("Connecting to server %s:%d", host, port)
26+
27+
return
28+
}
29+
defer conn.Close()
30+
reqOpts := sip.NewSipRequestOpts{
31+
Port: port,
32+
ToUser: toUser,
33+
User: fromUser,
34+
}
35+
req, ok := sip.NewSipRequest(sipgo.OPTIONS, host, &reqOpts)
36+
if !ok {
37+
output.PrintfFrameworkError("Creating request to %s with options %+v", host, reqOpts)
38+
39+
return
40+
}
41+
resp, ok := sip.SendAndReceiveUDP(conn, req)
42+
if ok {
43+
output.PrintfFrameworkSuccess("Server is up, response: %s", resp.String())
44+
} else {
45+
output.PrintfFrameworkError("Sending request %s", req.String())
46+
}
47+
}

protocol/sip/examples/tcp/main.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// This example sends an OPTIONS request over TCP (or TLS).
2+
package main
3+
4+
import (
5+
sipgo "github.com/emiago/sipgo/sip"
6+
"github.com/vulncheck-oss/go-exploit/output"
7+
"github.com/vulncheck-oss/go-exploit/protocol"
8+
"github.com/vulncheck-oss/go-exploit/protocol/sip"
9+
)
10+
11+
const (
12+
host = "127.0.0.1"
13+
useTLS = true
14+
)
15+
16+
func main() {
17+
transport := sip.TCP
18+
if useTLS {
19+
transport = sip.TLS
20+
}
21+
port := sip.DefaultPorts[transport]
22+
conn, ok := protocol.MixedConnect(host, port, useTLS)
23+
if !ok {
24+
output.PrintfFrameworkError("Connecting to server %s:%d", host, port)
25+
26+
return
27+
}
28+
defer conn.Close()
29+
reqOpts := sip.NewSipRequestOpts{
30+
Port: port,
31+
Transport: transport,
32+
}
33+
req, ok := sip.NewSipRequest(sipgo.OPTIONS, host, &reqOpts)
34+
if !ok {
35+
output.PrintfFrameworkError("Creating request to %s with options %+v", host, reqOpts)
36+
37+
return
38+
}
39+
resp, ok := sip.SendAndReceiveTCP(conn, req)
40+
if ok {
41+
output.PrintfFrameworkSuccess("Response: %s", resp.String())
42+
} else {
43+
output.PrintfFrameworkError("Sending request %s", req.String())
44+
}
45+
}

0 commit comments

Comments
 (0)