// Check service status and flag if it's exist. func checkFlag(db *sql.DB, round int, team steward.Team, svc steward.Service, wg *sync.WaitGroup) { defer wg.Done() // Check service port open portOpen := true if !svc.UDP { portOpen = tcpPortOpen(team, svc) } var state steward.ServiceState if portOpen { // First check service logic state, _ = checkService(db, round, team, svc) if state == steward.StatusUP { // If logic is correct, do flag check state, _ = getFlag(db, round, team, svc) } } else { state = steward.StatusDown } err := steward.PutStatus(db, steward.Status{round, team.ID, svc.ID, state}) if err != nil { log.Println("Add status failed:", err) return } }
func TestGetServiceCurrentStatus(t *testing.T) { db, err := openDB() defer db.Close() round := 1 team := 2 service := 3 status1 := steward.Status{Round: round, TeamID: team, ServiceID: service, State: steward.StatusUP} steward.PutStatus(db.db, status1) halfStatus := steward.Status{Round: round, TeamID: team, ServiceID: service, State: steward.StatusUnknown} state, err := steward.GetState(db.db, halfStatus) if err != nil { log.Fatalln("Get state failed:", err) } if state != steward.StatusUP { log.Fatalln("Get states invalid") } }
func putFlag(db *sql.DB, priv *rsa.PrivateKey, round int, team steward.Team, svc steward.Service) (err error) { flag, err := vexillary.GenerateFlag(priv) if err != nil { log.Println("Generate flag failed:", err) return } portOpen := true if !svc.UDP { portOpen = tcpPortOpen(team, svc) } var cred, logs string var state steward.ServiceState if portOpen { if team.UseNetbox { cred, logs, state, err = sshPut(team.Netbox, svc.CheckerPath, team.Vulnbox, svc.Port, flag) } else { cred, logs, state, err = put(svc.CheckerPath, team.Vulnbox, svc.Port, flag) } if err != nil { log.Println("Put flag to service failed:", err) return } if state != steward.StatusUP { log.Printf("Put flag, round %d, team %s, service %s: %s", round, team.Name, svc.Name, logs) } } else { state = steward.StatusDown } err = steward.PutStatus(db, steward.Status{round, team.ID, svc.ID, state}) if err != nil { log.Println("Add status to database failed:", err) return } err = steward.AddFlag(db, steward.Flag{-1, flag, round, team.ID, svc.ID, cred}) if err != nil { log.Println("Add flag to database failed:", err) return } return }
func TestGetAllStatus(t *testing.T) { db, err := openDB() defer db.Close() round := 1 team := 2 service := 3 status1 := steward.Status{Round: round, TeamID: team, ServiceID: service, State: steward.StatusUP} status2 := steward.Status{Round: round, TeamID: team, ServiceID: service, State: steward.StatusMumble} status3 := steward.Status{Round: round, TeamID: team, ServiceID: service, State: steward.StatusCorrupt} steward.PutStatus(db.db, status1) steward.PutStatus(db.db, status2) steward.PutStatus(db.db, status3) halfStatus := steward.Status{Round: round, TeamID: team, ServiceID: service, State: steward.StatusUnknown} states, err := steward.GetStates(db.db, halfStatus) if err != nil { log.Fatalln("Get states failed:", err) } if len(states) != 3 { log.Fatalln("Get states moar/less than put:", err) } if states[0] != steward.StatusUP || states[1] != steward.StatusMumble || states[2] != steward.StatusCorrupt { log.Fatalln("Get states invalid") } }
func TestPutStatus(t *testing.T) { db, err := openDB() defer db.Close() status := steward.Status{Round: 10, TeamID: 10, ServiceID: 10, State: 10} err = steward.PutStatus(db.db, status) if err != nil { log.Fatalln("Add status failed:", err) } }
func TestCountStatesResult(*testing.T) { db, err := openDB() if err != nil { log.Fatalln("Open database failed:", err) } defer db.Close() r := 1 // round t := 1 // team id s := 1 // service id svc := steward.Service{ID: s, Name: "foo", Port: 8080, CheckerPath: "", UDP: false} steward.PutStatus(db.db, steward.Status{Round: r, TeamID: t, ServiceID: s, State: steward.StatusUP}) steward.PutStatus(db.db, steward.Status{Round: r, TeamID: t, ServiceID: s, State: steward.StatusUP}) steward.PutStatus(db.db, steward.Status{Round: r, TeamID: t, ServiceID: s, State: steward.StatusUP}) steward.PutStatus(db.db, steward.Status{Round: r, TeamID: t, ServiceID: s, State: steward.StatusMumble}) res, err := counter.CountStatesResult(db.db, r, t, svc) if err != nil { log.Fatalln("Count states failed:", err) } must_be := 0.75 if res != must_be { log.Fatalln("Result invalid:", res, "instead", must_be) } }
func TestCountDefenceResult(*testing.T) { db, err := openDB() if err != nil { log.Fatalln("Open database failed:", err) } defer db.Close() r := 1 t := 1 services := make([]steward.Service, 0) services = append(services, steward.Service{ID: 1, Name: "foo", Port: 8080, CheckerPath: "", UDP: false}) services = append(services, steward.Service{ID: 2, Name: "bar", Port: 8081, CheckerPath: "", UDP: false}) services = append(services, steward.Service{ID: 3, Name: "baz", Port: 8082, CheckerPath: "", UDP: false}) services = append(services, steward.Service{ID: 4, Name: "qwe", Port: 8083, CheckerPath: "", UDP: false}) steward.PutStatus(db.db, steward.Status{Round: r, TeamID: t, ServiceID: 1, State: steward.StatusUP}) steward.PutStatus(db.db, steward.Status{Round: r, TeamID: t, ServiceID: 1, State: steward.StatusUP}) steward.PutStatus(db.db, steward.Status{Round: r, TeamID: t, ServiceID: 1, State: steward.StatusUP}) steward.PutStatus(db.db, steward.Status{Round: r, TeamID: t, ServiceID: 1, State: steward.StatusDown}) steward.PutStatus(db.db, steward.Status{Round: r, TeamID: t, ServiceID: 2, State: steward.StatusDown}) steward.PutStatus(db.db, steward.Status{Round: r, TeamID: t, ServiceID: 2, State: steward.StatusDown}) steward.PutStatus(db.db, steward.Status{Round: r, TeamID: t, ServiceID: 2, State: steward.StatusDown}) steward.PutStatus(db.db, steward.Status{Round: r, TeamID: t, ServiceID: 2, State: steward.StatusDown}) steward.PutStatus(db.db, steward.Status{Round: r, TeamID: t, ServiceID: 3, State: steward.StatusUP}) steward.PutStatus(db.db, steward.Status{Round: r, TeamID: t, ServiceID: 3, State: steward.StatusUP}) steward.PutStatus(db.db, steward.Status{Round: r, TeamID: t, ServiceID: 3, State: steward.StatusUP}) steward.PutStatus(db.db, steward.Status{Round: r, TeamID: t, ServiceID: 4, State: steward.StatusUP}) steward.PutStatus(db.db, steward.Status{Round: r, TeamID: t, ServiceID: 4, State: steward.StatusDown}) steward.PutStatus(db.db, steward.Status{Round: r, TeamID: t, ServiceID: 4, State: steward.StatusDown}) steward.PutStatus(db.db, steward.Status{Round: r, TeamID: t, ServiceID: 4, State: steward.StatusDown}) res, err := counter.CountDefenceResult(db.db, r, t, services) if err != nil { log.Fatalln("Count defence result failed:", err) } must_be := 0.75*0.25 + 0 + 1*0.25 + 0.25*0.25 if res != must_be { log.Fatalln("Result invalid:", res, "instead", must_be) } }
func TestCountRound(*testing.T) { db, err := openDB() if err != nil { log.Fatalln("Open database failed:", err) } defer db.Close() fillTestTeams(db.db) fillTestServices(db.db) priv, err := vexillary.GenerateKey() if err != nil { log.Fatalln("Generate key failed:", err) } round, err := steward.NewRound(db.db, time.Minute) if err != nil { log.Fatalln("Create new round failed:", err) } teams, err := steward.GetTeams(db.db) if err != nil { log.Fatalln("Get teams failed:", err) } services, err := steward.GetServices(db.db) if err != nil { log.Fatalln("Get services failed:", err) } flags := make([]string, 0) for _, team := range teams { for _, svc := range services { flag, err := vexillary.GenerateFlag(priv) if err != nil { log.Fatalln("Generate flag failed:", err) } flags = append(flags, flag) flg := steward.Flag{ID: -1, Flag: flag, Round: round, TeamID: team.ID, ServiceID: svc.ID, Cred: ""} err = steward.AddFlag(db.db, flg) if err != nil { log.Fatalln("Add flag to database failed:", err) } err = steward.PutStatus(db.db, steward.Status{ Round: round, TeamID: team.ID, ServiceID: svc.ID, State: steward.StatusUP}) if err != nil { log.Fatalln("Put status to database failed:", err) } } } flag1, err := steward.GetFlagInfo(db.db, flags[2]) if err != nil { log.Fatalln("Get flag info failed:", err) } err = steward.CaptureFlag(db.db, flag1.ID, teams[2].ID) if err != nil { log.Fatalln("Capture flag failed:", err) } flag2, err := steward.GetFlagInfo(db.db, flags[7]) if err != nil { log.Fatalln("Get flag info failed:", err) } err = steward.CaptureFlag(db.db, flag2.ID, teams[3].ID) if err != nil { log.Fatalln("Capture flag failed:", err) } err = counter.CountRound(db.db, round, teams, services) if err != nil { log.Fatalln("Count round failed:", err) } res, err := steward.GetRoundResult(db.db, teams[0].ID, round) if err != nil || res.AttackScore != 0.0 || res.DefenceScore != 1.75 { log.Fatalln("Invalid result:", res) } res, err = steward.GetRoundResult(db.db, teams[1].ID, round) if err != nil || res.AttackScore != 0.0 || res.DefenceScore != 1.75 { log.Fatalln("Invalid result:", res) } res, err = steward.GetRoundResult(db.db, teams[2].ID, round) if err != nil || res.AttackScore != 0.25 || res.DefenceScore != 2.0 { log.Fatalln("Invalid result:", res) } res, err = steward.GetRoundResult(db.db, teams[3].ID, round) if err != nil || res.AttackScore != 0.25 || res.DefenceScore != 2.0 { log.Fatalln("Invalid result:", res) } }
func TestReceiver(*testing.T) { db, err := openDB() if err != nil { log.Fatalln("Open database failed:", err) } defer db.Close() priv, err := vexillary.GenerateKey() if err != nil { log.Fatalln("Generate key failed:", err) } addr := "127.0.0.1:65000" flag, err := vexillary.GenerateFlag(priv) if err != nil { log.Fatalln("Generate flag failed:", err) } err = steward.AddFlag(db.db, steward.Flag{-1, flag, 1, 8, 1, ""}) if err != nil { log.Fatalln("Add flag failed:", err) } firstRound, err := steward.NewRound(db.db, time.Minute*2) if err != nil { log.Fatalln("New round failed:", err) } attackFlow := make(chan scoreboard.Attack) go FlagReceiver(db.db, priv, addr, time.Nanosecond, time.Minute, attackFlow) time.Sleep(time.Second) // wait for init listener // The attacker must appear to be a team (e.g. jury cannot attack) testFlag(addr, flag, invalidTeamMsg) t := steward.Team{ID: -1, Name: "TestTeam", Subnet: "127.0.0.1/24", Vulnbox: "1"} // Correct flag must be captured teamID, err := steward.AddTeam(db.db, t) if err != nil { log.Fatalln("Add team failed:", err) } serviceID := 1 // Flag must be captured only if service status ok steward.PutStatus(db.db, steward.Status{firstRound, teamID, serviceID, steward.StatusUP}) testFlag(addr, flag, capturedMsg) // Correct flag must be captured only one testFlag(addr, flag, alreadyCapturedMsg) // Incorrect (non-signed or signed on other key) flag must be invalid testFlag(addr, "1e7b642f2282886377d1655af6097dd6101eac5b=", invalidFlagMsg) // Correct flag that does not exist in database must not be captured newFlag, err := vexillary.GenerateFlag(priv) if err != nil { log.Fatalln("Generate flag failed:", err) } testFlag(addr, newFlag, flagDoesNotExistMsg) // Submitted flag does not belongs to the attacking team flag4, err := vexillary.GenerateFlag(priv) if err != nil { log.Fatalln("Generate flag failed:", err) } err = steward.AddFlag(db.db, steward.Flag{-1, flag4, 1, teamID, 1, ""}) if err != nil { log.Fatalln("Add flag failed:", err) } testFlag(addr, flag4, flagYoursMsg) // Correct flag from another round must not be captured flag2, err := vexillary.GenerateFlag(priv) if err != nil { log.Fatalln("Generate flag failed:", err) } curRound, err := steward.CurrentRound(db.db) err = steward.AddFlag(db.db, steward.Flag{-1, flag2, curRound.ID, 8, 1, ""}) if err != nil { log.Fatalln("Add flag failed:", err) } _, err = steward.NewRound(db.db, time.Minute*2) if err != nil { log.Fatalln("New round failed:", err) } testFlag(addr, flag2, flagExpiredMsg) // Correct flag from expired round must not be captured roundLen := time.Second roundID, err := steward.NewRound(db.db, roundLen) if err != nil { log.Fatalln("New round failed:", err) } flag3, err := vexillary.GenerateFlag(priv) if err != nil { log.Fatalln("Generate flag failed:", err) } err = steward.AddFlag(db.db, steward.Flag{-1, flag3, roundID, 8, 1, ""}) if err != nil { log.Fatalln("Add flag failed:", err) } time.Sleep(roundLen) // wait end of round testFlag(addr, flag3, flagExpiredMsg) // If service status down flag must not be captured roundID, err = steward.NewRound(db.db, time.Minute) if err != nil { log.Fatalln("New round failed:", err) } flag5, err := vexillary.GenerateFlag(priv) if err != nil { log.Fatalln("Generate flag failed:", err) } err = steward.AddFlag(db.db, steward.Flag{-1, flag5, roundID, 8, serviceID, ""}) if err != nil { log.Fatalln("Add flag failed:", err) } steward.PutStatus(db.db, steward.Status{roundID, teamID, serviceID, steward.StatusDown}) testFlag(addr, flag5, serviceNotUpMsg) steward.PutStatus(db.db, steward.Status{roundID, teamID, serviceID, steward.StatusUP}) // If attempts limit exceeded flag must not be captured newAddr := "127.0.0.1:64000" // Start new receiver for test timeouts go FlagReceiver(db.db, priv, newAddr, time.Second, time.Minute, attackFlow) time.Sleep(time.Second) // wait for init listener // Just for take timeout testFlag(newAddr, flag3, flagExpiredMsg) // Can't use testFlag, if attempts limit exceeded server does not send // greeting message, and client has not able to send flag conn, err := net.DialTimeout("tcp", newAddr, time.Second) if err != nil { log.Fatalln("Connect to receiver failed:", err) } msg, err := bufio.NewReader(conn).ReadString('\n') if err != nil { log.Fatalln("Invalid response:", err) } response := attemptsLimitMsg if msg != response { log.Fatalf("Invalid message [%v] instead [%v]", strings.Trim(msg, "\n"), strings.Trim(response, "\n")) } }