-
-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #16 from firefart/dev
Dev
- Loading branch information
Showing
11 changed files
with
192 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
stunner | ||
*.sh | ||
*.txt | ||
*.tar.gz | ||
release/ | ||
dist/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
FROM golang:latest AS build-env | ||
WORKDIR /src | ||
ENV CGO_ENABLED=0 | ||
COPY go.mod /src/ | ||
RUN go mod download | ||
COPY . . | ||
RUN go build -a -o stunner -ldflags="-s -w" -gcflags="all=-trimpath=/src" -asmflags="all=-trimpath=/src" | ||
|
||
FROM alpine:latest | ||
|
||
RUN apk add --no-cache ca-certificates \ | ||
&& rm -rf /var/cache/* | ||
|
||
RUN mkdir -p /app \ | ||
&& adduser -D stunner \ | ||
&& chown -R stunner:stunner /app | ||
|
||
USER stunner | ||
WORKDIR /app | ||
|
||
COPY --from=build-env /src/stunner . | ||
|
||
ENTRYPOINT [ "./stunner" ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package cmd | ||
|
||
import ( | ||
"bufio" | ||
"fmt" | ||
"os" | ||
"strings" | ||
"time" | ||
|
||
"github.com/firefart/stunner/internal" | ||
"github.com/sirupsen/logrus" | ||
) | ||
|
||
type BruteforceOpts struct { | ||
TurnServer string | ||
Protocol string | ||
Username string | ||
Passfile string | ||
UseTLS bool | ||
Timeout time.Duration | ||
Log *logrus.Logger | ||
} | ||
|
||
func (opts BruteforceOpts) Validate() error { | ||
if opts.TurnServer == "" { | ||
return fmt.Errorf("need a valid turnserver") | ||
} | ||
if !strings.Contains(opts.TurnServer, ":") { | ||
return fmt.Errorf("turnserver needs a port") | ||
} | ||
if opts.Protocol != "tcp" && opts.Protocol != "udp" { | ||
return fmt.Errorf("protocol needs to be either tcp or udp") | ||
} | ||
if opts.Username == "" { | ||
return fmt.Errorf("please supply a username") | ||
} | ||
if opts.Passfile == "" { | ||
return fmt.Errorf("please supply a password file") | ||
} | ||
if opts.Log == nil { | ||
return fmt.Errorf("please supply a valid logger") | ||
} | ||
return nil | ||
} | ||
|
||
func BruteForce(opts BruteforceOpts) error { | ||
if err := opts.Validate(); err != nil { | ||
return err | ||
} | ||
|
||
pfile, err := os.Open(opts.Passfile) | ||
if err != nil { | ||
return fmt.Errorf("could not read password file: %w", err) | ||
} | ||
defer pfile.Close() | ||
|
||
scanner := bufio.NewScanner(pfile) | ||
for scanner.Scan() { | ||
if err := testPassword(opts, scanner.Text()); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
if err := scanner.Err(); err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func testPassword(opts BruteforceOpts, password string) error { | ||
remote, err := internal.Connect(opts.Protocol, opts.TurnServer, opts.UseTLS, opts.Timeout) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
addressFamily := internal.AllocateProtocolIgnore | ||
allocateRequest := internal.AllocateRequest(internal.RequestedTransportUDP, addressFamily) | ||
allocateResponse, err := allocateRequest.SendAndReceive(opts.Log, remote, opts.Timeout) | ||
if err != nil { | ||
return fmt.Errorf("error on sending AllocateRequest: %w", err) | ||
} | ||
if allocateResponse.Header.MessageType.Class != internal.MsgTypeClassError { | ||
return fmt.Errorf("MessageClass is not Error (should be not authenticated)") | ||
} | ||
|
||
realm := string(allocateResponse.GetAttribute(internal.AttrRealm).Value) | ||
nonce := string(allocateResponse.GetAttribute(internal.AttrNonce).Value) | ||
|
||
allocateRequest = internal.AllocateRequestAuth(opts.Username, password, nonce, realm, internal.RequestedTransportUDP, addressFamily) | ||
allocateResponse, err = allocateRequest.SendAndReceive(opts.Log, remote, opts.Timeout) | ||
if err != nil { | ||
return fmt.Errorf("error on sending AllocateRequest Auth: %w", err) | ||
} | ||
if allocateResponse.Header.MessageType.Class == internal.MsgTypeClassSuccess { | ||
opts.Log.Infof("Found valid credentials: %s:%s", opts.Username, password) | ||
return nil | ||
} | ||
// we got an error | ||
errorCode := allocateResponse.GetAttribute(internal.AttrErrorCode).Value[4:] | ||
if string(errorCode) != "Unauthorized" { | ||
// get all other errors than auth errors | ||
opts.Log.Errorf("Unknown error: %s", string(errorCode)) | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters