srlabs / blue-merle Goto Github PK
View Code? Open in Web Editor NEWThe blue-merle package enhances anonymity and reduces forensic traceability of the GL-E750 Mudi 4G mobile wi-fi router
License: BSD 3-Clause "New" or "Revised" License
The blue-merle package enhances anonymity and reduces forensic traceability of the GL-E750 Mudi 4G mobile wi-fi router
License: BSD 3-Clause "New" or "Revised" License
Hi,
when doing a sim swap/imei change the device gives an error and I'm not sure what is means:
CFUN=4 failed. trying again.
after this error : Warning: reset took longer than expected.
Additionally I noticed with the previous blue merle version you were able to cancel the sim swap by pulling the switch down within 5 seconds. would it be able to provide that option again?
I'm using the EP-06 module.
Thanks to all that worked on the blue merle.
Issue: A few times I experienced that GL750 Mudi could not boot and/or the celluilar interface did not start witch some randomly generated IMEIs and I was assuming that they either may be gray/blacklisted ones nad/or simply not valid by syntax?
If syntaxial validity check is not done than please consider the Luhn algorithm formula for generated IMEIs
The subject says it all. In order to increase user confidence and credibility of the feature, please display the current and the new IMEI on the OLED.
blue-merle is broken with the new interface of GL-750 firmware > 4
Here is the install log from ssh
root@GL-E750:~# opkg install blue-merle*.ipk
Installing blue-merle (1.0.0-1) to root...
You have a GL.iNet GL-E750, running firmware version 4.3.6.
blue-merle has only been tested with GL-E750 Mudi Version 3.215.
The device or firmware version you are using have not been verified to work with blue-merle.
Would you like to continue on your own risk? (y/N): y
Configuring blue-merle.
patching file /www/src/temple/settings/index.js
Hunk #1 FAILED at 6.
Hunk #2 FAILED at 79.
Hunk #3 FAILED at 108.
Hunk #4 FAILED at 170.
patch: **** Can't reopen file /www/src/temple/settings/index.js : No such file or directory
patching file /www/src/temple/settings/index.html
Hunk #1 FAILED at 6.
Hunk #2 FAILED at 64.
Hunk #3 FAILED at 84.
patch: **** Can't reopen file /www/src/temple/settings/index.html : No such file or directory
patching file /usr/bin/switchaction
Hunk #1 FAILED at 10.
Hunk #2 FAILED at 136.
Hunk #3 FAILED at 157.
patch: **** Can't reopen file /usr/bin/switchaction : No such file or directory
patching file /usr/bin/switch_queue
Hunk #1 FAILED at 81.
Hunk #2 FAILED at 98.
patch: **** Can't reopen file /usr/bin/switch_queue : No such file or directory
The /tmp/ directory does not exist. This should be fine...
The /etc/ directory does not exist. Exiting...
TEST: DOES NOT EXIST
cp: can't stat '/etc/init.d/gl_tertf': No such file or directory
Updating database.
After that, it is in the opkg installed packages, but you can't access from the web interface and the switch have no effect.
Hello!
Can you add instructions how to update plugin to official readme.md?
The current version of GL-E750 for Europe is sold out and not available anymore. GL said a version 2 will become available in one month from now. Do you plan to support that as well?
So beffore i buy the mudi i just wana make this clear, by changing the imei, this DOES make it so i can use any carrier like trac phone or simple mobile, ect.? Esspesaly with the feater of the imei and imsi being changed in relation to the sim correct? I just dont wana pull the trigger and still be locked to t mobile
Hi
I really like your development!
But I found curious post on GL-iNet forum:
https://forum.gl-inet.com/t/how-many-times-can-i-change-imei/41542
Person asks will usage of this plugin harm the hardware part of router?
I have a MacroDroid script on my phone, that automatically detects if my phone is connected to Wi-Fi, and then puts the phone into Airplane Mode, disabling the cellular modem, but without disabling the Wi-Fi connectivity. This prevents my phone from being associated with the locations where I spend the majority of my time.
There's no use for expensive mobile data if you're connected to free Wi-Fi, and a mobile router than is stationary for an extended duration, while connected to the cellular network, puts the owner at risk of being "geographically profiled".
The router will necessarily spend the majority of its time in locations associated with the identity of the owner, such as their home, or their place of employment, allowing them to be identified.
The duration of the surveillance necessary to identity the owner of the device, via "geographic profiling", could be less than 7 days.
Even if the IMEI is changed every 7 days, this is not sufficient to prevent the owner from being identified using historical CSLI (Cell Site Location Information) data, which is retained by cellular providers for a minimum of 2 years, if not permanently.
It is conceivable that CSLI data recorded in proximity to a sensitive location, such as a place of worship, a political protest, an abortion clinic, could be used to trace a person directly to their residence.
As as example, if the owner attended a political protest, or traveled to a jurisdiction where abortion is legal, before returning home to a state where it is not, merely changing the IMSI/IMEI would not preserve their anonymity, as the association with locations associated with their identity would already have happened.
Would the Blue Merle developers be willing to implement a feature that automatically detects the presence of a Wi-Fi connection, and then disables the cellular modem?
It could also function in reverse, with the cellular modem being re-enabled after the Wi-Fi is disconnected.
This feature would significantly increase the "location privacy" provided by Blue Merle.
Thank you, please tell me what you think.
blue-merle
's deterministic IMEI generation currently likely does not work for PIN-protected SIM cards. If the PIN is not verified, get_imsi()
in imei_generate.py
returns an empty string (""
). This is because a SIM's IMSI can only be read out after the SIM's PIN is verified (or PIN verification is disabled).
For PIN-protected SIM cards where the PIN has not been verified when blue-merle
runs, the same IMEI will always be generated.
This has not yet been practically tested and validated.
Use a SIM's ICCID for deterministic IMEI generation. The ICCID ("Integrated Circuit Card Identifier") is a globally unique identifier for smart cards. It can be read out even prior to PIN verification.
To read a SIM's IMSI, use the CIMI
AT command.
To read a SIM's ICCID, use the QCCID
AT command.
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:
import random
def luhn_check(imei):
"""
Calculate the Luhn check digit for a given IMEI number.
"""
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 imei_generate():
# List of TACs for different manufacturers
tacs = {
"Samsung": "352073",
"iPhone": "352074",
"Sony": "352075",
"LG": "352076",
"Nokia": "352077",
"Huawei": "352078",
"Xiaomi": "352079",
"OnePlus": "352080"
}
# Randomly choose a manufacturer
manufacturer = random.choice(list(tacs.keys()))
tac = tacs[manufacturer]
# Generate FAC, USN
fac = str(random.randint(10, 99)) # Final Assembly Code
usn = str(random.randint(100000, 999999)) # Unique Serial Number
# Combine all parts to form the IMEI without the check digit
imei_without_check = tac + fac + usn
# Calculate the check digit using the Luhn algorithm
check_digit = luhn_check(imei_without_check)
# Combine all parts to form the complete IMEI
imei = imei_without_check + str(check_digit)
return imei
# Example usage
print(imei_generate())
Fix for Bash version
#!/bin/bash
# Function to calculate the Luhn check digit
luhn_check() {
local sum=0
local num_digits=${#1}
local oddeven=$((num_digits & 1))
for ((i=0; i<num_digits; i++)); do
local digit=${1:$i:1}
if ((!((i & 1) ^ oddeven))); then
digit=$((digit * 2))
fi
if ((digit > 9)); then
digit=$((digit - 9))
fi
sum=$((sum + digit))
done
echo $((10 - (sum % 10)))
}
# Function to generate a random IMEI
generate_imei() {
# TACs for different manufacturers
local tacs=(
"352073" # Samsung
"352074" # iPhone
"352075" # Sony
"352076" # LG
"352077" # Nokia
"352078" # Huawei
"352079" # Xiaomi
"352080" # OnePlus
)
# Randomly choose a manufacturer
local tac=${tacs[$RANDOM % ${#tacs[@]}]}
# Generate FAC, USN
local fac=$(printf "%02d" $((RANDOM % 90 + 10))) # Final Assembly Code
local usn=$(printf "%06d" $((RANDOM % 900000 + 100000))) # Unique Serial Number
# Combine all parts to form the IMEI without the check digit
local imei_without_check="${tac}${fac}${usn}"
# Calculate the check digit using the Luhn algorithm
local check_digit=$(luhn_check "$imei_without_check")
# Combine all parts to form the complete IMEI
local imei="${imei_without_check}${check_digit}"
echo "$imei"
}
# Example usage
generate_imei
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
There is a new Firmware that fixes various vulnerability the most problematic https://nvd.nist.gov/vuln/detail/CVE-2023-46454
I tested blue-merle on with a Mudi 750 V2 on 4.3.9. Besides the Firmware Version check that fails for a fully automated install it works as expected (Tested: Button, Webinterface, ClI) added a fix for the firmware check in this PR #28
As discussed on page 9 of the Documentation, a fingerprinting risk emerges when blue-merle
generates an IMEI with a TAC of a phone model not supporting LTE frequency bands the Mudi router supports, namely B1, B3, B5, B7, B8, B20, B28, B32, B38, B40 and B41. When a blue merle Mudi uses a frequency band that does not match the TAC’s specification, an observer can deduce that the IMEI is spoofed.
As limiting the frequency bands might impact service quality and availability, the feature should be optional.
The command to limit the baseband to specific bands is
AT+QCFG=$band
See AT Commands Manual (alternative public link) for details.
In Documentation.pdf, sections 4.2 and 4.2.2 (blue-merle
command) mention that the new IMEI is generated either randomly or deterministically, but section 4.2.1 (toggle button) does not mention how the new IMEI is generated at all (although README.md does mention it) - perhaps this could be clarified.
Hi!
You can use this database:
https://github.com/VTSTech/IMEIDB/blob/master/imeidb.csv
You should definitely add some. Because it is 6.2% like TAC will overlap.
This can cause issues as purely theoretically someone who spying can use this information to try to identify user of your application.
For example like this:
imei_prefix = ["35674108", "35290611", "35397710", "35323210", "35384110",
"35982748", "35672011", "35759049", "35266891", "35407115",
"35538025", "35480910", "35324590", "35901183", "35139729",
"35479164", "35326407", "35920507", "35915307", "35656908",
"35537508", "35381208", "35655408", "35669908", "35004331",
"35012763", "35013263", "35013596", "35014386", "35014545",
"35017890", "35022562", "35048105", "35048156", "35049626",
"35053352", "35063329", "35064217", "35068083", "35075982",
"35076156", "35076825", "35079439"]
Possible enhancement, subject to additional discussion:
Currently, deterministic IMEI generation will generate the same IMEI regardless of underlying Mudi device. Since the generation algorithm is open source and the only seed input is the IMSI, network operators can identify deterministically generated IMEIs.
It could be useful to provide a new deterministic IMEI generation mode that generates different deterministic IMEIs per Mudi. This can be done by e.g. writing a random seed to disk at blue-merle
installation time and using this seed in addition to the SIM's unique identifier (IMSI, ICCID) to derive the new IMEI. The random seed would not survive a factory reset, so it might be better to use another unique hardware identifier.
is there solution to restore a modem to its original IMEI?
I have already physically reset the router and reinstalled the latest firmware version from GL-iNet, but the IMEI has not reverted to the original.
blue-merle
should be compatible with GL-E750 Mudi version 3.217 from 2023-05-08 02:41:42 (UTC+00:00) / sha256: 5dab717c1b418b5da4613bce6d82949d9a3defadc53e660fef08d1febe6e93d3
(from here).
This is how I performed the update and arrived at this conclusion:
blue-merle_1.0.0-1_mips_24kc.ipk
installedblue-merle_1.0.0-1_mips_24kc.ipk
blue-merle
, and are modified by it. diff
'd those after step 2 against the versions of them after step 1 - there were zero differences:
/www/src/temple/settings/index.html
/www/src/temple/settings/index.js
/usr/bin/switchaction
/usr/bin/switch_queue
blue-merle_1.0.0-1_mips_24kc.ipk
blue-merle
looks as it shouldPlease note, however, that this does not prove that everything works as it should. Use this information at your own risk.
I created code draft to implement the MAC logging and MAC address wiping toggles in Blue Merle:
<label>
Logging
<input type="checkbox" id="cbLogging">
</label>
<label>
MAC Wiping
<input type="checkbox" id="cbMacWiping">
</label>
// Configs
config.add('logging', true);
config.add('mac_wiping', false);
// UI init
function initUI() {
document.getElementById('cbLogging').checked = config.get('logging');
document.getElementById('cbMacWiping').checked = config.get('mac_wiping');
document.getElementById('cbLogging').onchange = updateConfig;
document.getElementById('cbMacWiping').onchange = updateConfig;
}
// Update config
function updateConfig() {
config.set('logging', this.checked);
config.set('mac_wiping', this.checked);
saveConfig();
}
// Save handler
function saveConfig() {
// Validation
// Call scripts
// Persist config
luci.http.submit();
}
// Init UI
initUI();
// Save on unload
window.onbeforeunload = saveConfig;
toggle_mac_wiping() {
// Wipe/restore MACs logic
}
This will:
To stop writing logs at all you need to:
/etc/init.d/gl_clients disable
/etc/init.d/gl_clients stop
But there is one more way - Lua. And it looks more correct than first one:
-- Define toggles
local log_toggle = nil
local wipe_toggle = nil
-- Function to initialize toggles
function init_toggles()
-- Log toggle
log_toggle = SimpleForm("log_toggle")
log_toggle.title = "Log Toggle"
log_toggle.reset = false
log_toggle:append(TextValue("status", ""))
log_toggle:append(Checkbox("enabled", "Enable Logging"))
-- Wipe toggle
wipe_toggle = SimpleForm("wipe_toggle")
wipe_toggle.title = "Wipe Toggle"
wipe_toggle.reset = false
wipe_toggle:append(TextValue("status", ""))
wipe_toggle:append(Checkbox("enabled", "Enable Wiping"))
end
-- Function to handle toggle changes
function toggle_change(section)
if section == log_toggle then
-- Disable wiping if logs enabled
if log_toggle.enabled.value then
wipe_toggle.enabled.disabled = true
else
wipe_toggle.enabled.disabled = false
end
-- Update services based on log toggle
if log_toggle.enabled.value then
luci.sys.call("/etc/init.d/gl_clients enable")
luci.sys.call("/etc/init.d/gl_clients start")
else
luci.sys.call("/etc/init.d/gl_clients disable")
luci.sys.call("/etc/init.d/gl_clients stop")
end
elseif section == wipe_toggle then
-- Disable logs if wiping enabled
if wipe_toggle.enabled.value then
log_toggle.enabled.disabled = true
else
log_toggle.enabled.disabled = false
end
-- Update services based on wipe toggle
if wipe_toggle.enabled.value then
-- Add code to enable wiping
else
-- Add code to disable wiping
end
end
end
-- Initialize toggles
init_toggles()
-- Add toggles to page
entry({"admin", "services", "bluemerle"}, cbi("Blue Merle"), _("Blue Merle")).dependent = false
entry({"admin", "services", "bluemerle"}, firstchild()).dependent = false
entry({"admin", "services", "bluemerle"}, log_toggle, _("Log Toggle")).dependent = false
entry({"admin", "services", "bluemerle"}, wipe_toggle, _("Wipe Toggle")).dependent = false
-- Handle toggle changes
log_toggle.apply = function() toggle_change(log_toggle) end
wipe_toggle.apply = function() toggle_change(wipe_toggle) end
———
Additional features:
———
This will (if toggle enabled):
Luci GUI (firewall.xml)
<form action="/cgi-bin/luci/admin/network/firewall" method="post">
<fieldset id="password">
<input type="checkbox" name="password_dynamic">
<label>Enable Dynamic Password</label>
<select name="password_mode">
<option value="reboot">Change on Reboot</option>
</select>
</fieldset>
<fieldset id="max_security">
<input type="checkbox" name="max_security_enabled">
<label>Enable Max Security</label>
</fieldset>
<button type="submit">Save</button>
</form>
uci.lua
password = {}
password.dynamic = luci.http.formvalue("password_dynamic")
max_security = {}
max_security.enabled = luci.http.formvalue("max_security_enabled")
uci:set("wireless", "radio0", "password", "")
uci:set("firewall", "max_security", "enabled", max_security.enabled)
uci:commit("wireless")
uci:commit("firewall")
password.cron
PASSWORD=`uci get wireless.radio0.password`
DAY=`date +%d`
NEW_PASSWORD="$PASSWORD-$DAY"
uci set wireless.radio0.password="$NEW_PASSWORD"
uci commit
/etc/init.d/firewall restart
firewall.lua
enabled = uci.get("firewall", "max_security", "enabled")
if enabled == "1" then
iptables.filter.append("INPUT", "-p tcp --dport 80 -j ACCEPT")
iptables.filter.append("INPUT", "-p tcp --dport 443 -j ACCEPT")
iptables.filter.append("INPUT", "-p udp --dport 53 -j ACCEPT")
iptables.filter.append("INPUT", "-p tcp --dport 123 -j ACCEPT")
iptables.filter.append("OUTPUT", "-p tcp --sport 80 -j ACCEPT")
iptables.filter.append("OUTPUT", "-p tcp --sport 443 -j ACCEPT")
iptables.filter.append("OUTPUT", "-p udp --sport 53 -j ACCEPT")
iptables.filter.append("OUTPUT", "-p tcp --sport 123 -j ACCEPT")
iptables.filter.append("INPUT", "-j DROP")
iptables.filter.append("OUTPUT", "-j DROP")
else
# normal rules
end
iptables.apply()
Hi,
Is possible to setup blue-merle with GL-E750 Router with EG25-G Module ?
We currently use a Python script to generate and set new IMEIs.
Our dependency on Python bloats the package and increases execution times. There is also a rare issue where the Python script fails to set an updated IMEI. Our current understanding is that this is due to our exclusive
usage of the serial interface to the modem, which might break when the modem is used by other parts of the system at the same time.
In the future, we can migrate to Lua, which is natively supported by OpenWRT. Most of the actual work is already completed in luhn.lua.
For the IMEI generation method, the deterministic (d
) choice is the default in the screenshot, while in the implementation, the random (r
) choice is the default.
For the device shutdown vs. modem reset question, the latter (m
) choice is the default in the screenshot, while in the implementation, the former (s
) choice is the default.
I think there is a privacy risk in the GL-E750
implementation that blue-merle
could, but currently does not take into account:
The WAN MAC address, which is used for WiFi station / "repeater" mode1, is static. This can potentially cause a tracking risk:
The "MAC clone" feature already allows for changing the WAN MAC address (there's even a handy one-shot randomization feature), although the factory default WAN MAC address cannot be changed this way. If the user wishes to protect herself from the described tracking risk2, then, currently, the WAN MAC address must be changed manually, every time.
I'd therefore like to propose the following:
Provided you agree to the above assessment, I could pack up my changes into a pull request that implements this.
Unfortunately, it seems nontrivial to place an on/off switch for this in GL.iNet's admin panel properly: the new field would have to go through the API binary at /www/api
, for which the source code does not seem to be available. You seem to have had a bit of luck with adding the SIM switch choice :)
Either way, I'd at least provide a simple CLI command (e.g. uci set network.@interface[4].randomize_macaddr=0
)
Very neat project!
..
Hello!
As written in this article (link clickable) DNS cashing can expose you browsing history:
“Your DNS cache is effectively a list of visited websites, much like your browser history. However, the DNS cache is usually managed by your device’s operating system and is therefore outside the scope of any single browser — and the safeguards browsers usually implement.
One such safeguard is incognito (or private) mode. While incognito mode doesn’t deliver on the vast majority of its advertised privacy promises, it does prevent your browser from storing your browsing history. Yet, a very similar list of websites is present inside the DNS cache and outlives your incognito session. A compromised device could therefore expose your browsing history via the DNS cache, even if you visited those websites in incognito mode.”
Nice job, i just install and works nice.
I see the led screen don't show any clients anymore after the install, and at the admin panel also no clients connect.
The subject says it all. In order to provide a panik button for the most paranoid users, a single touch delete IMEI option would be nice addition.
In the spec it says:
3.1.2.1 Link between IMEI and IMSI in deterministic mode
In deterministic mode, the IMEI is statically derived from the IMSI. By checking the relationship
between IMSI and IMEI, an observer can identify that a blue merle IMEI changer is in use.
I think by adding a secret / salt, that the user provides additionally, e.g. by a parameter --deterministic-salt
, which is also used to seed the random generator ("salt + imsi"), the relationship between IMSI and IMEI could not be traced back anymore, right? Not sure if that would practically improve it (since there is already a random mode), though. Just as a suggestion / feedback.
For some reason I don't yet fully understand, the LuCI UI seems to cache the available modules causing the UI to display the non-existent blue-merle app after removal of the package
likewise, installing blue-merle through the CLI causes a stale UI that does not yet show blue-merle in the menu.
I've tried rm -f /tmp/luci-indexcache* ; rm -rf /tmp/luci-modulecache ; luc i-reload ; /etc/init.d/nginx restart
but to no avail.
So how mamy people have gotten the newst mudi to work with merle ?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.