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
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
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
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
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
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
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
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
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
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
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
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
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
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