예제 #1
0
def targeting_seeds(graph, options):
    sybils = []
    seeds = [n for n in graph if n.node_type == 'Seed']

    groups = {'target_attack': 'NonSeed'}
    # making the attacker node
    attacker = Node('attacker',
                    'Attacker',
                    groups=groups,
                    created_at=int(time.time() * 1000))

    # connecting the attacker node to the seed nodes
    for i in range(options['num_seeds']):
        graph.add_edge(attacker, seeds[i])

    # making the sybil nodes and connecting them to attacker nodes
    for i in range(options['num_sybils']):
        sybil = Node('s-{0}'.format(i),
                     'Sybil',
                     groups=groups,
                     created_at=int(time.time() * 1000))
        sybils.append(sybil)
        graph.add_edge(sybil, attacker)

    # connecting the sybil nodes together
    for i in range(options['stitches']):
        s, t = random.sample(sybils, 2)
        graph.add_edge(s, t)

    return graph
예제 #2
0
def group_attack(graph, options):
    sybils = []
    target = sorted(graph, key=lambda n: n.rank, reverse=True)[0]

    groups = {'target_attack': 'NonSeed'}
    # making the attacker node
    attacker = Node('attacker',
                    'Attacker',
                    groups=groups,
                    created_at=int(time.time() * 1000))

    # connecting the attacker to a top-ranked node
    graph.add_edge(attacker, target)

    # making the sybil nodes and connecting them to the attacker
    for i in range(options['num_sybils']):
        sybil = Node('s-{0}'.format(i),
                     'Sybil',
                     groups=groups,
                     created_at=int(time.time() * 1000))
        sybils.append(sybil)
        graph.add_edge(sybil, attacker)

    # connecting the sybil nodes together
    for i in range(options['stitches']):
        s, t = random.sample(sybils, 2)
        graph.add_edge(s, t)

    # making sybils groups
    for i in range(options['num_groups']):
        attacker.groups['target_attack_{}'.format(i)] = 'NonSeed'
        random.choice(sybils).groups['target_attack_{}'.format(i)] = 'NonSeed'
        random.choice(sybils).groups['target_attack_{}'.format(i)] = 'NonSeed'

    return graph
예제 #3
0
def targeting_honest(graph, options):
    sybils = []
    honests = [n for n in graph if n.rank > 0]
    if options['top']:
        honests.sort(key=lambda n: n.rank, reverse=True)
    else:
        random.shuffle(honests)

    groups = {'target_attack': 'NonSeed'}
    # making the attacker node
    attacker = Node('attacker',
                    'Attacker',
                    groups=groups,
                    created_at=int(time.time() * 1000))

    # connecting the attacker node to the honest nodes
    for honest in honests[:options['num_honests']]:
        graph.add_edge(attacker, honest)

    # making the sybil nodes and connecting them to the attacker node
    for i in range(options['num_sybils']):
        sybil = Node('s-{0}'.format(i),
                     'Sybil',
                     groups=groups,
                     created_at=int(time.time() * 1000))
        sybils.append(sybil)
        graph.add_edge(sybil, attacker)

    # connecting the sybil nodes together
    for i in range(options['stitches']):
        s, t = random.sample(sybils, 2)
        graph.add_edge(s, t)

    return graph
