天天看點

純python模拟登入今日校園雲端擷取cookie,用于實作自動簽到前言正題結尾

前言

2021.4.1

由于我的學校網站更新,登入成功後不傳回acw_tc、MOD_AUTH_CAS參數了,此實作方法或許已經失效,自行抓包分析吧

​ 自從二月份開始,由于疫情爆發,隻好在家上網課,每天上今日校園填寫相同問題的每日一報,就開始想,我每天都宅在家裡面,能有什麼問題,不如利用一點爬蟲的知識做一個自動填寫的腳本,可是遇到很多障礙,例如,手機app弄代理,抓包不到,因為今日校園用了ssl的加密傳輸方式,難以抓包分析,這也讓我的興趣沉下去了。

​ 直到開學返校後,原本的每日一報變成了每日三簽了,嫌麻煩的我又來了興趣,後來讓我在b站看到子墨的自動簽到項目。

  • ​子墨的部落格 連結
  • 子墨的github 連結

正題

​ 因為子墨的自動簽到項目依賴于他的伺服器api,最近使用的人多了起來,就頻繁出現api接口失效的情況,自己又不想買伺服器搭建,是以就自己動手,用純python代碼擷取登陸後的cookies,替換原來使用的api接口。

思維導圖如下

純python模拟登入今日校園雲端擷取cookie,用于實作自動簽到前言正題結尾

首先打開 https://www.cpdaily.com/v6/config/guest/tenant/list

在這個頁面裡CRTL - F 搜尋學校名字,找到後面這些字段

純python模拟登入今日校園雲端擷取cookie,用于實作自動簽到前言正題結尾

)

我的學校joinType為NOTCLOUD,沒研究過其他學校的,是以自行比較吧

純python模拟登入今日校園雲端擷取cookie,用于實作自動簽到前言正題結尾

打開idsUrl的連結,那就是學校的雲端登入頁面

随便填個賬号登入,抓取登入所送出的資料包看看送出了什麼資料

純python模拟登入今日校園雲端擷取cookie,用于實作自動簽到前言正題結尾

密碼是加密後的108位密文

It,dllt,execution,rmShown是是藏在登入頁面的資訊,每次重新整理登入頁面,lt,execution的值都會改變

清空本地cookie,重新重新整理頁面

擷取route、 JSESSIONID

純python模拟登入今日校園雲端擷取cookie,用于實作自動簽到前言正題結尾

重新整理頁面後,檢視第一個資料包的響應頭有set-cookie字段,route、JSESSIONID是我們所需要的

純python模拟登入今日校園雲端擷取cookie,用于實作自動簽到前言正題結尾
##url、headers、data自行擷取
##擷取 route、JSESSIONID
response = requests.get(url, headers=headers, data = payload)
if response.status_code == 200:
    ##response.cookies是CookieJar類型,requests.utils.dict_from_cookiejar可以把cookiejar類型轉換成dict類型
    cookie = requests.utils.dict_from_cookiejar(response.cookies)
    JSESSIONID = cookie["JSESSIONID"]
    route = cookie["route"]
           

嘗試正确賬号密碼登入,檢視登入的第一個資料包,表單資料中送出username,加密後的password,It,dllt,execution

純python模拟登入今日校園雲端擷取cookie,用于實作自動簽到前言正題結尾

請求表頭包含前面擷取到的route,JSESSIONID

純python模拟登入今日校園雲端擷取cookie,用于實作自動簽到前言正題結尾

擷取CASTGC,CASPRIVACY,iPlanetDirectory

響應表頭中的set-cookie包含我們需要的CASTGC,CASPRIVACY,iPlanetDirectory字段

純python模拟登入今日校園雲端擷取cookie,用于實作自動簽到前言正題結尾

登入後,頁面會跳轉,而響應表頭中的Location就是跳轉用的

##擷取CASTGC、CASPRIVACY、iPlanetDirectoryPro
form = [
	"username":xxxx,
	"password":xxx,
	"lt":xxx,
	"dllt":xxx,
	"execution":xxx,
	"_eventld":xxx,
	"rmShown":xxx,
]
res = requests.post(url,headers=headers2,data=form)
response_headers = res.history[0].headers##因為頁面重定向,是以需要擷取響應曆史的表頭
set_cookie = response_headers["SET-COOKIE"]
CASTGC = re.findall("CASTGC=(.*?);",set_cookie)[0]
CASPRIVACY = re.findall("CASPRIVACY=(.*?);",set_cookie)[0]
iPlanetDirectoryPro = re.findall("iPlanetDirectoryPro=(.*?);",set_cookie)[0]
Location = response_headers["Location"]
           

