Пример #1
0
func commandPrintShort(data interface{}) (idstr, agtname, duration, status string, err error) {
	defer func() {
		if e := recover(); e != nil {
			err = fmt.Errorf("commandPrintShort() -> %v", e)
		}
	}()
	cmd, err := client.ValueToCommand(data)
	if err != nil {
		panic(err)
	}
	idstr = fmt.Sprintf("%.0f", cmd.ID)
	if len(idstr) < 20 {
		for i := len(idstr); i < 20; i++ {
			idstr += " "
		}
	}

	agtname = cmd.Agent.Name
	if len(agtname) < 30 {
		for i := len(agtname); i < 30; i++ {
			agtname += " "
		}
	}
	if len(agtname) > 30 {
		agtname = agtname[0:27] + "..."
	}

	duration = cmd.FinishTime.Sub(cmd.StartTime).String()
	if len(duration) > 10 {
		duration = duration[0:8] + duration[len(duration)-3:len(duration)-1]
	}
	if len(duration) < 10 {
		for i := len(duration); i < 10; i++ {
			duration += " "
		}
	}

	status = cmd.Status
	if len(status) > 10 {
		status = status[0:9]
	}
	if len(status) < 10 {
		for i := len(status); i < 10; i++ {
			status += " "
		}
	}

	return
}
Пример #2
0
func searchCommands(aid float64, show string, cli client.Client) (cmds []mig.Command, err error) {
	defer func() {
		fmt.Printf("\n")
		if e := recover(); e != nil {
			err = fmt.Errorf("searchCommands() -> %v", e)
		}
	}()
	base := fmt.Sprintf("search?type=command&actionid=%.0f", aid)
	switch show {
	case "found":
		base += "&foundanything=true"
	case "notfound":
		base += "&foundanything=false"
	}
	offset := 0
	// loop until all results have been retrieved using paginated queries
	for {
		fmt.Printf(".")
		target := fmt.Sprintf("%s&limit=50&offset=%d", base, offset)
		resource, err := cli.GetAPIResource(target)
		// because we query using pagination, the last query will return a 404 with no result.
		// When that happens, GetAPIResource returns an error which we do not report to the user
		if resource.Collection.Error.Message == "no results found" {
			err = nil
			break
		} else if err != nil {
			panic(err)
		}
		for _, item := range resource.Collection.Items {
			for _, data := range item.Data {
				if data.Name != "command" {
					continue
				}
				cmd, err := client.ValueToCommand(data.Value)
				if err != nil {
					panic(err)
				}
				cmds = append(cmds, cmd)
			}
		}
		// else increase limit and offset and continue
		offset += 50
	}
	return
}
Пример #3
0
func searchFoundAnything(a mig.Action, wantFound bool, cli client.Client) (err error) {
	defer func() {
		if e := recover(); e != nil {
			err = fmt.Errorf("searchFoundAnything() -> %v", e)
		}
	}()
	target := "search?type=command&limit=1000000&actionid=" + fmt.Sprintf("%.0f", a.ID)
	if wantFound {
		target += "&foundanything=true"
	} else {
		target += "&foundanything=false"
	}
	resource, err := cli.GetAPIResource(target)
	if err != nil {
		panic(err)
	}
	agents := make(map[float64]mig.Command)
	for _, item := range resource.Collection.Items {
		for _, data := range item.Data {
			if data.Name != "command" {
				continue
			}
			cmd, err := client.ValueToCommand(data.Value)
			if err != nil {
				panic(err)
			}
			agents[cmd.Agent.ID] = cmd
		}
	}
	if wantFound {
		fmt.Printf("%d agents have found things\n", len(agents))
	} else {
		fmt.Printf("%d agents have not found anything\n", len(agents))
	}
	if len(agents) > 0 {
		fmt.Println("---- Command ID ----    ---- Agent Name & ID----")
		for agtid, cmd := range agents {
			fmt.Printf("%20.0f    %s [%.0f]\n", cmd.ID, cmd.Agent.Name, agtid)
		}
	}
	return
}
Пример #4
0
// search runs a search for actions, commands or agents
func search(input string, cli client.Client) (err error) {
	defer func() {
		if e := recover(); e != nil {
			err = fmt.Errorf("search() -> %v", e)
		}
	}()
	orders := strings.Split(input, " ")
	if len(orders) < 2 {
		orders = append(orders, "help")
	}
	sType := ""
	switch orders[1] {
	case "action", "agent", "command", "investigator":
		sType = orders[1]
	case "", "help":
		fmt.Printf(`usage: search <action|agent|command|investigator> where <parameters> [<and|or> <parameters>]
The following search parameters are available:
`)
		return nil
	default:
		return fmt.Errorf("Invalid search '%s'. Try `search help`.\n", input)
	}
	sp, err := parseSearchQuery(orders)
	if err != nil {
		panic(err)
	}
	items, err := runSearchQuery(sp, cli)
	if err != nil {
		panic(err)
	}
	switch sType {
	case "agent":
		agents, err := filterAgentItems(sp, items, cli)
		if err != nil {
			panic(err)
		}
		fmt.Println("----    ID      ---- + ----         Name         ---- + -- Status -- + -- Last Heartbeat --")
		for _, agt := range agents {
			name := agt.Name
			if len(name) < 30 {
				for i := len(name); i < 30; i++ {
					name += " "
				}
			}
			if len(name) > 30 {
				name = name[0:27] + "..."
			}
			status := agt.Status
			if len(status) < 12 {
				for i := len(status); i < 12; i++ {
					status += " "
				}
			}
			if len(status) > 12 {
				status = status[0:12]
			}
			fmt.Printf("%20.0f   %s   %s   %s\n", agt.ID, name, status, agt.HeartBeatTS.Format(time.RFC3339))
		}
	case "action", "command":
		fmt.Println("----    ID      ---- + ----         Name         ---- + --- Last Updated ---")
		for _, item := range items {
			for _, data := range item.Data {
				if data.Name != sType {
					continue
				}
				switch data.Name {
				case "action":
					idstr, name, datestr, _, _, err := actionPrintShort(data.Value)
					if err != nil {
						panic(err)
					}
					fmt.Printf("%s   %s   %s\n", idstr, name, datestr)
				case "command":
					cmd, err := client.ValueToCommand(data.Value)
					if err != nil {
						panic(err)
					}
					name := cmd.Action.Name
					if len(name) < 30 {
						for i := len(name); i < 30; i++ {
							name += " "
						}
					}
					if len(name) > 30 {
						name = name[0:27] + "..."
					}
					fmt.Printf("%20.0f   %s   %s\n", cmd.ID, name, cmd.FinishTime.Format(time.RFC3339))
				}
			}
		}
	case "investigator":
		fmt.Println("- ID - + ----         Name         ---- + --- Status ---")
		for _, item := range items {
			for _, data := range item.Data {
				if data.Name != sType {
					continue
				}
				switch data.Name {
				case "investigator":
					inv, err := client.ValueToInvestigator(data.Value)
					if err != nil {
						panic(err)
					}
					name := inv.Name
					if len(name) < 30 {
						for i := len(name); i < 30; i++ {
							name += " "
						}
					}
					if len(name) > 30 {
						name = name[0:27] + "..."
					}
					fmt.Printf("%6.0f   %s   %s\n", inv.ID, name, inv.Status)
				}
			}
		}
	}
	return
}