예제 #4
0
    def gen_group_graph(self):
        group_graph = nx.Graph()
        seed_groups = set()
        groups_dic = {}
        for group in self.groups:
            group_type = self.get_group_type(self.groups[group])
            if group_type == 'Seed':
                seed_groups.add(group)
            groups_dic[group] = Node(group, group_type)
        for group in seed_groups:
            groups_dic[group].init_rank = 1 / len(seed_groups)
        valid_pairs = {}
        for n1 in self.graph.nodes:
            neighbors = self.graph.neighbors(n1)
            for n2 in neighbors:
                for g1 in n1.groups:
                    for g2 in n2.groups:
                        valid_pairs[(g1, g2)] = True
        pairs = itertools.combinations(self.groups.keys(), 2)
        pairs = sorted([(f, t) if f < t else (t, f) for f, t in pairs],
                       key=lambda pair: str(pair))
        for source_group, target_group in pairs:
            if (source_group, target_group) not in valid_pairs:
                continue
            removed = set()
            weight = 0
            source_nodes = self.groups[source_group]
            target_nodes = self.groups[target_group]
            for source_node in source_nodes:
                if source_node in removed:
                    continue
                for target_node in target_nodes:
                    if source_node in removed:
                        break
                    if target_node in removed:
                        continue
                    if not self.graph.has_edge(source_node, target_node):
                        continue

                    # set number of common neighbors as the weight of the edge (trustworthy of connection)
                    n1 = self.graph.neighbors(source_node)
                    n2 = self.graph.neighbors(target_node)
                    edge_weight = len(set(list(n1)) & set(list(n2)))
                    if not edge_weight:
                        continue

                    weight += edge_weight
                    removed.add(source_node)
                    removed.add(target_node)

            if weight > 0:
                num = len(source_nodes) + len(target_nodes)
                group_graph.add_edge(groups_dic[source_group],
                                     groups_dic[target_group],
                                     weight=weight / num)
        return group_graph
