예제 #1
0
// 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
	}
}
예제 #2
0
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")
	}

}
예제 #3
0
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
}
예제 #4
0
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")
	}
}
예제 #5
0
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)
	}
}
예제 #6
0
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)
	}

}
예제 #7
0
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)

	}
}
예제 #8
0
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)
	}

}
예제 #9
0
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"))
	}
}