| 313 | return skipped_abilities |
| 314 | |
| 315 | async def report(self, file_svc, data_svc, output=False): |
| 316 | try: |
| 317 | report = dict(name=self.name, host_group=[a.display for a in self.agents], |
| 318 | start=self.start.strftime(self.TIME_FORMAT), |
| 319 | steps=[], finish=self.finish, planner=self.planner.name, adversary=self.adversary.display, |
| 320 | jitter=self.jitter, objectives=self.objective.display, |
| 321 | facts=[f.display for f in await self.all_facts()]) |
| 322 | agents_steps = {a.paw: {'steps': []} for a in self.agents} |
| 323 | for step in self.chain: |
| 324 | step_report = dict(link_id=step.id, |
| 325 | ability_id=step.ability.ability_id, |
| 326 | command=self.decode_bytes(step.command), |
| 327 | plaintext_command=self.decode_bytes(step.plaintext_command), |
| 328 | delegated=step.decide.strftime(self.TIME_FORMAT), |
| 329 | run=step.finish, |
| 330 | status=step.status, |
| 331 | platform=step.executor.platform, |
| 332 | executor=step.executor.name, |
| 333 | pid=step.pid, |
| 334 | description=step.ability.description, |
| 335 | name=step.ability.name, |
| 336 | attack=dict(tactic=step.ability.tactic, |
| 337 | technique_name=step.ability.technique_name, |
| 338 | technique_id=step.ability.technique_id)) |
| 339 | if output and step.output: |
| 340 | results = self.decode_bytes(file_svc.read_result_file(step.unique)) |
| 341 | step_report['output'] = json.loads(results.replace('\\r\\n', '').replace('\\n', '')) |
| 342 | if step.agent_reported_time: |
| 343 | step_report['agent_reported_time'] = step.agent_reported_time.strftime(self.TIME_FORMAT) |
| 344 | agents_steps[step.paw]['steps'].append(step_report) |
| 345 | report['steps'] = agents_steps |
| 346 | report['skipped_abilities'] = await self.get_skipped_abilities_by_agent(data_svc) |
| 347 | return report |
| 348 | except Exception: |
| 349 | logging.error('Error saving operation report (%s)' % self.name, exc_info=True) |
| 350 | |
| 351 | async def event_logs(self, file_svc, data_svc, output=False): |
| 352 | # Ignore discarded / high visibility links that did not actually run. |