Skip to content

Instantly share code, notes, and snippets.

Last active May 29, 2021 14:58
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
模拟 Gwifi 网页版,登陆 Gwifi
from typing import Any
from re import compile
from random import randint
from base64 import b64encode
from socket import socket, AF_INET, SOCK_DGRAM
from time import sleep
from requests import Session
from Crypto.Cipher.AES import MODE_CBC
from Crypto.Cipher import AES
class LoginGiwifi:
"""登陆 Giwifi 流程"""
HOST = ""
LOGIN_PAGE = f"{HOST}/gportal/web/login?account_type=2"
AUTH_PAGE = f"{HOST}/gportal/web/authLogin?round={randint(0, 1000)}"
USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0"
KEY = b"1234567887654321"
sign_re = compile('<input type="hidden" name="sign" value="(.+)"/>')
iv_re = compile('<input type="hidden" name="iv" id="iv" value="(.+)"/>')
sess = Session()
sess.headers["User-Agent"] = USER_AGENT
def __init__(self, username: str, password: str):
print(f"[*] sign: {self.sign}, iv: {self.iv}")
login_data = self.gene_login_form(username, password)
print(f"[*] login_data: {login_data}")
encrypted_data = self.encrypt_data(login_data.encode())
print(f"[*] send_data: {encrypted_data}")
auth_info = self.auth(encrypted_data)
print(f'[+] {auth_info["info"]}')
if (
"reasoncode" in auth_info["data"].keys()
and auth_info["data"]["reasoncode"] == 43
rebind_status = self.rebind_device(
username, password, auth_info["data"]["bindmac"]
print(f'[*] {rebind_status["info"]}')
reauth_info = self.auth(encrypted_data)
print(f'[+] {reauth_info["info"]}')
def get_ip() -> str:
"""获取到本机的 IP 地址"""
s = socket(AF_INET, SOCK_DGRAM)
s.connect(("", 53))
ip = s.getsockname()[0]
except Exception as e:
ip = ""
return ip
def get_sign(self):
"""获取登陆页面的密钥和 IV"""
login_resp = self.sess.get(self.LOGIN_PAGE)
sign_matched =
iv_matched =
assert sign_matched is not None and iv_matched is not None
self.sign = sign_matched[1]
self.iv = iv_matched[1]
def gene_login_form(
self, username: str, password: str, user_mac: str = None
) -> str:
login_form = {
"nasName": "SR8808-X",
"userIp": LoginGiwifi.get_ip(),
"pid": "20",
"sign": self.sign,
"iv": self.iv,
"name": username,
"password": password,
if user_mac:
login_form["userMac"] = user_mac
login_data = "&".join(f"{k}={v}" for k, v in login_form.items())
return login_data
def encrypt_data(self, login_data: bytes) -> bytes:
"""用 AES 加密表单"""
aes =, MODE_CBC, self.iv.encode())
padding_len = 16 - len(login_data) % 16 + len(login_data)
encrypted_data = aes.encrypt(login_data.ljust(padding_len, b"\x00"))
send_data = b64encode(encrypted_data)
return send_data
def auth(self, send_data: bytes) -> Any:
# POST encoded form
auth_resp =
self.AUTH_PAGE, data={"data": send_data, "iv": self.iv}
return auth_resp.json()
def rebind_device(self, username: str, password: str, mac: str) -> Any:
form_data = self.gene_login_form(username, password, mac)
encrypted_data = self.encrypt_data(form_data.encode())
rebind_resp =
f"{self.HOST}/gportal/web/reBindMac?round={randint(0, 1000)}",
data={"data": encrypted_data, "iv": self.iv},
return rebind_resp.json()
if __name__ == "__main__":
LoginGiwifi('这里填帐号', '这里填密码')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment