Open Quid68 opened 7 months ago
So does our fix replace the imi gen script or add to it?
You should add it to main script with replacing part of previous one. It is just a part of script
Were should i replace it? I looked on ur page and it doesn look like u implemented it on ur fork
I provided above options for testing only. But if you need full script here it is:
#!/usr/bin/env python3
import random
import string
import argparse
import serial
import re
from functools import reduce
from enum import Enum
class Modes(Enum):
DETERMINISTIC = 1
RANDOM = 2
STATIC = 3
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--verbose", help="Enables verbose output", action="store_true")
ap.add_argument("-g", "--generate-only", help="Only generates an IMEI rather than setting it", action="store_true")
modes = ap.add_mutually_exclusive_group()
modes.add_argument("-d", "--deterministic", help="Switches IMEI generation to deterministic mode", action="store_true")
modes.add_argument("-s", "--static", help="Sets user-defined IMEI", action="store")
modes.add_argument("-r", "--random", help="Sets random IMEI", action="store_true")
imei_length = 14 # without validation digit
imei_prefix = ["35674108", "35290611", "35397710", "35323210", "35384110",
"35982748", "35672011", "35759049", "35266891", "35407115",
"35538025", "35480910", "35324590", "35901183", "35139729",
"35479164"]
verbose = False
mode = None
TTY = '/dev/ttyUSB3'
BAUDRATE = 9600
TIMEOUT = 3
def luhn_check(imei):
sum = 0
num_digits = len(imei)
oddeven = num_digits & 1
for i in range(0, num_digits):
digit = int(imei[i])
if not ((i & 1) ^ oddeven):
digit *= 2
if digit > 9:
digit -= 9
sum += digit
return (10 - (sum % 10)) % 10
def generate_imei(imei_prefix, imsi_d=None):
if mode == Modes.DETERMINISTIC:
random.seed(imsi_d)
imei = random.choice(imei_prefix)
random_part_length = imei_length - len(imei)
imei += "".join(random.sample(string.digits, random_part_length))
validation_digit = luhn_check(imei)
imei = str(imei) + str(validation_digit)
return imei
def validate_imei(imei):
if len(imei) != 14:
return False
validation_digit = int(imei[-1])
imei_verify = imei[0:14]
validation_digit_verify = luhn_check(imei_verify)
return validation_digit == validation_digit_verify
def get_imsi():
with serial.Serial(TTY, BAUDRATE, timeout=TIMEOUT, exclusive=True) as ser:
ser.write(b'AT+CIMI\r')
output = ser.read(64)
imsi_d = re.findall(b'[0-9]{15}', output)
return b"".join(imsi_d)
def set_imei(imei):
with serial.Serial(TTY, BAUDRATE, timeout=TIMEOUT, exclusive=True) as ser:
cmd = b'AT+EGMR=1,7,\"'+imei.encode()+b'\"\r'
ser.write(cmd)
output = ser.read(64)
new_imei = get_imei()
return new_imei == imei.encode()
def get_imei():
with serial.Serial(TTY, BAUDRATE, timeout=TIMEOUT, exclusive=True) as ser:
ser.write(b'AT+GSN\r')
output = ser.read(64)
imei_d = re.findall(b'[0-9]{15}', output)
return b"".join(imei_d)
if __name__ == '__main__':
args = ap.parse_args()
if args.verbose:
verbose = args.verbose
if args.deterministic:
mode = Modes.DETERMINISTIC
imsi_d = get_imsi()
if args.random:
mode = Modes.RANDOM
if args.static is not None:
mode = Modes.STATIC
static_imei = args.static
if mode == Modes.STATIC:
if validate_imei(static_imei):
set_imei(static_imei)
else:
exit(-1)
else:
imei = generate_imei(imei_prefix, imsi_d)
if not args.generate_only:
if not set_imei(imei):
exit(-1)
exit(0)
It is replacement for this
I added LUHN check to make sure IMEI 100% valid
This part:
imei_prefix = ["35674108", "35290611", "35397710", "35323210", "35384110",
"35982748", "35672011", "35759049", "35266891", "35407115",
"35538025", "35480910", "35324590", "35901183", "35139729",
"35479164"]
Can be widened or fully replaced to mimic other devices using this database
For example this script will mimic to smartphones using smartphones manufacturers TACs (this variant untested):
#!/usr/bin/env python3
import random
import string
import argparse
import serial
import re
from enum import Enum
class Modes(Enum):
DETERMINISTIC = 1
RANDOM = 2
STATIC = 3
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--verbose", help="Enables verbose output", action="store_true")
ap.add_argument("-g", "--generate-only", help="Only generates an IMEI rather than setting it", action="store_true")
modes = ap.add_mutually_exclusive_group()
modes.add_argument("-d", "--deterministic", help="Switches IMEI generation to deterministic mode", action="store_true")
modes.add_argument("-s", "--static", help="Sets user-defined IMEI", action="store")
modes.add_argument("-r", "--random", help="Sets random IMEI", action="store_true")
imei_length = 14 # without validation digit
imei_prefix = [
"352073", # Samsung
"352074", # iPhone
"352075", # Sony
"352076", # LG
"352077", # Nokia
"352078", # Huawei
"352079", # Xiaomi
"352080" # OnePlus
]
verbose = False
mode = None
TTY = '/dev/ttyUSB3'
BAUDRATE = 9600
TIMEOUT = 3
def luhn_check(imei):
sum = 0
num_digits = len(imei)
oddeven = num_digits & 1
for i in range(0, num_digits):
digit = int(imei[i])
if not ((i & 1) ^ oddeven):
digit *= 2
if digit > 9:
digit -= 9
sum += digit
return (10 - (sum % 10)) % 10
def generate_imei(imei_prefix, imsi_d=None):
if mode == Modes.DETERMINISTIC:
random.seed(imsi_d)
tac = random.choice(imei_prefix)
imei = tac + "".join(random.sample(string.digits, imei_length - len(tac)))
validation_digit = luhn_check(imei)
imei = str(imei) + str(validation_digit)
return imei
def validate_imei(imei):
if len(imei) != 15:
return False
validation_digit = int(imei[-1])
imei_verify = imei[0:14]
validation_digit_verify = luhn_check(imei_verify)
return validation_digit == validation_digit_verify
def get_imsi():
with serial.Serial(TTY, BAUDRATE, timeout=TIMEOUT, exclusive=True) as ser:
ser.write(b'AT+CIMI\r')
output = ser.read(64)
imsi_d = re.findall(b'[0-9]{15}', output)
return b"".join(imsi_d)
def set_imei(imei):
with serial.Serial(TTY, BAUDRATE, timeout=TIMEOUT, exclusive=True) as ser:
cmd = b'AT+EGMR=1,7,\"'+imei.encode()+b'\"\r'
ser.write(cmd)
output = ser.read(64)
new_imei = get_imei()
return new_imei == imei.encode()
def get_imei():
with serial.Serial(TTY, BAUDRATE, timeout=TIMEOUT, exclusive=True) as ser:
ser.write(b'AT+GSN\r')
output = ser.read(64)
imei_d = re.findall(b'[0-9]{15}', output)
return b"".join(imei_d)
if __name__ == '__main__':
args = ap.parse_args()
if args.verbose:
verbose = args.verbose
if args.deterministic:
mode = Modes.DETERMINISTIC
imsi_d = get_imsi()
if args.random:
mode = Modes.RANDOM
if args.static is not None:
mode = Modes.STATIC
static_imei = args.static
if mode == Modes.STATIC:
if validate_imei(static_imei):
set_imei(static_imei)
else:
exit(-1)
else:
imei = generate_imei(imei_prefix, imsi_d)
if not args.generate_only:
if not set_imei(imei):
exit(-1)
exit(0)
have your ran the two and seen your script work? its good shit if it works
i will prepare a fork as it looks like your not git users.
that looks great! Thanks for the contribution.
Can you help me understand your statement:
The deal is your IMEIs fails check sum and have invalid TAC (in several countries).
a bit better? I'm surprised that you seem to have experience an invalid checksum. How did you notice the invalid checksum? And which TACs are invalid?
that looks great! Thanks for the contribution.
It seems like this is now redundant
which TACs are invalid?
All valid as I checked. But TACs list should be bigger a little bit
hey guys I scraped a TAC database, and have a list of codes you can use:
Thanks a lot for the TAC database. In fact, we considered "full randomization" across all possible models at first.
However, this would result in a higher likelihood of detection that the IMEI was in fact manipulated:
Great, I agree with what you say. However there should still be a decent selection of various popular devices to avoid correlation.
Maybe focus on top 20 best selling phones:
https://en.wikipedia.org/wiki/List_of_best-selling_mobile_phones#2022[90]
See Table 1 on page 9 for the models we choose from: https://github.com/srlabs/blue-merle/blob/main/Documentation.pdf
This is a good list. Thanks so much. Previously was using KaiOS but definitely doing to get a Mudi and run this!
Hi
Blue merle is NOT generating valid IMEI. Most totally invalid and rejected by ISP.
The deal is your IMEIs fails check sum and have invalid TAC (in several countries).
I am not really good in GitHub so I cannot submit PR.
Fix for Python version
But this is simple code to make it look more valid:
Fix for Bash version
This will make router mimic to one of this manufacturers: Samsung, iPhone, Sony, LG, Nokia, Huawei, Xiaomi, OnePlus
This ensures that ISP will not reject IMEI, nor shape speed because of “not mobile use”.
You can extend list of manufacturers by TACs from this database