Oauth的學習以及開發自助上課簽到指令碼

Kabuto_taka發表於2022-04-28

附上原始碼:                                 https://github.com/taka250/auto_checkin_skl_hdu

 

 

 

首先了解學習oauth的知識點

https://www.cnblogs.com/blowing00/p/4521135.html

http://cncc.bingj.com/cache.aspx?q=oauth2.0&d=4769308101185638&mkt=zh-CN&setlang=zh-CN&w=7GpK0TUY9vh41MBeGv6mo3zlrgdPnO7v     推薦這位老師寫的文章

其中的授權碼模式

(A)使用者訪問客戶端,後者將前者導向認證伺服器。

(B)使用者選擇是否給予客戶端授權。

(C)假設使用者給予授權,認證伺服器將使用者導向客戶端事先指定的"重定向URI"(redirection URI),同時附上一個授權碼。

(D)客戶端收到授權碼,附上早先的"重定向URI",向認證伺服器申請令牌。這一步是在客戶端的後臺的伺服器上完成的,對使用者不可見。

(E)認證伺服器核對了授權碼和重定向URI,確認無誤後,向客戶端傳送訪問令牌(access token)和更新令牌(refresh token)。

A.用bp抓包第一個請求時

Oauth的學習以及開發自助上課簽到指令碼

將我們導向了客戶端指定的uri(儲存在get引數中),響應頭也將我們302到了實現指定的uri(ticket就是授權碼)。前提是使用者給予了授權,在此情況下是用rsa對使用者名稱密碼進行驗證。Oauth的學習以及開發自助上課簽到指令碼

Oauth的學習以及開發自助上課簽到指令碼

我還發現了請求中包含了state引數。研究了一下是防止csrf的

然後就是拿到token了

要注意你電進行了兩次拿token兩次設定cookie,第一個token無用(。。。)

 

登入加簽到

首先學校的login.js裡面

Oauth的學習以及開發自助上課簽到指令碼

然後我看了下strEnc函式

/** 
* DES加密解密 
* @Copyright Copyright (c) 2006 
* @author Guapo 
* @see DESCore 
*/  
  
/* 
* encrypt the string to string made up of hex 
* return the encrypted string 
*/  
function strEnc(data,firstKey,secondKey,thirdKey){  
  
 var leng = data.length;  
 var encData = "";  

四個引數,第一個是使用者名稱加密碼加登入瀏覽器時的第一個頁面中的某個元素的value(lt) 所以說還需要爬蟲。

Oauth的學習以及開發自助上課簽到指令碼

  明明是des加密說是rsa(-v-。。。。跟rsa半毛錢關係都沒有。。。。之前還有人分析說這是rsa和des雙重加密。。笑)本來想在python裡解析js程式碼或者將js翻譯為python後來發現一個配置很麻煩一個用esecjs庫翻譯的結果執行效率很慢顯然來不及簽到。那我就直接去寫python的des加密指令碼。等我學完des準備寫的之後才想起來可以去github上找程式碼。。。(就當學習一次des)然後strEnc的三個引數等我看完原函式後瞭解了這個其實就是對結果進行三次加密des而已。附上我在github上找到的python程式碼https://github.com/twhiteman/pyDes  (網上的都是隻能對一個64位進行加密需要我改寫)巨折磨,這個2006年的js程式碼將四個字元擴充64位明文,而其他庫都是八位進行一次加密,太煩了,我還是在本地啟動一個node伺服器來跑程式碼試試。

 

Oauth的學習以及開發自助上課簽到指令碼

所以我掛了三個程式 qbot 和node伺服器加密和python進行checkin

Oauth的學習以及開發自助上課簽到指令碼

附上python server的程式碼

from flask import Flask, request
import Skl
import account


app = Flask(__name__)


@app.route('/', methods=["POST"])
def post_data():
    if request.get_json().get('message_type') == 'group' and request.get_json().get('group_id') == int(account.group):
        print(account.group)
        gid = request.get_json().get('group_id')
        uid = request.get_json().get('sender').get('user_id')
        message = request.get_json().get('raw_message')
        skl = Skl.Skl()
        if skl.check_num(message, uid, gid):
            skl.autocheck(message, account.user_1,
                          account.passwd_1, account.group)
            skl.autocheck(message, account.user_2,
                          account.passwd_2, account.group)
    return 'ok'


if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=8001)

和封裝的Skl類

import requests
import re
import uuid
import time


