-
Notifications
You must be signed in to change notification settings - Fork 7
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
Implement commands expansion logic #229
base: master
Are you sure you want to change the base?
Conversation
Update RestPostCommandAction to consume the new Search class
Separate search-related code to a new function Add docstrings and validations
Convert the Target.type to Enum to validate possible values
Improve error messages
Agents are part of group
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested and working.
Agent assigned to a group more than once:Group $ curl -s http://localhost:9200/wazuh-agents/_search | grep group004
"groups": ["group001","group004","group000","group004"],
"groups": ["group004","group001","group000"],
"groups": ["group004","group004"], Indexing command: curl -s http://localhost:9200/_plugins/_command_manager/commands -H 'Content-Type: application/json' -d '{
"commands": [
{
"source": "Engine",
"user": "user53",
"target": {
"id": "group004",
"type": "group"
},
"action": {
"name": "restart",
"args": {
"arg1": "/path/to/executable/arg6"
},
"version": "v4"
},
"timeout": 30
}
]
}' | jq
{
"_index": "wazuh-commands",
"_orders": [
{
"_id": "_6iXp5QBytahsG79A-l6"
},
{
"_id": "AKiXp5QBytahsG79A-p6"
},
{
"_id": "AaiXp5QBytahsG79A-p6"
}
],
"result": "OK"
} Only 3 commands are created: $ curl -s http://localhost:9200/wazuh-commands/_search | jq '.hits.hits[] | select(._id == "_6iXp5QBytahsG79A-l6" or ._id == "AKiXp5QBytahsG79A-p6" or ._id == "AaiXp5QBytahsG79A-p6") | ._source'
{
"agent": {
"groups": [
"group004",
"group004"
]
},
"@timestamp": "2025-01-27T11:47:59Z",
"delivery_timestamp": "2025-01-27T11:48:29Z",
"command": {
"action": {
"args": {
"arg1": "/path/to/executable/arg6"
},
"name": "restart",
"version": "v4"
},
"source": "Engine",
"user": "user53",
"order_id": "_qiXp5QBytahsG79A-l3",
"request_id": "_aiXp5QBytahsG79A-l3",
"timeout": 30,
"target": {
"id": "group004",
"type": "group"
},
"status": "failure"
}
}
{
"agent": {
"groups": [
"group001",
"group004",
"group000",
"group004"
]
},
"@timestamp": "2025-01-27T11:47:59Z",
"delivery_timestamp": "2025-01-27T11:48:29Z",
"command": {
"action": {
"args": {
"arg1": "/path/to/executable/arg6"
},
"name": "restart",
"version": "v4"
},
"source": "Engine",
"user": "user53",
"order_id": "_qiXp5QBytahsG79A-l3",
"request_id": "_aiXp5QBytahsG79A-l3",
"timeout": 30,
"target": {
"id": "group004",
"type": "group"
},
"status": "failure"
}
}
{
"agent": {
"groups": [
"group004",
"group001",
"group000"
]
},
"@timestamp": "2025-01-27T11:47:59Z",
"delivery_timestamp": "2025-01-27T11:48:29Z",
"command": {
"action": {
"args": {
"arg1": "/path/to/executable/arg6"
},
"name": "restart",
"version": "v4"
},
"source": "Engine",
"user": "user53",
"order_id": "_qiXp5QBytahsG79A-l3",
"request_id": "_aiXp5QBytahsG79A-l3",
"timeout": 30,
"target": {
"id": "group004",
"type": "group"
},
"status": "failure"
}
}
|
* @return an Orders object containing the generated orders. | ||
*/ | ||
@SuppressWarnings("unchecked") | ||
private static Orders commandsToOrders(NodeClient client, List<Command> commands) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commands expansion should be moved elsewhere, instead of RestPostCommandAction.java
.
Probably Orders
model, as it is the return type.
|
||
/// Commands expansion | ||
/// ================== | ||
/// Transforms the array of commands to orders. | ||
/// While commands can be targeted to groups of agents, orders are targeted to individual | ||
// agents. | ||
/// Given a group of agents A with N agents, a total of N orders are generated. One for each | ||
// agent. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These comments in the code help to understand the data flow and the responsibilities of this endpoint. Please, add them back.
private static List<Command> getCommandList(RestRequest request) throws IOException { | ||
// Request parsing | ||
XContentParser parser = request.contentParser(); | ||
List<Command> commands = new ArrayList<>(); | ||
ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser); | ||
parser.nextToken(); | ||
if (parser.nextToken() == XContentParser.Token.START_ARRAY) { | ||
commands = Command.parseToArray(parser); | ||
} else { | ||
log.error("Token does not match {}", parser.currentToken()); | ||
} | ||
|
||
return commands; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Parsing should be done in the model classes only.
channel.sendResponse( | ||
new BytesRestResponse( | ||
RestStatus.BAD_REQUEST, | ||
"Cannot generate orders. Invalid agent IDs or groups.")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In which case an Agent ID is invalid?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unused methods.
channel.sendResponse( | ||
new BytesRestResponse( | ||
RestStatus.BAD_REQUEST, | ||
"No valid commands detected in the request body.")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"No commands provided" is shorter and translates better to the condition being checked.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
la expansión de comandos no es correcta.
En una prueba que he hecho, he enviado el comando:
The commands expansion is not working as intended.
I tested using this command:
{
"commands": [
{
"action": {
"args": {},
"name": "restart",
"version": "5.0.0"
},
"source": "Users/Services",
"user": "Management API",
"timeout": 100,
"target": {
"id": "group001",
"type": "group"
}
}
]
}
One of the expanded commands is:
{
"_index": "wazuh-commands",
"_id": "J4LK0JQBHI2QBvqR03xq",
"_score": 1,
"_source": {
"agent": {
"groups": [
"group000",
"group001"
]
},
"command": {
"source": "Users/Services",
"user": "Management API",
"target": {
"type": "group",
"id": "group001"
},
"action": {
"name": "restart",
"args": {
},
"version": "5.0.0"
},
"timeout": 100,
"status": "pending",
"order_id": "JoLK0JQBHI2QBvqR03xU",
"request_id": "JYLK0JQBHI2QBvqR03xU"
},
"@timestamp": "2025-02-04T11:49:00Z",
"delivery_timestamp": "2025-02-04T11:50:40Z"
}
}
The result should be a command targeted to an specific agent, but it is not.
"target": {
"type": "agent",
"id": "<agent-id>"
}
Description
Detect the commands which target type is
group
, search in the.agents
index for the agents of each group and generate the corresponding Orders.Renamed the
Document
class toOrders
, replacing the previously unused Orders class.Working validations
Command expansion
Group used for the test:
group000
Request
Response
Command creation log
Command indexed
% curl http://127.0.0.1:9200/.commands/_search {"took":2,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":2,"relation":"eq"},"max_score":1.0,"hits":[{"_index":".commands","_id":"WS5fjpQBDZQg8-hA8AYd","_score":1.0,"_source":{"agent":{"groups":["group000","group001","group003"]},"@timestamp":"2025-01-22T14:17:19Z","delivery_timestamp":"2025-01-22T14:17:49Z","command":{"action":{"args":{"arg1":"/path/to/executable/arg6"},"name":"restart","version":"v4"},"source":"Engine","user":"user53","order_id":"WC5fjpQBDZQg8-hA8AYP","request_id":"Vy5fjpQBDZQg8-hA8AYP","timeout":30,"target":{"id":"group000","type":"group"},"status":"failure"}}},{"_index":".commands","_id":"Wi5fjpQBDZQg8-hA8AYe","_score":1.0,"_source":{"agent":{"groups":["group000","group002","group002"]},"@timestamp":"2025-01-22T14:17:19Z","delivery_timestamp":"2025-01-22T14:17:49Z","command":{"action":{"args":{"arg1":"/path/to/executable/arg6"},"name":"restart","version":"v4"},"source":"Engine","user":"user53","order_id":"WC5fjpQBDZQg8-hA8AYP","request_id":"Vy5fjpQBDZQg8-hA8AYP","timeout":30,"target":{"id":"group000","type":"group"},"status":"failure"}}}]}}
Command expansion - Group assigned to the same agent more than once
Using the group
001
Basic command creation
Using agent id:
agent94
Issues Resolved
Resolves #88