背景

天翼网关不支持自动重启,恰好有Padavan二级路由在,所以想通过定时执行脚本重启网关。

大致抓包看了下:

  1. 登录 保存cookie
  2. 访问pc页面保存token
  3. 请求重启接口

命令解读

使用light proxy 抓包看具体哪里出错

-- 设置代理
-p -e "http_proxy=http://127.0.0.1:12888"

-- 最大重定向次数
--max-redirect=0

-- debug 请求
-d

完整脚本

#!/bin/bash


password=qqq


result=$(wget --max-redirect=0 -d --quiet \
  --method POST \
  --timeout=0 \
  --header 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7' \
  --header 'Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7' \
  --header 'Cache-Control: no-cache' \
  --header 'Connection: keep-alive' \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --header 'Origin: http://192.168.1.1' \
  --header 'Pragma: no-cache' \
  --header 'Referer: http://192.168.1.1/' \
  --header 'Upgrade-Insecure-Requests: 1' \
  --header 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36' \
  --body-data "username=useradmin&psd=$password" \
  'http://192.168.1.1/cgi-bin/luci' 2>&1)




cookie_vale=$(echo "$result" | grep -i 'Set-Cookie'   | sed -n 's/.*sysauth=\([^;]*\).*/\1/p')

cookie_string='Cookie: sysauth='$cookie_vale

echo $cookie_string








result=$(curl --location 'http://192.168.1.1/cgi-bin/luci/admin/device/pc' \
         --header 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7' \
         --header 'Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7' \
         --header 'Cache-Control: no-cache' \
         --header 'Connection: keep-alive' \
         --header "$cookie_string" \
         --header 'Pragma: no-cache' \
         --header 'Upgrade-Insecure-Requests: 1' \
         --header 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36')


token=$(echo "$result" | sed -n "s/.*token: '\([^']*\).*/\1/p" | sed -n '1p')


curl --location 'http://192.168.1.1/cgi-bin/luci/admin/reboot' \
--header 'Accept: */*' \
--header 'Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7' \
--header 'Cache-Control: no-cache' \
--header 'Connection: keep-alive' \
--header 'Content-type: application/x-www-form-urlencoded' \
--header "$cookie_string" \
--header 'Origin: http://192.168.1.1' \
--header 'Pragma: no-cache' \
--header 'Referer: http://192.168.1.1/cgi-bin/luci/' \
--header 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36' \
--data-urlencode "token=$token" \
--data-urlencode '_=0.24887794922555595'

python3代码

# -*- coding: utf-8 -*-
import paramiko

remote_file_path = '/tmp/reload.py'

script_content = '''
# -*- coding: utf-8 -*-
import requests

password = "xxxxx"

headers = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Origin': 'http://192.168.1.1',
    'Pragma': 'no-cache',
    'Referer': 'http://192.168.1.1/',
    'Upgrade-Insecure-Requests': '1',
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'
}

data = {
    'username': 'useradmin',
    'psd': password
}


def main():
    # 登录获取Cookie
    response = requests.post('http://192.168.1.1/cgi-bin/luci', headers=headers, data=data, allow_redirects=False)
    cookie_value = response.headers.get('Set-Cookie').split(';')[0].split('=')[1]
    cookie_string = f'sysauth={cookie_value}'
    print(cookie_string)
    # 发送请求获取token
    headers['Cookie'] = cookie_string
    response = requests.get('http://192.168.1.1/cgi-bin/luci/admin/device/pc', headers=headers)
    token = response.text.split("token: '")[1].split("'")[0]
    print(token)
    payload = f'token={token}&_=0.24887794922555595'

    response = requests.request("POST", 'http://192.168.1.1/cgi-bin/luci/admin/reboot', headers=headers, data=payload)
    print('success')

if __name__ == "__main__":
    main()
'''


def main():
    def ssh_execute_command(hostname, port, username, password, command):
        # 创建SSH客户端对象
        client = paramiko.SSHClient()
        # 自动添加和保存远程服务器的SSH密钥
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

        try:
            # 连接远程服务器
            client.connect(hostname, port=port, username=username, password=password)

            # 执行命令
            stdin, stdout, stderr = client.exec_command(command)

            # 打印命令执行结果
            print(stdout.read().decode())

        except paramiko.AuthenticationException:
            print("认证失败,请检查用户名和密码")
        except paramiko.SSHException as e:
            print("SSH连接错误:", str(e))
        except Exception as e:
            print("连接远程服务器错误:", str(e))
        finally:
            # 关闭SSH连接
            client.close()

    def uploadFile(hostname, password, port, username):
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(hostname, port, username, password)
        # 将文本内容写入远程文件
        sftp = ssh.open_sftp()
        with sftp.open(remote_file_path, 'w') as remote_file:
            remote_file.write(script_content)

    # SSH服务器的连接信息
    hostname = "127.0.0.1"
    port = 5022
    username = "admin"
    password = "xxxxx"
    # 要写入脚本的内容
    uploadFile(hostname, password, port, username)
    # 写入脚本并执行
    command = 'python3 ' + remote_file_path
    ssh_execute_command(hostname, port, username, password, command)


if __name__ == "__main__":
    main()