擷取acw_tc、MOD_AUTH_CAS

請求Location的連結後就能擷取最重要的acw_tc、MOD_AUTH_CAS字段了

純python模拟登入今日校園雲端擷取cookie,用于實作自動簽到前言正題結尾
#擷取acw_tc、MOD_AUTH_CAS
res2 = requests.get(url=Location,headers=headers3)
response_headers = res2.history[0].headers##因為頁面重定向,是以需要擷取響應曆史的表頭
set_cookie2 = response_headers["SET-COOKIE"]
acw_tc = re.findall("acw_tc=(.*?);",set_cookie2)[0]
MOD_AUTH_CAS = re.findall("MOD_AUTH_CAS=(.*?);",set_cookie2)[0]
Location = response_headers["Location"]
           

以上就是擷取route等字段的思路和方法,問題來了,最開始登入所需要的密碼如何加密,lt等字段如何擷取呢

擷取It、dllt等字段

CTRL-F搜尋LT-,可以檢視隐藏在登入頁面html的字段

純python模拟登入今日校園雲端擷取cookie,用于實作自動簽到前言正題結尾

****

##xpath方法
LT = html.xpath('//*[@id="casLoginForm"]/input[1]/@value')[0]
##key是隐藏在登入界面的加密鑰匙,用來加密成108位密碼
key = html.xpath('//*[@id="pwdDefaultEncryptSalt"]/@value')[0]
dllt = html.xpath('//*[@id="casLoginForm"]/input[2]/@value')[0]
execution = html.xpath('//*[@id="casLoginForm"]/input[3]/@value')[0]
rmShown = html.xpath('//*[@id="casLoginForm"]/input[5]/@value')[0]

##lxml不知道如何上傳到雲函數,是以還是用正則吧
LT = re.findall('name="lt" value="(.*)"', html)[0]
key = re.findall('id="pwdDefaultEncryptSalt" value="(.*?)"',html)[0]
dllt = re.findall('name="dllt" value="(.*)"',html)[0]
execution = re.findall('name="execution" value="(.*?)"',html)[0]
rmShown = re.findall('name="rmShown" value="(.*?)"',html)[0]
           

其中id為pwddefaultEncryptSalt的value值是密碼加密的key,用來加密成108位密碼的,用到的方法是AES加密

加密子產品

import math
import random
import base64
from Crypto.Cipher import AES
# 擷取随機字元串
def getRandomString(length):
    chs = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
    result = ''
    for i in range(0, length):
        result += chs[(math.floor(random.random() * len(chs)))]
    return result

# AES加密
def EncryptAES(s, key, iv='1' * 16, charset='utf-8'):
    key = key.encode(charset)
    iv = iv.encode(charset)
    BLOCK_SIZE = 16
    pad = lambda s: (s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE))
    raw = pad(s)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    encrypted = cipher.encrypt(bytes(raw, encoding=charset))
    return str(base64.b64encode(encrypted), charset)
# 金智的AES加密過程
def AESEncrypt(data, key):
    return EncryptAES(getRandomString(64) + data, key, key)


pwd = AESEncrypt("密碼",key)
           

有了加密後的pwd,It等字段就可以實作模拟登入了,就可以擷取到acw_tc、MOD_AUTH_CAS等字段了,有了這些認證身份的東西,後面搞自動簽到就變得簡單了,通過手機端抓包擷取,分析就可以實作多種功能了。

  • 今日校園抓包參考 連結
  • 可能今日校園有檢測,用模拟器登入成功後再退出,再次登入會說手機驗證碼發送失敗

結尾

  • 通過深入研究子墨的自動簽到項目,發現子墨真的牛逼,把大部分學校的情況都考慮了,通用性很強。
  • 本項目僅供爬蟲學習交流,如作他用所承受的任何直接、間接法律責任一概與作者無關
  • 其次,本項目所通路的網站根目錄不存在robots協定
純python模拟登入今日校園雲端擷取cookie,用于實作自動簽到前言正題結尾