class Skl(object):
    def check_num(self, message, uid, gid):
        if re.match(r'^[0-9]{4}$', message):
            self.code = message
            return 1
        return 0

    def spider(self):
        response = requests.get(
            'https://cas.hdu.edu.cn/cas/login?state=IFgP7G0QAG0UFHop0M4&service=https%3A%2F%2Fskl.hdu.edu.cn%2Fapi%2Fcas%2Flogin%3Fstate%3DIFgP7G0QAG0UFHop0M4%26index%3D')
        response.enconding = 'utf-8'
        setcookie = response.headers['Set-Cookie']
        p = r'JSESSIONID=([0-9A-Za-z]{1,})'
        cookie = re.search(p, setcookie).group(1)
        p = r'<input type="hidden" id="lt" name="lt" value="(LT-\d{1,}-[0-9A-Za-z]{1,}-cas)" />'
        lt = re.search(p, response.text).group(1)
        p = r'<input type="hidden" name="execution" value="([0-9A-Za-z]{1,})" />'
        execu = re.search(p, response.text).group(1)

        return lt, execu, cookie

    def to_node(self, lt, upwd):
        response = requests.get(
            'http://127.0.0.1:2022/?lt={0}&upwd={1}'.format(lt, upwd)).text
        return response

    def checkin(self, rsa, lt, execu, cookie_1, user, code,passwd):
        url_1 = 'https://cas.hdu.edu.cn/cas/login?state=IFgP7G0QAG0UFHop0M4&service=https%3A%2F%2Fskl.hdu.edu.cn%2Fapi%2Fcas%2Flogin%3Fstate%3DIFgP7G0QAG0UFHop0M4%26index%3D'
        data_1 = {
            'rsa': rsa,
            'ul': len(user),
            'pl': len(passwd),
            'lt': lt,
            'execution': execu,
            '_eventId': 'submit'}

        head_1 = {
            'Host': 'cas.hdu.edu.cn',
            'Origin': 'https://cas.hdu.edu.cn',
            'Upgrade-Insecure-Requests': '1',
            'Cookie': 'hdu_cas_un={0}; JSESSIONID={1}; Language=zh_CN'.format(user, cookie_1),
            'Accept-Encoding': 'gzip, deflate',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36',
            'Referer': 'https://cas.hdu.edu.cn/cas/login?state=IFgP7G0QAG0UFHop0M4&service=https%3A%2F%2Fskl.hdu.edu.cn%2Fapi%2Fcas%2Flogin%3Fstate%3DIFgP7G0QAG0UFHop0M4%26index%3D'}

        res = requests.post(url_1, data=data_1,
                            headers=head_1, allow_redirects=False)
        url_2 = res.headers['Location']
        p = r'CASTGC=([^;]+)'
        cookie_3 = re.search(p, res.headers['Set-Cookie']).group(1)

        head_2 = {
            'Host': 'skl.hdu.edu.cn',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36',
            'Upgrade-Insecure-Requests': '1',
            'Referer': 'https://cas.hdu.edu.cn/',
            'Accept-Language': 'zh-CN,zh;q=0.9'}

        url_3 = requests.get(url_2, headers=head_2,
                             allow_redirects=False).headers['Location']

        head_3 = {
            'Host': 'cas.hdu.edu.cn',
            'Upgrade-Insecure-Requests': '1',
            'Cookie': 'CASTGC={0};JSESSIONID={1}; Language=zh_CN'.format(cookie_3, cookie_1),
            'Accept-Encoding': 'gzip, deflate',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36',
            'Referer': 'https://cas.hdu.edu.cn/'}
        url_4 = requests.get(url_3, headers=head_3,
                             allow_redirects=False).headers['Location']

        head_4 = {
            'Host': 'skl.hdu.edu.cn',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36',
            'Upgrade-Insecure-Requests': '1',
            'Referer': 'https://cas.hdu.edu.cn/',
            'Accept-Language': 'zh-CN,zh;q=0.9'}
        token = requests.get(url_4, headers=head_4,
                             allow_redirects=False).headers['X-Auth-Token']

        t = int(time.time()*1000)
        url_5 = 'https://skl.hdu.edu.cn/api/checkIn/code-check-in?userid={0}&code={1}&latitude=30.31958&longitude=120.3391&t={2}'.format(
            user, code, t)
        id = str(uuid.uuid1())
        head_5 = {
            'Host': 'skl.hdu.edu.cn',
            'X-Auth-Token': token,
            'Skl-Ticket': id,
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36',
            'Origin': 'https://skl.hduhelp.com',
            'Referer': 'https://cas.hdu.edu.cn/',
            'Accept-Language': 'zh-CN,zh;q=0.9',
            'Accept-Encoding': 'gzip, deflate'}
        res = requests.get(url_5, headers=head_5).text
        p = '\"msg\":\"(.+)\"'
        msg = re.search(p, res).group(1)
        return(msg)

    def autocheck(self, message, user, passwd, group):
        secret = []
        secret = self.spider()
        lt = secret[0]
        execu = secret[1]
        cookie = secret[2]
        rsa = self.to_node(lt, user+passwd)
        result = 'hdu賬號為'+user+'的返回訊息:' + \
            self.checkin(rsa, lt, execu, cookie, user, message,passwd)
        requests.get(
            url='http://127.0.0.1:5700/send_group_msg?group_id={0}&message={1}'.format(group, result))

最後的checkin還涉及到了uuid和時間戳。

個人感覺並不會對uuid進行校驗,畢竟只是近似於無法重複的數字

附上原始碼:                                 https://github.com/taka250/auto_checkin_skl_hdu

相關文章