#!/usr/bin/env python # # Utility to randomize Ki and other values in a Fairwaves SIM card DB file # # Copyright (C) 2017-2018 Alexander Chemeris # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # from optparse import OptionParser import os import sys import csv import random from pySim.utils import derive_milenage_opc #from pySim.utils import h2b def h2b(s): return ''.join([chr((int(x,16)<<4)+int(y,16)) for x,y in zip(s[0::2], s[1::2])]) def load_sim_db(filename): sim_db = {} with open(filename, 'r') as f: reader = csv.reader(f, delimiter=' ') # Skip the header reader.next() for l in reader: sim_db[l[0]] = l return sim_db def write_sim_db(filename, sim_db): with open(filename, 'a') as f: cw = csv.writer(f, delimiter=' ') for iccid in sorted(sim_db.iterkeys()): cw.writerow([x for x in sim_db[iccid]]) def process_sim(sim_keys, opts): # Update IMSI imsi = sim_keys[1] imsi = "%03d%02d%s" % (opts.mcc, opts.mnc, imsi[5:]) sim_keys[1] = imsi # Update Ki ki = ''.join(['%02x' % random.randrange(0,256) for i in range(16)]).upper() sim_keys[8] = ki # Update OPC op_opc = derive_milenage_opc(ki, opts.op).upper() sim_keys[9] = '01' + op_opc return sim_keys def process_db(sim_db, opts): sim_db_new = {} for iccid, sim_keys in sim_db.items(): sim_db_new[iccid] = process_sim(sim_keys, opts) return sim_db_new def parse_options(): parser = OptionParser(usage="usage: %prog [options]", description="Utility to randomize Ki and other values in a Fairwaves SIM card DB file.") parser.add_option("-s", "--sim-db", dest="sim_db_filename", type='string', metavar="FILE", help="filename of a SIM DB to load keys from (space separated)", default="sim_db.dat", ) parser.add_option("-o", "--out-db", dest="out_db_filename", type='string', metavar="FILE", help="filename of a SIM DB to write keys to (space separated)", default=None, ) parser.add_option("-x", "--mcc", dest="mcc", type="int", help="Mobile Country Code [default: %default]", default=001, ) parser.add_option("-y", "--mnc", dest="mnc", type="int", help="Mobile Network Code [default: %default]", default=01, ) parser.add_option("--op", dest="op", help="Set OP to derive OPC from OP and KI [default: %default]", default='00000000000000000000000000000000', ) (options, args) = parser.parse_args() if args: parser.error("Extraneous arguments") return options if __name__ == '__main__': # Parse options opts = parse_options() if opts.out_db_filename is None: print("Please specify output DB filename") sys.exit(1) print("Loading SIM DB ...") sim_db = load_sim_db(opts.sim_db_filename) sim_db = process_db(sim_db, opts) print("Writing SIM DB ...") write_sim_db(opts.out_db_filename, sim_db)