跳到正文
Carol's Blog
返回

对SCU网络服务安全性的第一次探索

对【川大疫情防控每日报系统】的探索

前言

本文中的数据皆由合理/合法途径获取,旨在课业之余找点乐趣,别无其他。

API

百度地图API

这里指百度地图的逆地理编码服务,下文中的ak为scu提供的

URL

[GET] https://api.map.baidu.com/reverse_geocoding/v3/

Query Params

释义
outputjson响应数据格式
coordtypewgs84ll坐标系统
ak0hYGiH3Ob5ZhV0eWzrGVXCD3bEdBCi6Laccess_key,使用scu自带的
location<经度>,<纬度>经纬度(float)

Response / Example

{
    "status": 0,
    "result": {
        "location": {
            "lng": 104.0790496319792,
            "lat": 30.641844458412959
        },
        "formatted_address": "四川省成都市武侯区一环路南2段-11号-附25号",
        "business": "跳伞塔,磨子桥,科华北路",
        "addressComponent": {
            "country": "中国",
            "country_code": 0,
            "country_code_iso": "CHN",
            "country_code_iso2": "CN",
            "province": "四川省",
            "city": "成都市",
            "city_level": 2,
            "district": "武侯区",
            "town": "",
            "town_code": "",
            "adcode": "510107",
            "street": "一环路",
            "street_number": "南2段-11号-附25号",
            "direction": "附近",
            "distance": "21"
        },
        "pois": [],
        "roads": [],
        "poiRegions": [],
        "sematic_description": "",
        "cityCode": 75
    }
}

疫情填报数据提交

URL

[POST] https://wfw.scu.edu.cn/ncov/wap/default/save

Data Form

以下表单内容仅由我个人信息得到,不一定囊括全部内容,且仅在2021-10-12与未来的一段时间内有效

类型默认值释义
zgfxdqint”0”是否在中高风险地区
mjryint”0”是否接触密接人员
csmjryInt”0”近14日内本人/共同居住者是否去过疫情发生场所
szxqmcstring""所在校区名称,从”江安校区”、“望江校区”与”华西校区”中选择
sfjzxgymint”0”是否接种新冠疫苗,“0”或”1”
jzxgymrqstring""接种第一剂新冠疫苗日期,日期格式:%Y-%m-%d
sfjzdezxgymint”0”是否接种第二剂新冠疫苗,“0”或”1”
jzdezxgymrqstring""接种第二剂新冠疫苗日期,日期格式:%Y-%m-%d
twint”1”体温范围(实际表单上的选项编号),“2”和”3”为正常
sfcxtzint”0”是否出现发热等症状,“0”或”1”
sfyyjcint”0”是否前往医院做过检查,如果sfcxtz为”1”需填写
jcjgqrint”0”检查结果,如果sfyyjc为”1”需填写。“1” => 疑似感染; “2” => 确认感染; “3” => 其他
jcjgstring""检查结果详细描述
sfjcbhint”0”是否接触无症状感染或疑似感染人群,“0”或”1”
jcbhlxint”0”接触人群类型,如果sfjcbh为”1”需填写,“1” => 疑似; “2” => 确诊
jcbhrqstring""接触时间,如果sfjcbh为”1”需填写,日期格式:%Y-%m-%d
sfcxzysxint”0”是否有疫情相关的情况,“0”或”1”
qksmstring""情况说明,如果sfcxzysx为”1”需填写
remarkstring""其他信息
sfzxint”1”是否在校
fxyystring""返校原因,sfxz为”1”时填写
bzxyystring""不在校原因,sfzx为”0”时填写
sfjcwhryint”0”是否接触武汉人员
sfjchbryint”0”是否接触河北人员
sfcyglqint”0”是否处于观察期
gllxint”0”观察场所(实际表单上的选项编号),如果sfcyglq为”1”需填写
glksrqstring”0”观察开始时间,日期格式:%Y-%m-%d
ismovedint”0”所在区域是否变化
bztcyyint”0”不在同一城市的原因(实际表单上的选项编号),ismoved为”1”时需填写
sftjhbint”0”是否途径河北
sftjwhint”0”是否途径武汉
szcsstring""所在城市,例:“成都市”
szgjstring""所在国家,例:“中国”
citystring""所在城市,例:“成都市”
provincestring""所在省,例:“四川省”
areastring""所在地区,例:“四川省 成都市 武侯区”
addressstring""具体所在地点,例:“四川省成都市武侯区望江路街道四川大学四川大学望江校区研究生院”
datestring""今日日期,日期格式:%Y%m%d
createdint0表单创建的时间戳
uidint0用户唯一标识
idint0当前表单的标识
geo_api_infojson/string""地理位置的详细信息,通过百度地图API获取

Response / Example

{
    "zgfxdq": "0",
    "mjry": "0",
    "csmjry": "0",
    "szxqmc": "望江校区",
    "sfjzxgym": "1",
    "jzxgymrq": "2021-xx-xx",
    "sfjzdezxgym": "1",
    "jzdezxgymrq": "2021-xx-xx",
    "tw": "2",
    "sfcxtz": "0",
    "sfjcbh": "0",
    "sfcxzysx": "0",
    "qksm": "",
    "sfyyjc": "0",
    "jcjgqr": "0",
    "remark": "",
    "address": "四川省成都市武侯区望江路街道四川大学四川大学望江校区研究生院",
    "geo_api_info": "{...}",
    "area": "四川省 成都市 武侯区",
    "province": "四川省",
    "city": "成都市",
    "sfzx": "1",
    "sfjcwhry": "0",
    "sfjchbry": "0",
    "sfcyglq": "0",
    "gllx": "",
    "glksrq": "",
    "jcbhlx": "",
    "jcbhrq": "",
    "bztcyy": "1",
    "sftjhb": "0",
    "sftjwh": "0",
    "szcs": "",
    "szgj": "",
    "bzxyy": "",
    "jcjg": "",
    "hsjcrq": "",
    "hsjcdd": "",
    "hsjcjg": "0",
    "date": "20211011",
    "uid": "2134xxx",
    "created": 1633881623,
    "jcqzrq": "",
    "sfjcqz": "",
    "szsqsfybl": 0,
    "sfsqhzjkk": 0,
    "sqhzjkkys": "",
    "sfygtjzzfj": 0,
    "gtjzzfjsj": "",
    "fxyy": "开学返校",
    "id": 4365xxxx,
    "gwszdd": "",
    "sfyqjzgc": "",
    "jrsfqzys": "",
    "jrsfqzfy": ""
}

