Skip to content

Commit 86360bc

Browse files
authored
Merge branch 'master' into handle-user-payloads
2 parents eb87513 + cc93a0f commit 86360bc

7 files changed

Lines changed: 33 additions & 70 deletions

File tree

app/api/rest_api.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ async def rest_core(self, request):
8989
operation_report=lambda d: self.rest_svc.display_operation_report(d),
9090
result=lambda d: self.rest_svc.display_result(d),
9191
contact=lambda d: self.rest_svc.download_contact_report(d),
92-
configuration=lambda d: self.rest_svc.update_config(d),
9392
link=lambda d: self.rest_svc.get_potential_links(**d),
9493
operation=lambda d: self.rest_svc.update_operation(**d),
9594
task=lambda d: self.rest_svc.task_agent_with_ability(**d),
@@ -103,8 +102,14 @@ async def rest_core(self, request):
103102
return web.json_response(await options[request.method][index](data))
104103
except ma.ValidationError as e:
105104
raise web.HTTPBadRequest(content_type='application/json', text=json.dumps(e.messages))
105+
except TypeError as e:
106+
self.log.error(repr(e), exc_info=True)
107+
error_msg = dict(error='400: Bad Request')
108+
raise web.HTTPBadRequest(text=json.dumps(error_msg), content_type='application/json')
106109
except Exception as e:
107110
self.log.error(repr(e), exc_info=True)
111+
error_msg = dict(error='500: Internal Server Error')
112+
raise web.HTTPInternalServerError(text=json.dumps(error_msg), content_type='application/json')
108113

109114
@check_authorization
110115
async def rest_core_info(self, request):

app/service/interfaces/i_rest_svc.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,6 @@ def get_link_pin(self, json_data):
107107
def construct_agents_for_group(self, group):
108108
raise NotImplementedError
109109

110-
@abc.abstractmethod
111-
def update_config(self, data):
112-
raise NotImplementedError
113-
114110
@abc.abstractmethod
115111
def update_operation(self, op_id, state, autonomous):
116112
raise NotImplementedError

app/service/rest_svc.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -269,16 +269,6 @@ async def construct_agents_for_group(self, group):
269269
return await self.get_service('data_svc').locate('agents', match=dict(group=group))
270270
return await self.get_service('data_svc').locate('agents')
271271

272-
async def update_config(self, data):
273-
if data.get('prop') == 'plugin':
274-
enabled_plugins = self.get_config('plugins')
275-
new_plugin = data.get('value')
276-
if new_plugin not in enabled_plugins:
277-
enabled_plugins.append(new_plugin)
278-
elif data.get('prop') != 'requirements': # Prevent users from editing requirements via API.
279-
self.set_config('main', data.get('prop'), data.get('value'))
280-
return self.get_config()
281-
282272
async def update_operation(self, op_id, state=None, autonomous=None, obfuscator=None):
283273
async def validate(op):
284274
try:

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ ldap3==2.9.1
1818
pyasn1==0.6.3
1919
reportlab==4.0.4 # debrief
2020
rich==13.7.0
21-
lxml==6.0.2 # debrief
21+
lxml==6.1.0 # debrief
2222
svglib==1.5.1 # debrief
2323
Markdown==3.8.1 # training
2424
dnspython==2.6.1

