TR 069 comunicación con el router

El protocolo TR 069 permite la comunicación entre un router (cliente cpe) y el operador ISP (servidor acs). Existe bastante información en internet al respecto, y la descripción del protocolo está en http://www.broadband-forum.org   (para la versión 1.4 https://www.broadband-forum.org/technical/download/TR-069.pdf)

Tomando como base (e inspiración) la información en https://nada-labs.net/2015/getting-root-on-a-telus-vgs1432/, pueden realizarse algunas pruebas, suponiendo que podemos configurar en nuestro router los parámetros del cliente TR069,

teniendo así dos escenarios:

  1. Emular o suplantar al servidor (acs) con un ordenador, abriendo un puerto y estableciendo una comunicación con el router para ver y modificar parámetros (aunque se consigue, el router está tan limitado por el ISP que modificar algunos parámetros no tiene ningún impacto)
  2. Emular o suplantar al router (cliente) con un ordenador, para establecer la comunicación con el ACS del proveedor de Internet y poder obtener algo de información (no he conseguido que el acs llegue a devolver la información solicitada, aunque sí establecer la comunicación)

1. Emular/suplantar al servidor ACS

Se trata de usar un ordenador a modo de acs, para comunicarnos con el router y poder configurarlo (todo teniendo en cuenta el protocolo TR069)

