From f4b3a331d675487db8bcf1423095e4d44edb9361 Mon Sep 17 00:00:00 2001 From: Dimitris Karakostas Date: Sun, 10 Dec 2017 13:45:07 +0000 Subject: [PATCH 1/5] Make huffman, method, alignment Round fields --- backend/breach/models/round.py | 39 ++++++++++++----------- backend/breach/strategy.py | 18 +++++++---- backend/breach/tests/test_backtracking.py | 1 + 3 files changed, 32 insertions(+), 26 deletions(-) diff --git a/backend/breach/models/round.py b/backend/breach/models/round.py index 7229c6dd..7600d4ef 100644 --- a/backend/breach/models/round.py +++ b/backend/breach/models/round.py @@ -2,6 +2,7 @@ from django.db import models from django.core.exceptions import ValidationError from breach.analyzer import decide_next_world_state +from breach.models import Target from itertools import groupby @@ -9,26 +10,8 @@ class Round(models.Model): class Meta: unique_together = (('victim', 'index'),) - def check_block_align(self): - try: - return self.block_align - except AttributeError: - self.block_align = self.victim.target.block_align - return self.block_align - - def check_huffman_pool(self): - try: - return self.huffman_pool - except AttributeError: - self.huffman_pool = self.victim.target.huffman_pool - return self.huffman_pool - def get_method(self): - try: - return self.method - except AttributeError: - self.method = self.victim.target.method - return self.method + return self.method def clean(self): if not self.knownsecret.startswith(self.victim.target.prefix): @@ -129,3 +112,21 @@ def fetch_per_batch_info(self): default=1.0, help_text='Accumulated probability of current round\'s given knownsecret. ' ) + + method = models.IntegerField( + default=Target.SERIAL, + choices=Target.METHOD_CHOICES, + help_text='Method of building candidate samplesets.' + ) + + block_align = models.BooleanField( + default=True, + help_text=('Whether to use block alignment or not, in case ' + 'maxreflectionlength does not allow it') + ) + + huffman_pool = models.BooleanField( + default=True, + help_text=('Whether to use Huffman pool or not, in case ' + 'maxreflectionlength does not allow it') + ) diff --git a/backend/breach/strategy.py b/backend/breach/strategy.py index 6b53b815..c5638a12 100644 --- a/backend/breach/strategy.py +++ b/backend/breach/strategy.py @@ -145,7 +145,7 @@ def _reflection(self, alphabet): '' ] - if self._round.check_huffman_pool(): + if self._round.huffman_pool: # Huffman complement indicates the knownalphabet symbols that are not currently being tested huffman_complement = set(self._round.knownalphabet) - set(alphabet) @@ -349,15 +349,16 @@ def _get_first_reflection(): return while len(_get_first_reflection()) > self._round.victim.target.maxreflectionlength: - if self._round.get_method() == Target.DIVIDE_CONQUER: - self._round.victim.target.method = Target.SERIAL - self._round.victim.target.save() + if self._round.method == Target.DIVIDE_CONQUER: + self._round.method = Target.SERIAL + self._round.save() logger.info('Divide & conquer method cannot be used, falling back to serial.') - elif self._round.check_huffman_pool(): + elif self._round.huffman_pool: self._round.huffman_pool = False self._round.save() logger.info('Huffman pool cannot be used, removing it.') elif self._round.check_block_align(): + elif self._round.block_align: self._round.block_align = False self._round.save() logger.info('Block alignment cannot be used, removing it.') @@ -391,7 +392,10 @@ def _create_round(self, state): amount=self._victim.target.samplesize, knownalphabet=state['knownalphabet'], knownsecret=state['knownsecret'], - accumulated_probability=prob + accumulated_probability=prob, + huffman_pool=self._victim.target.huffman_pool, + block_align=self._victim.target.block_align, + method=self._victim.target.method ) next_round.save() self._round = next_round @@ -423,7 +427,7 @@ def _create_round_samplesets(self): candidate_alphabets = self._build_candidates(state) alignmentalphabet = '' - if self._round.check_block_align(): + if self._round.block_align: alignmentalphabet = list(self._round.victim.target.alignmentalphabet) random.shuffle(alignmentalphabet) alignmentalphabet = ''.join(alignmentalphabet) diff --git a/backend/breach/tests/test_backtracking.py b/backend/breach/tests/test_backtracking.py index d73427dc..b603f58f 100644 --- a/backend/breach/tests/test_backtracking.py +++ b/backend/breach/tests/test_backtracking.py @@ -39,6 +39,7 @@ def test_create_multiple_branches(self, Sniffer): amount=1, knownsecret='branchsecret', knownalphabet='012', + method=BACKTRACKING ) SampleSet.objects.create( From 72e3d7b30f4509fd407531de0639ec5b49082fc7 Mon Sep 17 00:00:00 2001 From: Dimitris Karakostas Date: Sun, 10 Dec 2017 13:45:31 +0000 Subject: [PATCH 2/5] Add Round fields migration --- .../migrations/0027_auto_20171210_1343.py | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 backend/breach/migrations/0027_auto_20171210_1343.py diff --git a/backend/breach/migrations/0027_auto_20171210_1343.py b/backend/breach/migrations/0027_auto_20171210_1343.py new file mode 100644 index 00000000..7c6b521d --- /dev/null +++ b/backend/breach/migrations/0027_auto_20171210_1343.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.2 on 2017-12-10 13:43 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('breach', '0026_auto_20171208_1153'), + ] + + operations = [ + migrations.AddField( + model_name='round', + name='block_align', + field=models.BooleanField(default=True, help_text='Whether to use block alignment or not, in case maxreflectionlength does not allow it'), + ), + migrations.AddField( + model_name='round', + name='huffman_pool', + field=models.BooleanField(default=True, help_text='Whether to use Huffman pool or not, in case maxreflectionlength does not allow it'), + ), + migrations.AddField( + model_name='round', + name='method', + field=models.IntegerField(choices=[(1, 'serial'), (2, 'divide&conquer'), (3, 'backtracking')], default=1, help_text='Method of building candidate samplesets.'), + ), + ] From e526e0603544ac092b55511bdaaed78c6cfd0421 Mon Sep 17 00:00:00 2001 From: Dimitris Karakostas Date: Sun, 10 Dec 2017 13:45:52 +0000 Subject: [PATCH 3/5] Remove block alignment test on maxreflection downgrading --- backend/breach/strategy.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/backend/breach/strategy.py b/backend/breach/strategy.py index c5638a12..9464e22b 100644 --- a/backend/breach/strategy.py +++ b/backend/breach/strategy.py @@ -357,11 +357,6 @@ def _get_first_reflection(): self._round.huffman_pool = False self._round.save() logger.info('Huffman pool cannot be used, removing it.') - elif self._round.check_block_align(): - elif self._round.block_align: - self._round.block_align = False - self._round.save() - logger.info('Block alignment cannot be used, removing it.') else: raise MaxReflectionLengthError('Cannot attack, specified maxreflectionlength is too short') From 84bf7fbfc0fb4db1d1f20fda34dede2d71e89de9 Mon Sep 17 00:00:00 2001 From: Dimitris Karakostas Date: Sun, 10 Dec 2017 13:46:06 +0000 Subject: [PATCH 4/5] Add max reflection tests --- backend/breach/tests/test_strategy.py | 69 +++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/backend/breach/tests/test_strategy.py b/backend/breach/tests/test_strategy.py index 40d921c7..20141ff1 100644 --- a/backend/breach/tests/test_strategy.py +++ b/backend/breach/tests/test_strategy.py @@ -212,3 +212,72 @@ def test_divide_and_conquer(self, Sniffer): 'https://di.uoa.gr/?breach=^1^0^test3^test2^' ) strategy1._mark_current_work_completed() + + @patch('breach.strategy.Sniffer') + def test_downgrade_to_serial(self, Sniffer): + target = Target.objects.create( + name='maxreflection', + endpoint='https://test.com/?breach=%s', + prefix='test', + alphabet='0123', + maxreflectionlength=16, + method=2 + ) + + victim = Victim.objects.create( + target=target, + sourceip='192.168.10.141', + snifferendpoint='http://localhost/' + ) + + strategy = Strategy(victim) + work = strategy.get_work() + self.assertEqual(work, {'url': u'https://test.com/?breach=^1^3^2^test0^', 'amount': 64, 'timeout': 0, 'alignmentalphabet': u''}) + + target.delete() + + @patch('breach.strategy.Sniffer') + def test_downgrade_huffman(self, Sniffer): + target = Target.objects.create( + name='maxreflection', + endpoint='https://test.com/?breach=%s', + prefix='test', + alphabet='0123', + maxreflectionlength=12, + method=2 + ) + + victim = Victim.objects.create( + target=target, + sourceip='192.168.10.141', + snifferendpoint='http://localhost/' + ) + + strategy = Strategy(victim) + work = strategy.get_work() + self.assertEqual(work, {'url': u'https://test.com/?breach=^test0^', 'amount': 64, 'timeout': 0, 'alignmentalphabet': u''}) + + target.delete() + + @patch('breach.strategy.Sniffer') + def test_maxreflectionerror(self, Sniffer): + target = Target.objects.create( + name='maxreflection', + endpoint='https://test.com/?breach=%s', + prefix='test', + alphabet='0123', + maxreflectionlength=6, + method=2 + ) + + victim = Victim.objects.create( + target=target, + sourceip='192.168.10.141', + snifferendpoint='http://localhost/' + ) + + strategy = Strategy(victim) + work = strategy.get_work() + self.assertEqual(work, {}) + + target.delete() From 352d0506a8233b31195678bbd90953c88948990c Mon Sep 17 00:00:00 2001 From: Dimitris Karakostas Date: Sun, 10 Dec 2017 13:54:59 +0000 Subject: [PATCH 5/5] Remove unnecessary Round test --- backend/breach/tests/test_models.py | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/backend/breach/tests/test_models.py b/backend/breach/tests/test_models.py index 842b0c0d..df32f9e8 100644 --- a/backend/breach/tests/test_models.py +++ b/backend/breach/tests/test_models.py @@ -1,5 +1,5 @@ from django.test import TestCase -from breach.models import Target, Victim, Round +from breach.models import Target, Victim class ModelTestCase(TestCase): @@ -35,26 +35,3 @@ def test_victim(self): self.assertEqual(self.victim.realtimeurl, 'http://localhost:3031') self.assertEqual(self.victim.snifferendpoint, 'http://127.0.0.1:9000') self.assertEqual(self.victim.calibration_wait, 0.0) - - def test_round(self): - round1 = Round.objects.create( - victim=self.victim, - knownalphabet='01' - ) - - self.assertTrue(round1.check_block_align()) - round1.block_align = False - self.assertTrue(round1.check_huffman_pool()) - round1.huffman_pool = False - self.assertEqual(round1.get_method(), 1) - round1.method = 2 - - round2 = Round.objects.create( - victim=self.victim, - knownalphabet='01', - index=2 - ) - - self.assertTrue(round2.check_block_align()) - self.assertTrue(round2.check_huffman_pool()) - self.assertEqual(round2.get_method(), 1)