Skip to content

Commit

Permalink
parent 7c76667
Browse files Browse the repository at this point in the history
author mayankmittal-iitr <[email protected]> 1638563217 +0530
committer Mayank Mittal <[email protected]> 1642515212 +0530

Add flag submission service
  • Loading branch information
MayankMittal1 committed Jan 18, 2022
1 parent 7c76667 commit e149cf5
Show file tree
Hide file tree
Showing 17 changed files with 510 additions and 8 deletions.
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 {
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

0 comments on commit e149cf5

Please sign in to comment.