uidid的获取

从以上表单数据可以看出,uid为用户的唯一标识,我已测试过多次,对于同一用户的不同次提交,该字段未有变化。

id根据我的猜测,可能是指表单创建的序号,从1开始自增的编号。

该猜测还在测试中。

一份可用的geo_api_info

对于川大望江校区的学生,这里有一份整理好可用的geo_api_info

{
    "type": "complete",
    "position": {
        "Q": 30.630839301216,
        "R": 104.079966362848,
        "lng": 104.07997,
        "lat": 30.630839
    },
    "location_type": "ip",
    "message": "Get ipLocation success.Get address success.",
    "accuracy": null,
    "isConverted": true,
    "status": 1,
    "addressComponent": {
        "citycode": "028",
        "adcode": "510107",
        "businessAreas": [
            {
                "name": "跳伞塔",
                "id": "510107",
                "location": {
                    "Q": 30.636149,
                    "R": 104.071224,
                    "lng": 104.071224,
                    "lat": 30.636149
                }
            },
            {
                "name": "小天竺",
                "id": "510107",
                "location": {
                    "Q": 30.639354,
                    "R": 104.068942,
                    "lng": 104.068942,
                    "lat": 30.639354
                }
            }
        ],
        "neighborhoodType": "科教文化服务;学校;高等院校",
        "neighborhood": "四川大学",
        "building": "",
        "buildingType": "",
        "street": "科华北路",
        "streetNumber": "194号",
        "country": "中国",
        "province": "四川省",
        "city": "成都市",
        "district": "武侯区",
        "township": "望江路街道"
    },
    "formattedAddress": "四川省成都市武侯区望江路街道四川大学四川大学望江校区研究生院",
    "roads": [],
    "crosses": [],
    "pois": [],
    "info": "SUCCESS"
}

需要注意的是:

一个猜想

对于现有的表单设计,只用了uid一项字段来唯一标识一名用户,而且根据我的uid内容,可以认为所有uid的内容都为较小的整形数。也就是说,也许可以暴力的遍历所有小整数,从而获取有效的uid

自动打卡脚本示例

cookies_strhttps://wfw.scu.edu.cn/ncov/wap/default/index 获取

以下内容仅作参考

# -*- coding: utf-8 -*-
import re
import json
import time
import datetime
import requests


# handle cookies and init session
def init_session(cookies_str: str) -> requests.Session():
    cookies_dict = {}
    for line in cookies_str.split(';'):
        key, value = line.split('=', 1)
        cookies_dict[key] = value

    session = requests.session()
    cookiesJar = requests.utils.cookiejar_from_dict(
        cookies_dict,
        cookiejar=None, 
        overwrite=True
    )
    session.cookies = cookiesJar
    return session


# get default json with uid and id
def get_default_json(session: requests.Session) -> tuple:
    url = 'https://wfw.scu.edu.cn/ncov/wap/default/index'

    resp = session.get(url=url)

    if resp.status_code != 200:
        print('[ERROR]', resp.status_code)
        exit()

    html = resp.content.decode('utf-8')

    pattern = re.compile('var def =(.*);!?')

    res = re.findall(pattern, html)
    if len(res) == 0:
        print('[ERROR] not found')
        exit()

    res_json = json.loads(res[0])
    return session, res_json


# load default geo_api_info
def modify_json(res_json: dict) -> dict:
    with open('geo_api_info.json', 'r') as ifile:
        res_json['geo_api_info'] = json.load(ifile)

    res_json['province'] = res_json['geo_api_info']['addressComponent']['province']
    res_json['city'] = res_json['geo_api_info']['addressComponent']['city']
    res_json['address'] = res_json['geo_api_info']['formattedAddress']
    res_json['area'] = ' '.join([
        res_json['province'],
        res_json['city'],
        res_json['geo_api_info']['addressComponent']['district']
    ])
    res_json['date'] = datetime.datetime.now().strftime("%Y%m%d")
    res_json['created'] = int(time.time())
    res_json['ismoved'] = 0
    return res_json


def post_json(session: requests.Session, res_json: dict):
    url = 'https://wfw.scu.edu.cn/ncov/wap/default/save'
    resp = session.post(url=url, data=res_json)
    print(resp.status_code, resp.content.decode('utf-8'))


if __name__ == '__main__':
    cookies_str = 'eai-sess=xxx; UUkey=xxx'
    session = init_session(cookies_str)
    session, res_json = get_default_json(session)
    res_json = modify_json(res_json)
    post_json(session, res_json)

分享这篇文章:
通过邮件分享这篇文章

分享到微信

微信对普通网页没有开放通用直连分享协议。更稳妥的方式是复制链接、扫码打开,或在支持的设备上调用系统分享。

上一篇
贪心的猴子
下一篇
快速反平方根算法