graphql interaction
The API should ensure a check daemon process is running and upload the target host information to graphql so the check-daemon can execute.
To deploy a check: (Click to expand)
mutation InsertChecks {
insert_checks_deployed(
objects: [{
check_id: "<uuid here>",
event_id: "<uuid here>",
group_id: "<uuid here>",
host: "<ip or hostname here>"
}]
) {
affected_rows
}
}
Dependencies for deployment
To ensure the operation is successful, the event_id, check_id and group_id must exist. For the sandbox, each challenge will be an event_id that will need to be randomly generated.
events
To create a new event and let the id be generated (Click to expand)
mutation InsertSomeEvent {
insert_events_one(
object: {
name: "linux basics 1"
}
) {
id
}
}
This will return the following json that can be parsed for the UUID
{
"data": {
"insert_events_one": {
"id": "c29184d6-299f-48f3-9273-f80c0e2a44be"
}
}
}
Groups
Similarly group_id can be inserted and generate an id, or use the keycloak uuid for a user:
Click to expand
mutation InsertUserGroup {
insert_groups_one(
object: {
id: "b8e9cc26-5c35-4826-86b1-0c7bbca8128b",
name: "sradigan@c2games.org"
}
) {
id
name
}
}
Or make something arbitrary and let the database make the id for you:
Click to expand
mutation ArbitraryGroup {
insert_groups_one(
object: {
name: "Some Generic Team Name"
}
) {
id
name
}
}
{
"data": {
"insert_groups_one": {
"id": "3a420055-7a14-45bc-b6af-cfdf85a1fa88",
"name": "Some Generic Team Name"
}
}
}
Checks
For the checks, likely these will need to be defined ahead of time, and example is here:
Click to expand (really long)
{
"data": {
"checks_checks": [
{
"id": "106483ca-74c3-4933-8b60-ac3986580d87",
"name": "external_icmp",
"display_name": "Router",
"type": "service",
"script": "check_icmp.py",
"args": null,
"created": "2022-09-08T12:41:05.13732+00:00",
"modified": "2022-09-08T12:41:05.13732+00:00",
"description": "Check if router responds to ping"
},
{
"id": "7cb7143e-f9ef-48b7-8bd8-0fbab626fcec",
"name": "external_www_content",
"display_name": "WWW Content",
"type": "service",
"script": "check_web_content.py",
"args": null,
"created": "2022-09-08T12:44:09.784755+00:00",
"modified": "2022-09-08T12:44:09.784755+00:00",
"description": "Check if HTTP content served"
},
{
"id": "8820a6b7-cc2e-4f47-a9c5-5743e9dad0c3",
"name": "external_www_content_ssl",
"display_name": "SSL WWW Content",
"type": "service",
"script": "check_web_content.py",
"args": "--ssl --ssl-ca-bundle root_ca.crt",
"created": "2022-09-08T12:45:24.921085+00:00",
"modified": "2022-09-08T12:45:24.921085+00:00",
"description": "Check if HTTPS content served"
},
{
"id": "a8d979fb-1428-46a7-9748-4f1463404094",
"name": "external_ftp_content",
"display_name": "FTP Content",
"type": "service",
"script": "check_ftp.py",
"args": "--check-size --check-hash",
"created": "2022-09-08T12:46:34.249669+00:00",
"modified": "2022-09-08T12:46:34.249669+00:00",
"description": "Check if FTP content served"
},
{
"id": "3b300334-a27b-4363-a1ad-77da72811840",
"name": "external_ftp_write",
"display_name": "FTP Write",
"type": "service",
"script": "check_ftp.py",
"args": "--check-write",
"created": "2022-09-08T12:47:24.217153+00:00",
"modified": "2022-09-08T12:47:24.217153+00:00",
"description": "Check FTP write permission"
},
{
"id": "da972052-40d2-49b0-9429-ce76d5b2374f",
"name": "external_ssh",
"display_name": "SSH Access",
"type": "service",
"script": "check_ssh.py",
"args": null,
"created": "2022-09-08T12:48:02.856626+00:00",
"modified": "2022-09-08T12:48:02.856626+00:00",
"description": "Check SSH Access"
},
{
"id": "5ccd8b8f-6861-4295-87dc-a27952886da9",
"name": "external_ftp_login",
"display_name": "FTP Login",
"type": "service",
"script": "check_ftp.py",
"args": "--check-login",
"created": "2022-09-08T12:48:46.320794+00:00",
"modified": "2022-09-08T12:48:46.320794+00:00",
"description": "Check FTP login"
},
{
"id": "f8533f29-cc7a-4082-a7b9-3d2f5cf27795",
"name": "external_http",
"display_name": "HTTP Connection",
"type": "service",
"script": "check_http.py",
"args": null,
"created": "2022-09-08T12:49:41.318909+00:00",
"modified": "2022-09-08T12:49:41.318909+00:00",
"description": "Check HTTP port open"
},
{
"id": "fd277bc7-d75f-4c2b-857b-64addf41eb60",
"name": "external_reverse_dns",
"display_name": "External Reverse DNS",
"type": "service",
"script": "check_dns.py",
"args": "--reverse --external",
"created": "2022-09-08T12:51:33.724987+00:00",
"modified": "2022-09-08T12:51:33.724987+00:00",
"description": "Check reverse DNS resolution externally"
},
{
"id": "6bfa7185-d39b-4fcd-9a41-dfd93c416fb0",
"name": "internal_reverse_dns",
"display_name": "Internal Reverse DNS",
"type": "service",
"script": "check_dns.py",
"args": "--reverse --internal",
"created": "2022-09-08T12:51:58.812633+00:00",
"modified": "2022-09-08T12:51:58.812633+00:00",
"description": "Check reverse DNS resolution internally"
},
{
"id": "96e75289-ddae-4d39-85f1-8256f075af45",
"name": "internal_forward_dns",
"display_name": "Internal Forward DNS",
"type": "service",
"script": "check_dns.py",
"args": "--forward --internal",
"created": "2022-09-08T12:52:19.140746+00:00",
"modified": "2022-09-08T12:52:19.140746+00:00",
"description": "Check forward DNS resolution internally"
},
{
"id": "0b5ec095-3de6-4096-b357-8da018367210",
"name": "internal_mysql",
"display_name": "MySQL",
"type": "service",
"script": "check_mysql.py",
"args": null,
"created": "2022-09-08T12:53:42.592692+00:00",
"modified": "2022-09-08T12:53:42.592692+00:00",
"description": "Check MySQL access and content"
},
{
"id": "e20b0eda-31f2-4e29-91fc-4c21251c2f7b",
"name": "external_forward_dns",
"display_name": "External Forward DNS",
"type": "service",
"script": "check_forward_dns.py",
"args": "--forward --external",
"created": "2022-09-08T12:50:42.254286+00:00",
"modified": "2022-09-08T12:50:42.254286+00:00",
"description": "Check forward DNS resolution externally"
},
{
"id": "2055d4ec-a27f-4b79-a2b5-5d8e833b907f",
"name": "internal_red_exploits",
"display_name": "Redteam Exploits",
"type": "service",
"script": "user_keys_and_passwords.py",
"args": "--timeout 1 -n {{.Group.Id}}",
"created": "2022-09-08T12:56:59.63913+00:00",
"modified": "2022-09-08T12:56:59.63913+00:00",
"description": "Check status of redteam exploits"
}
]
}
}
Acceptance Criteria
-
Queries are in place for getting data needed to spin up a or tear down a check -
Mutations are in place to add or remove active checks -
Check daemon is started for a deployment (maybe this can be another issue?)See #18 -
Appropriate entries for any dependent GQL fields are supplied - uploading the check group (the user's keycloak uuid for sandbox)
- ensuring the event entry is created for the scenario being played, so like mini-hack-1, world-of-bills-3 or whatever the name of the thing being spun up is.
-
IP address of the target is supplied to graphql
Edited by Sean Radigan