tests/objects/test_link.py

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,12 @@ def test_link_eq(self, ability, executor):
4141
test_executor = executor(name='psh', platform='windows')
4242
test_ability = ability(ability_id='123', executors=[test_executor])
4343
fact = Fact(trait='remote.host.fqdn', value='dc')
44-
test_link = Link(command='sc.exe \\dc create sandsvc binpath= "s4ndc4t.exe -originLinkID 111111"',
44+
# sc.exe \\dc create sandsvc binpath= "s4ndc4t.exe -originLinkID 111111"
45+
test_link = Link(command='c2MuZXhlIFxcZGMgY3JlYXRlIHNhbmRzdmMgYmlucGF0aD0gInM0bmRjNHQuZXhlIC1vcmlnaW5MaW5rSUQgMTExMTExIg==',
4546
paw='123456', ability=test_ability, id=111111, executor=test_executor)
4647
test_link.used = [fact]
47-
test_link2 = Link(command='sc.exe \\dc create sandsvc binpath= "s4ndc4t.exe -originLinkID 222222"',
48+
# sc.exe \\dc create sandsvc binpath= "s4ndc4t.exe -originLinkID 222222"
49+
test_link2 = Link(command='c2MuZXhlIFxcZGMgY3JlYXRlIHNhbmRzdmMgYmlucGF0aD0gInM0bmRjNHQuZXhlIC1vcmlnaW5MaW5rSUQgMjIyMjIyIg==',
4850
paw='123456', ability=test_ability, id=222222, executor=test_executor)
4951
test_link2.used = [fact]
5052
assert test_link == test_link2
@@ -54,31 +56,36 @@ def test_link_neq(self, ability, executor):
5456
test_ability = ability(ability_id='123', executors=[test_executor])
5557
fact_a = Fact(trait='host.user.name', value='a')
5658
fact_b = Fact(trait='host.user.name', value='b')
57-
test_link_a = Link(command='net user a', paw='123456', ability=test_ability, id=111111, executor=test_executor)
59+
# net user a
60+
test_link_a = Link(command='bmV0IHVzZXIgYQ==', paw='123456', ability=test_ability, id=111111, executor=test_executor)
5861
test_link_a.used = [fact_a]
59-
test_link_b = Link(command='net user b', paw='123456', ability=test_ability, id=222222, executor=test_executor)
62+
# net user b
63+
test_link_b = Link(command='bmV0IHVzZXIgYg==', paw='123456', ability=test_ability, id=222222, executor=test_executor)
6064
test_link_b.used = [fact_b]
6165
assert test_link_a != test_link_b
6266

6367
@mock.patch.object(Link, '_emit_status_change_event')
6468
def test_no_status_change_event_on_instantiation(self, mock_emit_status_change_method, ability, executor):
6569
executor = executor('psh', 'windows')
6670
ability = ability(executor=executor)
67-
Link(command='net user a', paw='123456', ability=ability, executor=executor)
71+
# net user a
72+
Link(command='bmV0IHVzZXIgYQ==', paw='123456', ability=ability, executor=executor)
6873
mock_emit_status_change_method.assert_not_called()
6974

7075
@mock.patch.object(Link, '_emit_status_change_event')
7176
def test_status_change_event_fired_on_status_change(self, mock_emit_status_change_method, ability, executor):
7277
executor = executor('psh', 'windows')
7378
ability = ability(executor=executor)
74-
link = Link(command='net user a', paw='123456', ability=ability, executor=executor, status=-3)
79+
# net user a
80+
link = Link(command='bmV0IHVzZXIgYQ==', paw='123456', ability=ability, executor=executor, status=-3)
7581
link.status = -5
7682
mock_emit_status_change_method.assert_called_with(from_status=-3, to_status=-5)
7783

7884
def test_emit_status_change_event(self, event_loop, fake_event_svc, ability, executor):
7985
executor = executor('psh', 'windows')
8086
ability = ability(executor=executor)
81-
link = Link(command='net user a', paw='123456', ability=ability, executor=executor, status=-3)
87+
# net user a
88+
link = Link(command='bmV0IHVzZXIgYQ==', paw='123456', ability=ability, executor=executor, status=-3)
8289
fake_event_svc.reset()
8390

8491
event_loop.run_until_complete(
@@ -99,7 +106,8 @@ def test_emit_status_change_event(self, event_loop, fake_event_svc, ability, exe
99106
def test_link_agent_reported_time_not_present_when_none_roundtrip(self, ability, executor):
100107
test_executor = executor(name='psh', platform='windows')
101108
test_ability = ability(ability_id='123')
102-
test_link = Link(command='sc.exe \\dc create sandsvc binpath= "s4ndc4t.exe -originLinkID 111111"',
109+
# sc.exe \\dc create sandsvc binpath= "s4ndc4t.exe -originLinkID 111111"
110+
test_link = Link(command='c2MuZXhlIFxcZGMgY3JlYXRlIHNhbmRzdmMgYmlucGF0aD0gInM0bmRjNHQuZXhlIC1vcmlnaW5MaW5rSUQgMTExMTExIg==',
103111
paw='123456', ability=test_ability, executor=test_executor, id=111111)
104112
serialized_link = test_link.display
105113
loaded_link = Link.load(serialized_link)
@@ -111,7 +119,8 @@ def test_link_agent_reported_time_present_when_set_roundtrip(self, ability, exec
111119
agent_reported_time = '2021-02-23T11:50:16Z'
112120
test_executor = executor(name='psh', platform='windows')
113121
test_ability = ability(ability_id='123')
114-
test_link = Link(command='sc.exe \\dc create sandsvc binpath= "s4ndc4t.exe -originLinkID 111111"',
122+
# sc.exe \\dc create sandsvc binpath= "s4ndc4t.exe -originLinkID 111111"
123+
test_link = Link(command='c2MuZXhlIFxcZGMgY3JlYXRlIHNhbmRzdmMgYmlucGF0aD0gInM0bmRjNHQuZXhlIC1vcmlnaW5MaW5rSUQgMTExMTExIg==',
115124
paw='123456', ability=test_ability, executor=test_executor, id=111111,
116125
agent_reported_time=BaseService.get_timestamp_from_string(agent_reported_time))
117126
serialized_link = test_link.display
@@ -126,7 +135,8 @@ def test_link_knowledge_svc_synchronization(self, event_loop, executor, ability,
126135
fact = Fact(trait='remote.host.fqdn', value='dc')
127136
fact2 = Fact(trait='domain.user.name', value='Bob')
128137
relationship = Relationship(source=fact, edge='has_admin', target=fact2)
129-
test_link = Link(command='echo "this was a triumph"',
138+
# echo "this was a triumph"
139+
test_link = Link(command='ZWNobyAidGhpcyB3YXMgYSB0cml1bXBoIg==',
130140
paw='123456', ability=test_ability, id=111111, executor=test_executor)
131141
event_loop.run_until_complete(test_link.create_relationships([relationship], None))
132142
checkable = [(x.trait, x.value) for x in test_link.facts]
@@ -144,16 +154,17 @@ def test_create_relationship_source_fact(self, event_loop, ability, executor, op
144154
fact1 = Fact(trait='remote.host.fqdn', value='dc')
145155
fact2 = Fact(trait='domain.user.name', value='Bob')
146156
relationship = Relationship(source=fact1, edge='has_admin', target=fact2)
147-
link1 = Link(command='echo "Bob"', paw='123456', ability=test_ability, id='111111', executor=test_executor)
157+
# echo "Bob"
158+
link1 = Link(command='ZWNobyAiQm9iIg==', paw='123456', ability=test_ability, id='111111', executor=test_executor)
148159
operation = operation(name='test-op', agents=[],
149160
adversary=Adversary(name='sample', adversary_id='XYZ', atomic_ordering=[],
150161
description='test'),
151162
source=Source(id='test-source', facts=[fact1]))
152163
event_loop.run_until_complete(data_svc.store(operation.source))
153164
event_loop.run_until_complete(operation._init_source())
154165
event_loop.run_until_complete(link1.create_relationships([relationship], operation))
155-
156-
link2 = Link(command='echo "Bob"', paw='789100', ability=test_ability, id='222222', executor=test_executor)
166+
# echo "Bob"
167+
link2 = Link(command='ZWNobyAiQm9iIg==', paw='789100', ability=test_ability, id='222222', executor=test_executor)
157168
event_loop.run_until_complete(link2.create_relationships([relationship], operation))
158169

159170
fact_store_operation_source = event_loop.run_until_complete(knowledge_svc.get_facts(dict(source=operation.source.id)))
@@ -168,7 +179,8 @@ def test_save_discover_seeded_fact_not_in_command(self, event_loop, ability, exe
168179
fact1 = Fact(trait='remote.host.fqdn', value='dc')
169180
fact2 = Fact(trait='domain.user.name', value='Bob')
170181
relationship = Relationship(source=fact1, edge='has_user', target=fact2)
171-
link = Link(command='net user', paw='123456', ability=test_ability, id='111111', executor=test_executor)
182+
# net user
183+
link = Link(command='bmV0IHVzZXI=', paw='123456', ability=test_ability, id='111111', executor=test_executor)
172184
operation = operation(name='test-op', agents=[],
173185
adversary=Adversary(name='sample', adversary_id='XYZ', atomic_ordering=[],
174186
description='test'),

tests/services/test_rest_svc.py

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -125,28 +125,6 @@ def test_delete_operation(self, event_loop, rest_svc, data_svc):
125125
event_loop.run_until_complete(internal_rest_svc.delete_operation(delete_criteria))
126126
assert event_loop.run_until_complete(data_svc.locate('operations', match=dict(id=operation_id))) == []
127127

128-
def test_update_config(self, event_loop, data_svc, rest_svc):
129-
internal_rest_svc = rest_svc(event_loop)
130-
# check that an ability reflects the value in app. property
131-
pre_ability = event_loop.run_until_complete(data_svc.locate('abilities', dict(ability_id='123')))
132-
assert '0.0.0.0' == BaseWorld.get_config('app.contact.http')
133-
assert 'curl 0.0.0.0' == next(pre_ability[0].executors).test
134-
135-
# update property
136-
event_loop.run_until_complete(internal_rest_svc.update_config(data=dict(prop='app.contact.http', value='127.0.0.1')))
137-
138-
# verify ability reflects new value
139-
post_ability = event_loop.run_until_complete(data_svc.locate('abilities', dict(ability_id='123')))
140-
assert '127.0.0.1' == BaseWorld.get_config('app.contact.http')
141-
assert 'curl 127.0.0.1' == next(post_ability[0].executors).test
142-
143-
def test_update_config_plugin(self, event_loop, rest_svc):
144-
internal_rest_svc = rest_svc(event_loop)
145-
# update plugin property
146-
assert ['sandcat', 'stockpile'] == BaseWorld.get_config('plugins')
147-
event_loop.run_until_complete(internal_rest_svc.update_config(data=dict(prop='plugin', value='ssl')))
148-
assert ['sandcat', 'stockpile', 'ssl'] == BaseWorld.get_config('plugins')
149-
150128
def test_create_operation(self, event_loop, rest_svc, data_svc):
151129
want = {'name': 'Test',
152130
'adversary': {'description': 'an empty adversary profile', 'name': 'ad-hoc', 'adversary_id': 'ad-hoc',

tests/web_server/test_core_endpoints.py

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -110,24 +110,6 @@ async def test_invalid_request(aiohttp_client, authorized_cookies, sample_agent)
110110
assert messages == dict(sleep_min=['Not a valid integer.'])
111111

112112

113-
async def test_command_overwrite_failure(aiohttp_client, authorized_cookies):
114-
resp = await aiohttp_client.post('/api/rest',
115-
cookies=authorized_cookies,
116-
json=dict(index='configuration',
117-
prop='requirements',
118-
value=dict(go=dict(command='this should not get written',
119-
type='installed program',
120-
version='1.11',),
121-
python=dict(attr='version',
122-
module='sys',
123-
type='python_module',
124-
version='3.11.0'))))
125-
126-
assert resp.status == HTTPStatus.OK
127-
config_dict = await resp.json()
128-
assert config_dict.get('requirements', dict()).get('go', dict()).get('command') == 'go version'
129-
130-
131113
async def test_custom_rejecting_login_handler(aiohttp_client):
132114
class RejectAllLoginHandler(LoginHandlerInterface):
133115
def __init__(self, services):

0 commit comments

Comments
 (0)