Initial commit

This commit is contained in:
Lan Tian
2025-03-30 17:20:58 -07:00
commit 3860df07ea
2 changed files with 85 additions and 0 deletions

33
README.md Normal file
View File

@@ -0,0 +1,33 @@
# Enable Web UI on FreedomFi Indoor CBRS Radio
This script implements a minimal TR-069 remote management server to enable Web UI on the FreedomFi Indoor CBRS Radio (Sercomm SCE4255W).
## Usage
1. Install Python 3 on your local computer.
2. Start script with `python3 tr069.py`
3. Update the DNS settings of your router, so that it can hijack `acs.freedomfi.com` to the IP address of your computer.
4. Turn on the FreedomFi Indoor CBRS Radio, and plug it into your LAN.
5. Once the radio starts connecting to remote management, you should see the script start printing some XML messages. These are the messages sent by the radio.
```bash
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cwmp="urn:dslforum-org:cwmp-1-0">
<soap-env:Header>
<cwmp:ID soap-env:mustUnderstand="1">null</cwmp:ID>
</soap-env:Header>
<soap-env:Body>
<cwmp:SetParameterValuesResponse>
<Status xsi:type="xsd:int">0</Status>
</cwmp:SetParameterValuesResponse>
</soap-env:Body>
</soap-env:Envelope>
192.168.0.209 - - [30/Mar/2025 17:15:50] "POST / HTTP/1.1" 200 -
```
If you do not see any requests, make sure you set up the DNS hijacking correctly. Try visiting `http://acs.freedomfi.com:8443` with your browser, and it should show an XML response.
6. Once you see `cwmp:SetParameterValuesResponse` in the response, the Web UI should be enabled.
7. Log in to the Web UI at the radio's IP address. The web UI is on port 443 with HTTPS enabled. E.g. `https://192.168.1.123/`
8. The default username and password are `sc_femto` and `tsFid2wz` ([source](https://discord.com/channels/404106811252408320/836735476659912754/1355330850232995861)).
9. Stop the script and remove the DNS hijacking, so that the radio doesn't try to connect to remote management infinitely.

52
tr069.py Normal file
View File

@@ -0,0 +1,52 @@
from http.server import SimpleHTTPRequestHandler, HTTPServer
xml_data = """
<?xml version='1.0' encoding='UTF-8'?>
<soap11env:Envelope xmlns:soap11enc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soap11env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:cwmp="urn:dslforum-org:cwmp-1-0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap11env:Header>
<cwmp:ID soap11env:mustUnderstand="1">null</cwmp:ID>
</soap11env:Header>
<soap11env:Body>
<cwmp:SetParameterValues>
<ParameterList>
<ParameterValueStruct>
<Name xsi:type="xsd:string">Device.X_000E8F_DeviceFeature.X_000E8F_WebServerEnable</Name>
<Value xsi:type="xsd:boolean">1</Value>
</ParameterValueStruct>
</ParameterList>
<ParameterKey xsi:type="xsd:string">SetPValues1234</ParameterKey>
</cwmp:SetParameterValues>
</soap11env:Body>
</soap11env:Envelope>
"""
class HTTPRequestHandler(SimpleHTTPRequestHandler):
"""This handler uses server.base_path instead of always using os.getcwd()"""
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "text/xml")
self.end_headers()
self.wfile.write(xml_data.strip().encode("utf-8"))
def do_POST(self):
content_len = int(self.headers.get("Content-Length", 0))
post_body = self.rfile.read(content_len).decode("utf-8")
print(post_body)
self.send_response(200)
self.send_header("Content-type", "text/xml")
self.end_headers()
if "cwmp:SetParameterValuesResponse" in post_body or "cwmp:Fault" in post_body:
return
self.wfile.write(xml_data.strip().encode("utf-8"))
httpd = HTTPServer(("", 8443), HTTPRequestHandler)
httpd.serve_forever()