0

I work in an environment where occasionally we have to bulk configure TP-Link ADSL routers. As one can understand this does cause productivity issues. I solved the issue using python & especially it's requests.session() library. It worked tremendously well especially for older TP-LINK models such as TP-LINK Archer D5.

Reference: How to control a TPLINK router with a python script

The method that i used was to do the configuration via browser, packet capture using Wireshark and replicate it using Python. Archer VR600 introduces new method. When starting configuration using the browser, the main page requests for new password. Once done then it generates a random long string (KEY) which is sent to the router.This key is random and unique, based on this random string JSESSIONID is generated and used throughout the session.

AC1600 IP Address: 192.168.1.1

PC IP Address: 192.168.1.100

KEY and SESSIONID when configured via Browser.

key when configured via browser

Session ID when configured via browser

KEY and SESSIONID when configured via Python Script.

Key when configured via browser

Key when configured via browser

As you can see i am trying to replicate the steps via script but failing due to not been able to create a unique key which will be accepted by the router, thus failing to generate a SESSIONID and enable rest on the configuration. 

Code:

def configure_tplink_archer_vr600():
    user = 'admin'
    salt = '%3D'
    default_password = 'admin:admin'
    password = "admin"
    base_url = 'http://192.168.1.1'
    setPwd_url = 'http://192.168.1.1/cgi/setPwd?pwd='
    login_url = "http://192.168.1.1/cgi/login?UserName=0f98175e8bd1c9297fc22ec6a47fa4824bfb3c8c73141acd7b46db283557d229c9783f409690c9af5e87055608b358ab4d1dfc45f17e6261daabd3e042d7aee92aa1d8829a8d5a69eb641dcc103b17c4f443a96800c8c523b911589cf7e6164dbc1001194"
    get_busy_url = "http://192.168.1.1/cgi/getBusy"
    authorization = base64.b64encode(
        (default_password).encode()).decode('ascii')
    salted_password = base64.b64encode((password).encode()).decode('ascii')
    salted_password = salted_password.replace("=", "%3D")
    print("Salted Password" + salted_password)
    setPwd_url = setPwd_url + salted_password

    rs = requests.session()
    rs.headers['Cookie'] = 'Authorization=Basic ' + authorization
    rs.headers['Referer'] = base_url
    rs.headers[
        'User-Agent'] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"
    print("This is authorization string: " + authorization)

    response = rs.post(setPwd_url)
    print(response)
    print(response.text.encode("utf-8"))

    response = rs.post(get_busy_url)
    print(response)
    print(response.text.encode("utf-8"))

    response = rs.post(login_url)
    print(response)
    print(response.text.encode("utf-8"))
yasir zamir
  • 125
  • 1
  • 1
  • 6
  • I don't understand the use of Wireshark in this instance... Are you perhaps capturing session cookies from other computers and using them to log in to the router? If not why don't you just log in using a session? That would save the session cookie and you can just go on from there. – Xosrov Dec 24 '19 at 19:32
  • As i have mentioned earlier, what the browser is generating via my clicks on the page, the browser interacts with the router with the HTTP methods. I am trying to replicate it via a script and hence i use wireshark. older models have not issue with this method. But the new model of router has extra request which i have coded as "login_url" which is sent to router. The point is when i do from browser a key is generated sent to router it returns session key and whole process is continued via browser. On the other when i script is used it fails as if it is expecting new KEY. – yasir zamir Dec 25 '19 at 05:01
  • You're trying to "bulk configure" many routers, and you're just using the cookies sent from one of the routers to log in to all of them. Cookies work per session, and aren't the same in each attempt – Xosrov Dec 25 '19 at 09:20

1 Answers1

0

Use the python requests library to log in to the router, this cuts the need for any manual work:


  • Go to the login page and right click + inspect element.
  • Navigate to the resources tab, here you can see HTTP methods as they happen.
  • Login using some username and password and you should see the corresponding GET/POST method on the network tab.
  • Click on it and find the payload it sends to the router, this is usually in json format and you'll need to build it in your python script, and send it as an input to the webpage.(luckily there are many tutorials for this out there.

Note that sometimes a payload for the script is actually generated by some javascript, but in most cases it's just some string cramped into the HTML source. If you see a payload you don't understand, just search for it in the page source. Then you'll have to extract it with something like regex and add it to your payload.

Xosrov
  • 689
  • 4
  • 18