English | فارسی
A small command-line tool, written in Rust, to read information from and change settings of the ZLT X28 modem/router.
It started as a rescue project: the modem got stuck on a white screen after login, the web panel was limited, and the firmware could not be upgraded from the normal admin account. This tool talks directly to the modem's web API (/cgi-bin/http.cgi) and to its SSH server, so you can work around those problems from your terminal.
Use it only on a modem that you own. Some actions (SSH command execution, telnet patch, IMEI change) give you full control of the device. A wrong command can brick it.
| Feature | Option | Channel | Status |
|---|---|---|---|
| Show modem status | --show-status |
HTTP API | Working |
| Read firewall settings | --get-firewall |
HTTP API | Working |
| Send an AT command to the modem (for example, set the IMEI) | --at-command |
HTTP API | Working |
| Run a shell command as root | --ssh-exec |
SSH | Working |
| Upload a local file to the modem | --ssh-upload-file |
SSH | Working |
| Download a file from the modem | --ssh-download-file |
SSH | Working |
| Enable WAN (fixes the white screen after login on some units) | --enable-wan |
HTTP API | See Known issues |
| Apply the telnet patch (opens a telnet shell on the modem) | --apply-telnet-patch |
HTTP API | See Known issues |
Set the firewall level (off, low, medium, high) |
--set-firewall |
HTTP API | See Known issues |
| Disable TR-069 (remote management by the ISP) | --disable-tr069 |
HTTP API | See Known issues |
| Reboot the modem | --reboot |
HTTP API | See Known issues |
Other details:
- Logs in with username and password (the password is hashed with SHA-256 together with a token from the modem), or reuses an existing session with
--session-id. - Accepts the modem's self-signed HTTPS certificate.
- Prints results as one JSON object per line, so it is easy to use in scripts.
-
Rust 1.85 or newer (the project uses Rust edition 2024). Install it from https://rustup.rs.
-
A C toolchain,
pkg-config, and OpenSSL development files. They are needed to build thessh2andnative-tlscrates. On Debian/Ubuntu:sudo apt install build-essential pkg-config libssl-dev
-
Network access to the modem. The default address is
192.168.70.1.
git clone https://github.com/ehsanecc/modempatch.git
cd modempatch
cargo build --releaseThe binary is created at target/release/zlt_x28_patcher.
zlt_x28_patcher [OPTIONS] (--username <USER> --password <PASS> | --session-id <ID>)
| Option | Description |
|---|---|
-H, --host <HOST> |
Modem address. Default: 192.168.70.1 |
-u, --username <USER> |
Login username (required unless --session-id is given) |
-p, --password <PASS> |
Login password (required unless --session-id is given) |
--session-id <ID> |
Use an existing session ID instead of a username and password (HTTP API only) |
You can use one HTTP action per run.
| Option | Description |
|---|---|
--at-command <AT> |
Send an AT command and print the result |
--enable-wan |
Enable WAN |
--apply-telnet-patch |
Enable WAN and apply the telnet patch |
--set-firewall <off|low|medium|high> |
Set the firewall mode |
--get-firewall |
Show the firewall status |
--disable-tr069 |
Disable TR-069 |
--show-status |
Show modem status |
--reboot |
Reboot the modem |
You can use one SSH action per run. SSH always needs --username and --password.
| Option | Description |
|---|---|
--ssh-exec <CMD> |
Run a shell command on the modem (as root) |
--ssh-upload-file <LOCAL:REMOTE> |
Upload a local file to a remote path |
--ssh-download-file <REMOTE:LOCAL> |
Download a remote file to a local path (fails if the local file already exists) |
Run zlt_x28_patcher --help to see the same list in your terminal.
# Show modem status
zlt_x28_patcher -u admin -p admin --show-status
# Use a different modem address
zlt_x28_patcher -H 192.168.1.1 -u admin -p admin --get-firewall
# Reuse a session instead of logging in again
zlt_x28_patcher --session-id <SESSION_ID> --show-status
# Send an AT command
zlt_x28_patcher -u admin -p admin --at-command 'AT+EGMR=1,7,"123456789012345"'
# Run a command on the modem over SSH
zlt_x28_patcher -u admin -p admin --ssh-exec "uname -a"
# Upload and download files over SSH
zlt_x28_patcher -u admin -p admin --ssh-upload-file ./myfile:/customer/myfile
zlt_x28_patcher -u admin -p admin --ssh-download-file /etc/passwd:./passwdAbout IMEI: changing a device IMEI is restricted or illegal in some countries. Check your local law before you use
AT+EGMR.
Each result is printed as a JSON line, for example:
{"token":"..."}
{"sessionId":"..."}
{"status":{ ... }}If your login does not work as expected, or the web panel is limited (this happened to the author):
- Try the username and password printed on the modem's case (label). In the author's case,
superadmin:superadminhad limited access, and switching to the label credentials made the firmware upgrade possible. - Other pairs worth trying:
admin:admin,superadmin:superadmin,Admin:Conf,admin:root. - If you get a white screen after login, enabling WAN helped in the author's case.
This is version 0.1.1 and it is still a work in progress. In the current code:
--enable-wan,--apply-telnet-patch,--set-firewall,--disable-tr069and--rebootbuild their requests but do not wait for them to be sent, and they also send an empty CSRF token. Their "Done" message therefore does not prove that the modem changed. The reboot code also has a comment from the author saying it does not work yet.- Only one HTTP action and one SSH action can be used per run.
- Firmware patching (uploading the
x28script andx28.tgz) is planned but not implemented.
Please open an issue or pull request if you can help.
This software is provided as is, without any warranty. You are responsible for what you do with your device. Flashing firmware or running root commands can permanently damage it.
Made by Ehsan Varasteh (2026), after a couple of days of fighting to revive a modem.