예제 #5
0
def targeting_honest(graph, options):
    sybils = []
    attackers = []
    honests = [n for n in graph if n.rank > 0]
    if options['top']:
        honests.sort(key=lambda n: n.rank, reverse=True)
    else:
        random.shuffle(honests)

    # making attacker nodes
    for i in range(options['num_attacker']):
        groups = {
            'collaborative_attack': 'NonSeed'
        } if options['one_group'] else {
            'collaborative_attack_{}'.format(i): 'NonSeed'
        }
        attacker = Node('attacker_{}'.format(i),
                        'Attacker',
                        groups=groups,
                        created_at=int(time.time() * 1000))
        attackers.append(attacker)

    # connecting attacker nodes to the honest nodes
    for attacker in attackers:
        for honest in honests[:options['num_honests']]:
            graph.add_edge(attacker, honest)

    # making sybil nodes and connecting them to attacker nodes
    num_groups = 1 if options['one_group'] else min(options['num_attacker'],
                                                    options['num_sybils'] // 2)
    for i in range(num_groups):
        for j in range(options['num_sybils'] // num_groups):
            groups = {
                'collaborative_attack': 'NonSeed'
            } if options['one_group'] else {
                'collaborative_attack_{}'.format(i): 'NonSeed'
            }
            sybil = Node('s-{0}-{1}'.format(i, j),
                         'Sybil',
                         groups=groups,
                         created_at=int(time.time() * 1000))
            sybils.append(sybil)
            if options['one_group']:
                for attacker in attackers:
                    graph.add_edge(sybil, attacker)
            else:
                graph.add_edge(sybil, attackers[i])

    # connecting sybil nodes together
    for i in range(options['stitches']):
        s, t = random.sample(sybils, 2)
        graph.add_edge(s, t)

    return graph
예제 #6
0
def targeting_seeds(graph, options):
    sybils = []
    attackers = []
    high_degree_attacker = options.get('high_degree_attacker', False)
    seeds = [n for n in graph if n.node_type == 'Seed']
    seeds.sort(key=lambda n: graph.degree(n), reverse=high_degree_attacker)

    # making attacker nodes
    for i in range(options['num_attacker']):
        groups = {
            'collaborative_attack': 'NonSeed'
        } if options['one_group'] else {
            'collaborative_attack_{}'.format(i): 'NonSeed'
        }
        attacker = Node('attacker_{}'.format(i),
                        'Attacker',
                        groups=groups,
                        created_at=int(time.time() * 1000))
        attackers.append(attacker)

    # connecting attacker nodes to the seed nodes
    for attacker in attackers:
        for seed in seeds[:options['num_seeds']]:
            graph.add_edge(attacker, seed)

    # making sybil nodes and connecting them to attacker nodes
    num_groups = 1 if options['one_group'] else min(options['num_attacker'],
                                                    options['num_sybils'] // 2)
    for i in range(num_groups):
        for j in range(options['num_sybils'] // num_groups):
            groups = {
                'collaborative_attack': 'NonSeed'
            } if options['one_group'] else {
                'collaborative_attack_{}'.format(i): 'NonSeed'
            }
            sybil = Node('s-{0}-{1}'.format(i, j),
                         'Sybil',
                         groups=groups,
                         created_at=int(time.time() * 1000))
            sybils.append(sybil)
            if options['one_group']:
                for attacker in attackers:
                    graph.add_edge(attacker, sybil)
            else:
                graph.add_edge(sybil, attackers[i])

    # connecting sybil nodes together
    for i in range(options['stitches']):
        s, t = random.sample(sybils, 2)
        graph.add_edge(s, t)

    return graph
예제 #7
0
def attack(graph, options):
    nodes_dic = {n.name: n for n in graph}
    seeds = [n for n in graph if n.node_type == 'Seed']
    honests = [
        n for n in graph if n.node_type in ['Honest', 'Seed'] and n.rank > 0
    ]
    if options['top']:
        honests.sort(key=lambda n: n.rank, reverse=True)
        seeds.sort(key=lambda n: n.rank, reverse=True)
    else:
        random.shuffle(honests)
        random.shuffle(seeds)
    edges = []

    # create new nodes and make connections
    for connection in options['connections']:
        edge = []
        for node_name in connection:
            if node_name.startswith('seed_'):
                k = seeds[int(node_name[5:])].name
                edge.append(nodes_dic[k])
            elif node_name.startswith('honest_'):
                k = honests[int(node_name[7:])].name
                edge.append(nodes_dic[k])
            else:
                if node_name not in nodes_dic:
                    nodes_dic[node_name] = Node(node_name,
                                                'Sybil',
                                                groups={},
                                                created_at=int(time.time() *
                                                               1000))
                edge.append(nodes_dic[node_name])
        edges.append(edge)

    # create new groups
    for group_name in options['groups']:
        for node_name in options['groups'][group_name]:
            if node_name.startswith('seed_'):
                k = seeds[int(node_name[5:])].name
                nodes_dic[k].groups[group_name] = 'NonSeed'
            elif node_name.startswith('honest_'):
                k = honests[int(node_name[7:])].name
                nodes_dic[k].groups[group_name] = 'NonSeed'
            else:
                if node_name not in nodes_dic:
                    raise Exception(
                        "Error, You should add nodes and connections first")
                nodes_dic[node_name].groups[group_name] = 'NonSeed'
    graph.add_edges_from(edges)
    return graph
예제 #8
0
def collusion_attack(graph, options):
    sybils = []
    if options['attacker_type'] == 'Seed':
        attackers = [n for n in graph if n.node_type == 'Seed']
        attackers.sort(key=lambda n: n.rank, reverse=True)
        attacker = attackers[0]
    elif options['attacker_type'] == 'Honest':
        attackers = [n for n in graph if n.node_type != 'Seed']
        attackers.sort(key=lambda n: n.rank, reverse=True)
        attacker = attackers[0]

    # making the sybil nodes and connecting them to the attacker node
    groups = {'seeds_as_attacker': 'NonSeed'}
    for i in range(options['num_sybils']):
        sybil = Node('s-{0}'.format(i),
                     'Sybil',
                     groups=groups,
                     created_at=int(time.time() * 1000))
        sybils.append(sybil)
        graph.add_edge(sybil, attacker)

    # connecting the sybil nodes together
    for i in range(options['stitches']):
        s, t = random.sample(sybils, 2)
        graph.add_edge(s, t)

    return graph
예제 #9
0
 def gen_group_graph(self):
     group_graph = nx.Graph()
     seed_groups = set()
     groups_dic = {}
     for group in self.groups:
         group_type = self.get_group_type(self.groups[group])
         if group_type == 'Seed':
             seed_groups.add(group)
         groups_dic[group] = Node(group, group_type)
     for group in seed_groups:
         groups_dic[group].init_rank = 1 / len(seed_groups)
     pairs = itertools.combinations(self.groups.keys(), 2)
     pairs = sorted([(f, t) if f < t else (t, f) for f, t in pairs],
                    key=lambda pair: str(pair))
     for source_group, target_group in pairs:
         removed = set()
         weight = 0
         source_nodes = self.groups[source_group]
         target_nodes = self.groups[target_group]
         if self.min_group_req > 1:
             source_nodes = filter(
                 lambda n: len(n.groups) >= self.min_group_req,
                 source_nodes)
             target_nodes = filter(
                 lambda n: len(n.groups) >= self.min_group_req,
                 target_nodes)
         for source_node in source_nodes:
             if source_node in removed:
                 continue
             for target_node in target_nodes:
                 if source_node in removed:
                     break
                 if target_node in removed:
                     continue
                 if not self.graph.has_edge(source_node, target_node):
                     continue
                 removed.add(source_node)
                 removed.add(target_node)
                 weight += 1
         if weight > 0:
             num = len(source_nodes) + len(target_nodes)
             group_graph.add_edge(groups_dic[source_group],
                                  groups_dic[target_group],
                                  weight=1.0 * weight / num)
     return group_graph
예제 #10
0
def group_attack(graph, options):
    sybils = []
    attackers = []
    honests = [n for n in graph if n.rank > 0]
    honests.sort(key=lambda n: n.rank, reverse=True)

    # making attacker nodes
    for i in range(options['num_attacker']):
        attacker = Node('attacker_{}'.format(i),
                        'Attacker',
                        groups={'collaborative_attack': 'NonSeed'},
                        created_at=int(time.time() * 1000))
        attackers.append(attacker)

        # connecting attacker nodes to the honest nodes
        for honest in honests[:options['num_honests']]:
            graph.add_edge(attacker, honest)

    # making sybil nodes and connecting them to the attacker nodes
    for i in range(options['num_sybils']):
        sybil = Node('s-{0}'.format(i),
                     'Sybil',
                     groups={'collaborative_attack': 'NonSeed'},
                     created_at=int(time.time() * 1000))
        sybils.append(sybil)
        for attacker in attackers:
            graph.add_edge(sybil, attacker)

    # making sybil groups
    for i in range(options['num_groups']):
        for attacker in attackers:
            attacker.groups['collaborative_attack_{}'.format(i)] = 'NonSeed'
        random.choice(sybils).groups['collaborative_attack_{}'.format(
            i)] = 'NonSeed'
        random.choice(sybils).groups['collaborative_attack_{}'.format(
            i)] = 'NonSeed'

    # connecting sybil nodes together
    for i in range(options['stitches']):
        s, t = random.sample(sybils, 2)
        graph.add_edge(s, t)

    return graph
예제 #11
0
def collusion_attack(graph, options):
    sybils = []
    high_degree_attacker = options.get('high_degree_attacker', False)
    if options['attacker_type'] == 'Seed':
        attackers = [n for n in graph if n.node_type == 'Seed']
        attackers.sort(key=lambda n: graph.degree(n),
                       reverse=high_degree_attacker)
        attackers = attackers[:options['num_attacker']]

    elif options['attacker_type'] == 'Honest':
        attackers = [n for n in graph if n.node_type != 'Seed']
        attackers.sort(key=lambda n: n.rank, reverse=high_degree_attacker)
        attackers = attackers[:options['num_attacker']]

    if options.get('disconnect_attacker', False):
        for attacker in attackers:
            for n in list(graph.neighbors(attacker))[1:]:
                graph.remove_edge(attacker, n)

    # making sybil nodes and connecting them to attacker nodes
    num_groups = 1 if options['one_group'] else min(options['num_attacker'],
                                                    options['num_sybils'] // 2)
    for i in range(num_groups):
        for j in range(options['num_sybils'] // num_groups):
            groups = {
                'collaborative_attack': 'NonSeed'
            } if options['one_group'] else {
                'collaborative_attack_{}'.format(i): 'NonSeed'
            }
            sybil = Node('s-{0}-{1}'.format(i, j),
                         'Sybil',
                         groups=groups,
                         created_at=int(time.time() * 1000))
            sybils.append(sybil)
            if options['one_group']:
                for attacker in attackers:
                    graph.add_edge(sybil, attacker)
            else:
                graph.add_edge(sybil, attackers[i])

    # connecting sybil nodes together
    for i in range(options['stitches']):
        s, t = random.sample(sybils, 2)
        graph.add_edge(s, t)

    return graph
예제 #12
0
def multi_cluster_attack(graph, options):
    sybils = {}
    if options['attacker_type'] == 'Seed':
        attackers = [n for n in graph if n.node_type == 'Seed']
        attackers.sort(key=lambda n: graph.degree(n), reverse=False)
        attackers = attackers[:options['num_attacker']]

    elif options['attacker_type'] == 'Honest':
        attackers = [n for n in graph if n.node_type != 'Seed']
        attackers.sort(key=lambda n: n.rank, reverse=True)
        attackers = attackers[:options['num_attacker']]

    # making sybil nodes and connecting them to attacker nodes
    num_groups = min(options['num_attacker'], options['num_sybils'] // 2)
    for i in range(num_groups):
        for j in range(options['num_sybils'] // num_groups):
            groups = {'collaborative_attack_{}'.format(i): 'NonSeed'}
            sybil = Node('s-{0}-{1}'.format(i, j),
                         'Sybil',
                         groups=groups,
                         created_at=int(time.time() * 1000))
            sybils[sybil] = i
            graph.add_edge(sybil, attackers[i])
        inside_sybils = [n for n in sybils if sybils[n] == i]
        pairs = itertools.combinations(inside_sybils, 2)
        for s, t in pairs:
            graph.add_edge(s, t)

    for s1 in sybils:
        candidates = [
            s for s in sybils
            if sybils[s] != sybils[s1] and outside_degree(graph, s) < 3
        ]
        num_sample = min(3 - outside_degree(graph, s1), len(candidates))
        if not candidates:
            continue
        candidates = random.sample(candidates, num_sample)
        for s2 in candidates:
            graph.add_edge(s1, s2)
    return graph
예제 #13
0
def many_small_groups_attack(graph, options):
    sybils = []
    attackers = [n for n in graph if n.node_type == 'Seed']
    attackers.sort(key=lambda n: n.rank, reverse=False)
    attackers = attackers[:options['num_attacker']]

    for i in range(options['num_sybils']):
        groups = {'sg-{}'.format(i): 'NonSeed'}
        sybil = Node('s-{}'.format(i),
                     'Sybil',
                     groups=groups,
                     created_at=int(time.time() * 1000))
        sybils.append(sybil)
        for attacker in attackers:
            graph.add_edge(sybil, attacker)
            attacker.groups.update(groups)

    # connecting the sybil nodes together
    for i in range(options['stitches']):
        s, t = random.sample(sybils, 2)
        graph.add_edge(s, t)
    return graph
예제 #14
0
def stupid_sybil(graph, options):
    sybils = []
    attackers = [n for n in graph if n.rank > 0]
    attackers.sort(key=lambda n: n.rank, reverse=True)
    for attacker in attackers:
        attacker.groups['stupid_sybil'] = 'NonSeed'
        for i in range(2):
            groups = {'stupid_sybil': 'NonSeed'}
            sybil = Node('stupid_sybil_{}'.format(i),
                         'Sybil',
                         groups=groups,
                         created_at=int(time.time() * 1000))
            sybils.append(sybil)
            graph.add_edge(attacker, sybil)
        reset_ranks(graph)
        ranker = algorithms.GroupSybilRank(graph)
        ranker.rank()
        border = max([s.rank for s in sybils])
        if border:
            break
        graph.remove_nodes_from(sybils)
        del attacker.groups['stupid_sybil']
    return graph