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

Flag Handler Service #36

Open
wants to merge 1 commit into
base: develop
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 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ tmp/*
katana
test.go
vendor/*
*.log
*.log
5 changes: 5 additions & 0 deletions config.sample.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,8 @@ url = "mongodb://scar:scar@localhost:27017/?authSource=admin"
[admin]
username = "sdslabs"
password = "sdslabs"

[flag]
flaglength = 10
tickperiod = 300
submissionport = 4040
2 changes: 2 additions & 0 deletions configs/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,6 @@ var (
TeamVmConfig = KatanaConfig.TeamVmConfig

MongoConfig = KatanaConfig.Mongo

FlagConfig = KatanaConfig.FlagConfig
)
7 changes: 7 additions & 0 deletions configs/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ type MongoCfg struct {
URL string `toml:"url"`
}

type FlagCfg struct {
FlagLength int `toml:"flaglength"`
TickPeriod uint `toml:"tickperiod"`
SubmissionServicePort string `toml:"submissionport"`
}

type KatanaCfg struct {
KubeHost string `toml:"kubehost"`
KubeNameSpace string `toml:"kubenamespace"`
Expand All @@ -62,4 +68,5 @@ type KatanaCfg struct {
Mongo MongoCfg `toml:"mongo"`
TeamVmConfig TeamChallengeConfig `toml:"teamvm"`
AdminConfig AdminCfg `toml:"admin"`
FlagConfig FlagCfg `toml:"flag"`
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/gofiber/fiber/v2 v2.1.0
github.com/golang/protobuf v1.4.3
github.com/googleapis/gnostic v0.5.3 // indirect
github.com/jasonlvhit/gocron v0.0.1
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
github.com/sirupsen/logrus v1.6.0
github.com/spf13/cobra v1.0.0
Expand Down
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
github.com/go-redis/redis v6.15.5+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
Expand Down Expand Up @@ -201,6 +202,8 @@ github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jasonlvhit/gocron v0.0.1 h1:qTt5qF3b3srDjeOIR4Le1LfeyvoYzJlYpqvG7tJX5YU=
github.com/jasonlvhit/gocron v0.0.1/go.mod h1:k9a3TV8VcU73XZxfVHCHWMWF9SOqgoku0/QlY2yvlA4=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
Expand Down Expand Up @@ -260,6 +263,7 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
Expand Down Expand Up @@ -400,6 +404,7 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
Expand Down
14 changes: 14 additions & 0 deletions lib/mongo/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,18 @@ const (
UsernameKey = "username"

PasswordKey = "password"

FlagsCollection = "flags"

ChallengesCollection = "challenges"

SubmissionsCollection = "submissions"

ValueKey = "value"

IDKey = "id"

SubmittedBy = "submittedby"

Flag = "flag"
)
80 changes: 80 additions & 0 deletions lib/mongo/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,83 @@ func FetchSingleTeam(teamName string) (*types.CTFTeam, error) {
}
return team, nil
}

func FetchFlag(flagValue string) (*types.Flag, error) {
collection := link.Collection(FlagsCollection)
flag := &types.Flag{}
ctx := context.Background()
if err := collection.FindOne(ctx, bson.M{ValueKey: flagValue}).Decode(flag); err != nil {
return nil, err
}
return flag, nil
}

func FetchChallenge(challengeId int) (*types.Challenge, error) {
collection := link.Collection(ChallengesCollection)
challenge := &types.Challenge{}
ctx := context.Background()
if err := collection.FindOne(ctx, bson.M{IDKey: challengeId}).Decode(challenge); err != nil {
return nil, err
}
return challenge, nil
}

func FetchTeams(ctx context.Context, collectionName string, filter bson.M, opts ...*options.FindOptions) []types.CTFTeam {
collection := link.Collection(collectionName)
var data []types.CTFTeam

cur, err := collection.Find(ctx, filter, opts...)
if err != nil {
log.Println(err.Error())
return nil
}
defer cur.Close(ctx)
for cur.Next(ctx) {
var result types.CTFTeam
if err := cur.Decode(&result); err != nil {
log.Println(err.Error())
return nil
}
data = append(data, result)
}
if err := cur.Err(); err != nil {
log.Println(err)
return nil
}
return data
}

func FetchChallenges(ctx context.Context, collectionName string, filter bson.M, opts ...*options.FindOptions) []types.Challenge {
collection := link.Collection(collectionName)
var data []types.Challenge

cur, err := collection.Find(ctx, filter, opts...)
if err != nil {
log.Println(err.Error())
return nil
}
defer cur.Close(ctx)
for cur.Next(ctx) {
var result types.Challenge
if err := cur.Decode(&result); err != nil {
log.Println(err.Error())
return nil
}
data = append(data, result)
}
if err := cur.Err(); err != nil {
log.Println(err)
return nil
}
return data
}

func FetchSubmission(teamId int, flag string) (*types.Submission, error) {
collection := link.Collection(SubmissionsCollection)
submission := &types.Submission{}
ctx := context.Background()
if err := collection.FindOne(ctx, bson.M{SubmittedBy: teamId, Flag: flag}).Decode(submission); err != nil {
return nil, err
}
return submission, nil
}
55 changes: 55 additions & 0 deletions lib/utils/ssh.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package utils

import (
"bytes"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"golang.org/x/crypto/ssh"
"strings"
)

func CheckPrivateKey(privateKey, publicKey string) bool {
//check key
pub, _, _, _, err := ssh.ParseAuthorizedKey([]byte(publicKey))
if err != nil {
fmt.Println("error in parsing public key")
return false
}

private, err := ssh.ParsePrivateKey([]byte(privateKey))
if err != nil {
fmt.Println("error in parsing private key")
return false
}

return bytes.Equal(private.PublicKey().Marshal(), pub.Marshal())
}

func GenerateSSHKeyPair() (string, string, error) {
privateKey, err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil {
return "", "", err
}

// generate and write private key as PEM
var privKeyBuf strings.Builder

privateKeyPEM := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)}
if err := pem.Encode(&privKeyBuf, privateKeyPEM); err != nil {
return "", "", err
}

// generate and write public key
pub, err := ssh.NewPublicKey(&privateKey.PublicKey)
if err != nil {
return "", "", err
}

var pubKeyBuf strings.Builder
pubKeyBuf.Write(ssh.MarshalAuthorizedKey(pub))

return pubKeyBuf.String(), privKeyBuf.String(), nil
}
47 changes: 47 additions & 0 deletions services/flaghandlerservice/controller.go
Original file line number Diff line number Diff line change
@@ -1 +1,48 @@
package flaghandlerservice

import (
"context"
"time"

"github.com/sdslabs/katana/lib/mongo"
"github.com/sdslabs/katana/types"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
)

func checkSubmission(submission *types.Submission) bool {
_, err := mongo.FetchSubmission(submission.SubmittedBy, submission.Flag)
return err != nil
}

func submitFlag(value string, team types.CTFTeam) (bool, int) {
flag, err := mongo.FetchFlag(value)
var points int
if err != nil {
return false, 0
}
if flag.TeamID == team.Index {
return false, 0
}
submission := &types.Submission{}
submission.ChallengeID = flag.ChallengeID
submission.Flag = flag.Value
submission.SubmittedBy = team.Index
submission.Time = time.Now()
if !checkSubmission(submission) {
return false, 0
}
if res, err := mongo.FetchChallenge(flag.ChallengeID); err != nil {
return false, 0
} else {
team.Score = team.Score + res.Points
points = res.Points
}
if err := mongo.UpdateOne(context.Background(), mongo.TeamsCollection, bson.M{"id": team.Index}, team, options.FindOneAndUpdate().SetUpsert(false)); err != nil {
return false, 0
}
if _, err := mongo.InsertOne(context.Background(), mongo.SubmissionsCollection, submission); err != nil {
return false, 0
}
return true, points
}
51 changes: 51 additions & 0 deletions services/flaghandlerservice/cronjob.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package flaghandlerservice

import (
"context"
"log"
"sync"
"time"

"github.com/jasonlvhit/gocron"
"github.com/sdslabs/katana/configs"
"github.com/sdslabs/katana/lib/mongo"
"github.com/sdslabs/katana/types"
"go.mongodb.org/mongo-driver/bson"
)

func Ticker(wg sync.WaitGroup) {
log.Println("Ticker")
defer wg.Done()
handler()
gocron.Every(uint64(configs.FlagConfig.TickPeriod)).Second().Do(handler)
<-gocron.Start()
// gocron.Every(uint64(configs.FlagConfig.TickPeriod)).Second().Do(flaggetter) todo:trigger setter here
// <-gocron.Start()
}

func handler() {
log.Print("Handler triggered -> ", time.Now())
challenges := mongo.FetchChallenges(context.Background(), mongo.ChallengesCollection, bson.M{})
teams := mongo.FetchTeams(context.Background(), mongo.TeamsCollection, bson.M{})
time := time.Now()
for _, team := range teams {
for _, challenge := range challenges {
go flagUpdater(challenge, team, time)
}
}
}

func flagUpdater(challenge types.Challenge, team types.CTFTeam, triggerTime time.Time) {
flagValue := random(configs.FlagConfig.FlagLength)
var flag = &types.Flag{}
flag.Value = flagValue
flag.ChallengeID = challenge.ID
flag.CreatedAt = triggerTime
flag.TeamID = team.Index
if _, err := mongo.InsertOne(context.Background(), mongo.FlagsCollection, flag); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if this will be an issue. Use upsert here. Will do a discussion on this.

log.Println(err)
} else {
log.Println("Trigger setter")
//todo : trigger flag setter here
}
}
36 changes: 36 additions & 0 deletions services/flaghandlerservice/random.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package flaghandlerservice

import (
"bytes"
"crypto/rand"
"encoding/binary"
)

func Bytes(n int) []byte {
b := make([]byte, n)
_, err := rand.Read(b)
if err != nil {
panic(err)
}
return b
}

var defLetters = []rune("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")

func random(n int, letters ...string) string {
var letterRunes []rune
if len(letters) == 0 {
letterRunes = defLetters
} else {
letterRunes = []rune(letters[0])
}

var bb bytes.Buffer
bb.Grow(n)
l := uint32(len(letterRunes))
// on each loop, generate one random rune and append to output
for i := 0; i < n; i++ {
bb.WriteRune(letterRunes[binary.BigEndian.Uint32(Bytes(4))%l])
}
return bb.String()
}
Loading