本文仅供技术学习与交流,请勿用于违反校规校纪的行为。
前言
学校使用的智慧学工考勤系统要求学生在指定时间、指定地点进行 GPS 打卡签到。出于对移动端安全和 Web 接口逆向的学习兴趣,我对该系统的签到流程进行了分析,并编写了一个 Android 应用来复现整个过程。
系统分析
签到流程拆解
通过抓包分析,整个考勤签到系统的核心流程如下:
登录认证 → 获取课程列表 → 获取打卡任务 → 提交签到(经纬度 + 精度)GPS 定位验证机制
系统前端使用了一个 geoDistance2Ranges 函数,基于 GCJ-02 坐标系计算用户位置与目标点之间的距离。关键发现:
- 定位验证仅在客户端(JavaScript)执行,服务端并不会二次校验 GPS 坐标的合理性
- 签到接口直接接收客户端 POST 的
latitude、longitude、accuracy参数 - 照片字段(
photo)同样不做强制校验
这意味着只要构造合法的 HTTP 请求,就可以提交任意坐标完成签到。
登录认证流程
登录并非简单的账号密码验证,而是一套与微信绑定的多步骤流程:
1. POST 姓名 + 学号 + 验证码 → 返回中间页(stop page)
2. 从中间页提取微信扫码登录链接
3. 用户在微信中打开链接完成授权
4. 轮询检测登录状态 → 获取重定向 URL
5. 跟随重定向拿到最终 Session Cookie其中有个坑:服务端返回的重定向 URL 是 JSON 格式,其中 / 被转义为 \/,直接使用会导致路径出现双斜杠 //,需要手动 unescape。
技术实现
技术栈
| 组件 | 技术选型 |
|---|---|
| 语言 | Kotlin |
| 网络请求 | OkHttp3 + 自定义 CookieJar |
| HTML 解析 | Jsoup |
| UI 框架 | Material Design 3 |
| 本地存储 | SharedPreferences |
| 异步处理 | Kotlin Coroutines |
核心模块
PunchApi.kt — 网络层封装
负责所有与服务端的交互,包括:
- Session 管理:自定义
CookieJar跨域持久化 Cookie - 登录流程:处理验证码获取、表单提交、微信 QR 链接提取、登录状态轮询
- 签到提交:构造 POST 请求发送自定义经纬度
为了绕过服务端的 UA 检测,请求头模拟了完整的浏览器指纹(User-Agent、Referer、Origin 等)。
MainActivity.kt — UI 与业务逻辑
采用单 Activity 多 View 的架构,通过控制 loginView、guideView、mainContent 三个视图的显隐来实现页面切换:
- 登录页:输入姓名、学号、验证码
- 引导页:展示微信登录链接,提供一键复制功能,实时显示轮询状态
- 主页面:GPS 坐标设置、预设管理、课程打卡列表、签到历史
PrefsManager.kt — 本地持久化
使用 SharedPreferences 存储:
- 登录凭证(Cookie),实现免登录
- GPS 预设位置列表
- 签到历史记录
关键代码片段
签到请求的核心就这几行:
val formBody = FormBody.Builder()
.add("latitude", lat.toString())
.add("longitude", lng.toString())
.add("accuracy", "65.0")
.add("photo", "")
.build()
val request = Request.Builder()
.url("$BASE_URL/student/course/$courseId/punch/$punchId")
.header("User-Agent", UA)
.post(formBody)
.build()服务端只看这几个字段,没有任何额外的签名或设备指纹校验。
功能一览
- 学生身份登录(姓名 + 学号 + 验证码)
- 微信扫码授权登录
- 登录状态持久化,下次打开免登录
- 自定义 GPS 经纬度进行签到
- GPS 预设位置管理(添加 / 删除 / 快速切换)
- 课程列表与打卡任务查看
- 签到历史记录本地保存
- 退出登录
安全声明
本应用:
- 未接入任何第三方 SDK 或接口
- 未收集、上传、存储用户的任何个人信息
- 所有数据仅在用户设备本地保存
仅与以下两个域名通信:
https://wx703c2206450720dd.g8n.cn(考勤系统)https://login.b8n.cn(登录认证)
源码
仓库地址(私有):http://43.136.67.174:9999/aven/GPSPunchApp
写在最后
这个项目的目的是学习移动端逆向和 Web 接口分析,整个过程涉及到了抓包分析、Cookie 会话管理、HTML 解析、多步骤登录流程处理等实用技术。
从安全角度来看,该考勤系统存在明显的设计缺陷 — 将关键校验逻辑放在客户端而非服务端。对于开发者而言,这是一个很好的反面教材:永远不要信任客户端提交的数据。
开发者:凡笙