Esto lo podremos hacer sólo si nuestro router nos permite configurar los parámetros, indicamos la url del acs como la de nuestro ordenador (ip y puerto, lo he dejado en el puerto 80, pero en mis ejemplos iré cambiando a veces esta url, p.ej http://192.168.1.100:3333), quitamos la autenticación del cliente, para simplificar y ponemos un intervalo que nos valga para probar (60 segundos es demasiado poco, hay que poner algo más, es el intervalo en el que el router va a contactar con el acs)

En TR069 es el cliente el que inicia la comunicación con el servidor acs (de ahí el parámtero inform interval para hacerlo cada cierto tiempo). No obstante, existe también la posibilidad de que el ACS fuerce al router a conectarse a él (existe una url del router que lo fuerza, p.ej. http://192.168.1.1:7547/tr69), o bien , con  cualquier cambio en la configuración, imagen anterior, el router se conecta al acs)

Por eso, justo antes de cambiar la configuración del cliente TR069 del router, ponemos un puerto a la escucha en nuestro ordenador con netcat (-k persistente):

ncat -v -k -l 80

Entonces recibiremos la petición POST del router:

La petición POST es una solicitud de mensaje Inform, y para poder comunicarnos con él hay que apuntar el parámetro mustUnderstand, que debemos usar el mismo durante toda la comunicación (y que va cambiando, es una especie de identificacdor de sesión)

Según TR069, el ACS ha de responder a este mensaje con un OK al que posteriormente el router responde con un mensaje vacío. A partir de ahí el ACS (nuestro ordenador) ya puede pedirle cosas al router. Es complicado hacer varias solicitudes en una sola comunicación netcat, por lo que yo he ido haciendo:

  1. iniciar netcat
  2. forzar la conexión de router al netcat y ver el mensaje que nos envía (copiar mustUnderstand)
  3. Responder en el netcat al router y esperar su respuesta vacía
  4. solicitar algo al router y esperar respuesta
  5. cerrar netcat

La respuesta la escribimos directamente en el cursor donde está nuestro netcat, (recuadro naranja en la imagen superior). Tenemos que tener a mano un calculador de strings, porque hay que enviar el Content-Length, cuyo valor es la longitud (número de caracteres) de la cadena xml que enviamos, y sumarle «1» que corresponde al retorno de carro (pulsar return) yo he usado https://www.browerling.com/tools/text-length.

Respuesta que tiene que enviar el ACS (netcat)

Escribimos la respuesta (copiar/pegar) que tiene que dar el ACS, directamente en la ventana del netcat, y pulsamos enter

HTTP/1.1 200 OK
Content-Type: text/xml; charset=ISO-8859-1
Content-Length: 527

<soapenv:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:cwmp="urn:dslforum-org:cwmp-1-0" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <soapenv:Header>
      <cwmp:ID soapenv:mustUnderstand="1">1032922721</cwmp:ID>
   </soapenv:Header>
   <soapenv:Body>
      <cwmp:InformResponse>
         <MaxEnvelopes>1</MaxEnvelopes>
      </cwmp:InformResponse>
   <soapenv:Body>
</soapenv:Envelope>    

La respuesta del router (inmediata) es:

POST / HTTP/1.1
Host: 192.168.1.38:3333
User-Agent: BCM_TR69_CPE_04_00
Connection: keep-alive
Authorization: Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
Content-Length: 0

Y ahora ya es cuando podemos pedirle la modificación de un parámetro, contestando a este último POST del router, y de acuerdo  con la especificación TR069 (SetParameterValues), por ejemplo, tratamos de modificar el valor del Telnet de DENY_ALL a LAN_ONLY (o ALLOW_ALL):

HTTP/1.1 200 OK
Content-Type: text/xml; charset=ISO-8859-1
Content-Length: 1085

<soapenv:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:cwmp="urn:dslforum-org:cwmp-1-0" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Header>
        <cwmp:ID soapenv:mustUnderstand="1">1032922721</cwmp:ID>
    </soapenv:Header>
    <soapenv:Body>
        <cwmp:SetParameterValues>
            <ParameterList soap:arrayType="cwmp:ParameterValueStruct[2]">
                <ParameterValueStruct>
                    <Name>InternetGatewayDevice.X_5067F0_AccessServiceCfg.TelnetStatus</Name>
                    <Value xsi:type="xsd:string">LAN_ONLY</Value>
                </ParameterValueStruct>
                <ParameterValueStruct>
                    <Name>InternetGatewayDevice.X_5067F0_AccessServiceCfg.FtpStatus</Name>
                    <Value xsi:type="xsd:string">LAN_ONLY</Value>
                </ParameterValueStruct>
            </ParameterList>
        </cwmp:SetParameterValues>
    </soapenv:Body>
</soapenv:Envelope>

El router responde con el OK a dicho cambio, con un status 0:

Aunque ya he comentado que esto no afecta para nada al router tan capado…

Iniciando de nuevo una sesión con ncat, podemos pedir todos los parámetros y sus valores al router, para ello, forzamos la conexión del router, le contestamos con el inform, esperamos su nueva petición vacía, y le lanzamos la respuesta (según TR069):

HTTP/1.1 200 OK
Content-Type: text/xml; charset=ISO-8859-1
Content-Length: 651

<soapenv:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:cwmp="urn:dslforum-org:cwmp-1-0" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Header>
        <cwmp:ID soapenv:mustUnderstand="1">2013855969</cwmp:ID>
    </soapenv:Header>
    <soapenv:Body>
        <cwmp:GetParameterValues>
            <ParameterNames soap:arrayType="xsd:string[]">
                <string>InternetGatewayDevice.</string>
            </ParameterNames>
        </cwmp:GetParameterValues>
    </soapenv:Body>
</soapenv:Envelope>

El router responde con un xml larguísimo con todos los parámetros y sus valores…

POST / HTTP/1.1
Host: 192.168.1.100:3333
User-Agent: BCM_TR69_CPE_04_00
Connection: keep-alive
Authorization: Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
SOAPAction: 
Content-Type: text/xml
Content-Length: 650955

<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">2123854369</cwmp:ID>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
      <cwmp:GetParameterValuesResponse>
        <ParameterList SOAP-ENC:arrayType="cwmp:ParameterValueStruct[2739]">
            <ParameterValueStruct>
              <Name>InternetGatewayDevice.DeviceSummary</Name>
              <Value xsi:type="xsd:string">InternetGatewayDevice:1.4[](Baseline:2, EthernetLAN:2, Time:2, IPPing:1, DeviceAssociation:2, QoS:2, Bridging:2, xxx </Value>
            </ParameterValueStruct>
            <ParameterValueStruct>
              <Name>InternetGatewayDevice.LANDeviceNumberOfEntries</Name>
              <Value xsi:type="xsd:unsignedInt">1</Value>
            </ParameterValueStruct>
            <ParameterValueStruct>
              <Name>InternetGatewayDevice.WANDeviceNumberOfEntries</Name>
              <Value xsi:type="xsd:unsignedInt">1</Value>
            </ParameterValueStruct>
            <ParameterValueStruct>
                     <ParameterValueStruct>
              <Name>InternetGatewayDevice.DeviceInfo.Manufacturer</Name>
              <Value xsi:type="xsd:string"> xxx </Value>
            </ParameterValueStruct>
            <ParameterValueStruct>
              <Name>InternetGatewayDevice.DeviceInfo.ManufacturerOUI</Name>
              <Value xsi:type="xsd:string"> xxx </Value>
            </ParameterValueStruct>
            <ParameterValueStruct>
              <Name>InternetGatewayDevice.DeviceInfo.ModelName</Name>
              <Value xsi:type="xsd:string"> xxx </Value>
            </ParameterValueStruct>

TR069 permite hacer muchas cosas, aunque por desgracia, no he conseguido mucho. Por ejemplo, se pueden subir archivos al router, pero obtengo errores:

Existe Software específico de ACS, he intentado varios, pero lo más sencillo resulta utilizar simplemente una sesión netcat. He intentado con Drayteck ACS, FreeACS (https://github.com/freeacs), funcionan, pero son demasiado complicados y no merece la pena para este tipo de pruebas:


2- Emular/Suplantar al Cliente TR069

Se trata ahora del proceso inverso, es decir, tratar de conectarse al servidor ACS del ISP, para ello, iniciamos un netcat pero esta vez conectándonos directamente al servidor ACS original y con sus parámetros. Para ello, iniciamos un netcat y copiamos en él (enviamos) directamente lo que obteníamos en el primer paso del caso anterior, sin modificar nada…. El ISP contesta con el inform.

Copiamos la petición inicial que nos hace el router en el punto 1 anterior
respuesta del ACS del ISP

El ISP responde el inform, usa una aplicación Java. Lo que intento es usar los métodos ACS de la especificación para pedir desde el router cierto tipo de información al servidor ACS, p. ej. puede solicitarse el firmware, lo he intentado, pero sin éxito:

Al responder nosotros con el mensaje vacío, el ACS nos cierra la conexión, porque no quiere nada de nosotros…

Error en la solicitud del firmware (petición tras el inform, es decir, sin enviar la petición con contenido vacío para que el ACS no nos cierre la conexión):

POST /xxxxxxxxx HTTP/1.1
Host: 192.168.1.100:xxx
User-Agent: BCM_TR69_CPE_04_00
Connection: keep-alive
Authorization: Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
SOAPAction: 
Content-Type: text/xml
Content-Length: 615

<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-2">
    <SOAP-ENV:Header>
      <cwmp:ID SOAP-ENV:mustUnderstand="1">1234567890</cwmp:ID>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
      <cwmp:RequestDownload>
        <FileType>1 Firmware Upgrade Image</FileType>
        <FileTypeArg></FileTypeArg>
      </cwmp:RequestDownload>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
HTTP/1.1 400 Bad Request
Date: Wed, 12 Dec 2018 11:48:37 GMT
Server: Apache
Content-Length: 127
Set-Cookie: JSESSIONID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; path=/
X-Powered-By: Servlet/2.5 JSP/2.1
Connection: close
Content-Type: text/html; charset=UTF-8

Inform message expected to initiate a new session but received : class com.alcatel.hdm.cpe.cwmp.castorcodec.rpc.RequestDownload

He intentado instalar Easycwmp http://www.easycwmp.org/, pero ha sido imposible de momento, seguiré intentándolo a ver si se logra algo más…

1 Comment

  1. Abry · domingo, 29 marzo, 2020 Reply

    Al final te cierra la conexión porque te faltó incluir la cookie me imagino

Responder a Abry Cancelar la respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.