@@ -1155,9 +1155,51 @@ async def waitfor_for_task_output(
11551155 final_output = b""
11561156 for output in aggregated_output :
11571157 final_output += base64 .b64decode (output ["response_text" ])
1158+ subtaskIds = await get_all_subtask_ids (mythic = mythic , task_display_id = task_display_id , fetch_display_id_instead = True )
1159+ for subtask in subtaskIds :
1160+ subtaskOutput = await get_all_task_output_by_id (mythic = mythic , task_display_id = subtask )
1161+ for r in subtaskOutput :
1162+ final_output += base64 .b64decode (r ["response_text" ])
11581163 return final_output
11591164
11601165
1166+ async def get_all_subtask_ids (mythic : mythic_classes .Mythic , task_display_id : int ,
1167+ fetch_display_id_instead : bool ) -> List [int ]:
1168+ subtaskIds = []
1169+ idQuery = f"""
1170+ query taskIdFromDisplayID($task_display_id: Int!){{
1171+ task(where: {{display_id: {{_eq: $task_display_id}}}}){{
1172+ id
1173+ }}
1174+ }}
1175+ """
1176+ subtaskQuery = """
1177+ query subtaskList($task_id: Int!){
1178+ task(where: {parent_task_id: {_eq: $task_id}}){
1179+ id
1180+ display_id
1181+ }
1182+ }
1183+ """
1184+ initial = await mythic_utilities .graphql_post (
1185+ mythic = mythic , query = idQuery , variables = {"task_display_id" : task_display_id }
1186+ )
1187+ if initial ["task" ]:
1188+ taskIdsToCheck = [initial ["task" ][0 ]["id" ]]
1189+ while len (taskIdsToCheck ) > 0 :
1190+ currentTaskId = taskIdsToCheck .pop ()
1191+ subtasks = await mythic_utilities .graphql_post (
1192+ mythic = mythic , query = subtaskQuery , variables = {"task_id" : currentTaskId }
1193+ )
1194+ for t in subtasks ["task" ]:
1195+ taskIdsToCheck .append (t ["id" ])
1196+ if fetch_display_id_instead :
1197+ subtaskIds .append (t ["display_id" ])
1198+ else :
1199+ subtaskIds .append (t ["id" ])
1200+ return subtaskIds
1201+
1202+
11611203async def get_all_task_output (
11621204 mythic : mythic_classes .Mythic , custom_return_attributes : str = None , batch_size : int = 10
11631205) -> AsyncGenerator :
@@ -1208,6 +1250,33 @@ async def get_all_task_output_by_id(
12081250 return initial ["response" ]
12091251
12101252
1253+ async def get_all_task_and_subtask_output_by_id (
1254+ mythic : mythic_classes .Mythic , task_display_id : int , custom_return_attributes : str = None
1255+ ) -> List [dict ]:
1256+ """
1257+ Execute a query to get all responses for a given task.
1258+ The default set of attributes returned in the dictionary can be found at graphql_queries.task_output_fragment.
1259+ If you want to use your own `custom_return_attributes` string to identify what information you want back, you have to include the `id` and `timestamp` fields, everything else is optional.
1260+ """
1261+ query = f"""
1262+ query AllTaskResponses($task_display_id: Int!){{
1263+ response(order_by: {{id: asc}}, where: {{task:{{display_id: {{_eq: $task_display_id}}}}}}) {{
1264+ { custom_return_attributes if custom_return_attributes is not None else '...task_output_fragment' }
1265+ }}
1266+ }}
1267+ { graphql_queries .task_output_fragment if custom_return_attributes is None else '' }
1268+ """
1269+ initial = await mythic_utilities .graphql_post (
1270+ mythic = mythic , query = query , variables = {"task_display_id" : task_display_id }
1271+ )
1272+ subtaskIds = await get_all_subtask_ids (mythic = mythic , task_display_id = task_display_id , fetch_display_id_instead = True )
1273+ for subtask in subtaskIds :
1274+ subtaskOutput = await get_all_task_output_by_id (mythic = mythic , task_display_id = subtask )
1275+ for r in subtaskOutput :
1276+ initial ["response" ].append (r )
1277+ return initial ["response" ]
1278+
1279+
12111280async def subscribe_new_task_output (
12121281 mythic : mythic_classes .Mythic ,
12131282 timeout : int = None ,
@@ -2256,7 +2325,8 @@ async def create_saved_c2_instance(
22562325 }
22572326 """
22582327 resp = await mythic_utilities .graphql_post (mythic = mythic , query = mutation , variables = {
2259- "instance_name" : instance_name , "c2profile_id" : resp ["c2profile" ][0 ]["id" ], "c2_instance" : json .dumps (c2_parameters )
2328+ "instance_name" : instance_name , "c2profile_id" : resp ["c2profile" ][0 ]["id" ],
2329+ "c2_instance" : json .dumps (c2_parameters )
22602330 })
22612331 return resp ["create_c2_instance" ]
22622332
0 commit comments