漠漠帆来重,冥冥鸟去迟。——韦应物《赋得暮雨送李胄/赋得暮雨送李曹》 楠少博客 阅读文章 慧职教破解-自动签到 楠少 2019-09-09 6666666 8888888 实习 慧职教 抓包 接口 破解 摘要大学最后一学年了,本应该下学期实习的,由于种种原因,学校教学计划调整了,我们就被安排了,这学期外出实习,下学期回校上课。 **目录 (Table of Contents)** [TOC] ### 说明:由于本博客不是操作过程中写下,没有留下相关截图、抓包等数据。 ## 起因 大学最后一学年了,本应该下学期实习的,由于种种原因,学校教学计划调整了,我们就被安排了,这学期外出实习,下学期回校上课。~~校方这一决定受到了无数学生的支持。~~ 实习期间,检测学生实习状态的就靠今天要说的这一软件了,叫“慧职教”。百度百科未收录,AppStore上显示开发者主体为 “广州市德慷电子有限公司” 这里也不过多介绍了。 学校要求:签到、提问、周记、月记、总结(实习过程两个月) + 签到:工作日每天签到,一天只能签到一次,要求在定位一公里内,周末不能签到。 + 提问:两次以上。 + 周记:每周一篇,限定时间,限制字数步得少于150,限制复制粘贴。只可以提交前一周、当前周、下一周的周记,错过时间,官方软件不提供添加方法。 + 月记:每月一次,一共两次。 + 总结:实习快结束时添加,有字数要求、无查重。 先不说别的,每天都打卡签到 还要在指定区域,太麻烦了ba。 遂 搞之。 ## 过程 ![签到页面模拟器截图](https://ae01.alicdn.com/kf/H6f5cea843c1e49e1bb71bc7e298b8e6bC.png "签到页面模拟器截图") (图为签到页面模拟器截图,已开启虚拟定位) 今天是实习要求日期第一天,早上出去办点事,回来的时候室友已经开搞了(因为我们很早就聊过这个,都是就要搞个脚本每天自动签到的)。咱们先反编译了安卓版的安装包,扒了扒源码,签到的时候抓了个包 签到地址为:`http://gzdk.gzisp.net:8082/sign/addSignIn?time=&ADDR=&AXIS=&CONTENT=&IDS=&ISEVECTION=0&SCALE=18&authorization=&token=` 经过数次尝试,发现实际需要参数只有:`ADDR={}&AXIS={}-{}&SCALE=18&authorization={}&ISEVECTION=0` `ADDR`: 位置文本,即签到后列表显示的文本,未发现有其他用处。 `AXIS`:经纬度信息,格式:Y-X,官方软件中判断距离使用,未发现其他用处。 `authorization`:值于token相同,用于身份验证。 `ISEVECTION`:是否出差,0为否。 日前有过提交实习信息,所以身份是已经登录的,这也导致了我们在寻找`authorization`参数时,爬了很多坑。 首先,我们认为这个参数是签到时根据某些特定加密算法,混合多个参数参与加密而生成的值,于是我们扒拉安卓apk反编译代码,找到吐血也没有找到相关有价值的信息。 事实上是我们高估他的安全性了,而实质上该系统安全性也确实差。 我们尝试了一次登录抓包,发现了 token 、authorization值的来源,原来它在登录的时候,服务器端就已经返回了,并且后期不会发生变化(因为后期将软件后台清理掉重新打开时,没有检测到重新登录的网络请求),属实有点尴尬。 登录接口 :`http://gzdk.gzisp.net/api/authenticateNew` 请求方法:POST 必要参数 : "username": 登录用户名,一般学生为学号,教职工为教工号 "password": 登录密码 "schoolId": 学校id 登录失败返回结果: ```JSON { "res": "err", "desc": "登陆失败,密码错误!" } ``` 登录成功返回结果: ```JSON { "res": "succ", "data": { "userName": "{{登录用户姓名}}", "sysVersion": "1", "userId": "{{可能是数据库表id}}", "userType": "STUDENT", "schoolId": "37", "sex": null, "organName": null, "gradeTypeVersion": "0", "differentMap": "{\"gradeTypeVersion\":\"0\",\"indexType\":\"base\"}", "id_token": "{{很长的一段token,用于身份验证,varchar(255)存放不下}}" } } ``` "res" 返回登录结果 失败会返回字段 "desc" 失败详情 成功会返回数据集合 "data" 有价值、后期可以用得到的参数为:`userName`、`userId`、`id_token` 安全性差还体现在 所有的业务逻辑判断,只在前台做了判断,后端均没有验证,也就是说,从目前所有我们抓到的接口来看,只要必要值存在,值是否合理,逻辑是否合理,都是不管的,你往接口传参数,后端便加入数据库,2333. 在安卓扒反编译代码的过程中,发现这个软件,很多地方都是直接使用webview嵌套的网页,使用腾讯的开源组件`TBS`,系统登录入口网址: [`http://gzdk.gzisp.net/hzjmui/mui/login.html`](http://gzdk.gzisp.net/hzjmui/mui/login.html "登录入口地址") 进入这个网址后,你会发现,和移动端就是一模一样。 有网页端的话,那数据抓包就简单多了啊。 ## 抓包结果 这里就不多说过程了,直接把各种接口整理一下吧。 ### 登录 地址:http://gzdk.gzisp.net/api/authenticateNew 请求方法:POST 必要参数: "username": 登录用户名,一般学生为学号,教职工为教工号 "password": 登录密码 "schoolId": 学校id 登录失败返回结果: ```JSON { "res": "err", "desc": "登陆失败,密码错误!" } ``` 登录成功返回结果: ```JSON { "res": "succ", "data": { "userName": "{{登录用户姓名}}", "sysVersion": "1", "userId": "{{可能是数据库表id}}", "userType": "STUDENT", "schoolId": "37", "sex": null, "organName": null, "gradeTypeVersion": "0", "differentMap": "{\"gradeTypeVersion\":\"0\",\"indexType\":\"base\"}", "id_token": "{{很长的一段token,用于身份验证,varchar(255)存放不下}}" } } ``` ### 获取签到列表(历史签到记录) 地址:http://gzdk.gzisp.net:8082/sign/getMyCheckinSubList 请求方法:GET 参数:authorization 登录请求返回的 id_token 返回结果 ```JSON { "res": "success", "data": [{ "THEME": "校外实习考勤签到", "DESCRIBE": "企业项目开发、PHP项目开发、Golang项目开发、Python项目开发。", "ADDRESS": "江苏省 扬州市 经济开发区吴洲东路198号104幢", "STARTDATE": "2019-09-09 00:00:00", "ENDDATE": "2019-11-01 00:00:00", "locationX": 119.444725, "locationY": 32.339367 }, [ { "content": "\"null\"", "id": 436495, "internshipId": "{{校内指导老师id}}", "isEvection": false, "label": "江苏省 扬州市 经济开发区吴洲东路198号104幢", "locationX": 32.339367, "locationY": 119.444725, "scale": 18, "sendTime": "2019-09-09 13:50:15", "studentId": "{{userid}}", "subContent": "按照学校教务规定,本校校外实习的同学要每天在指定位置上签到。此记录当作实习考勤备份在学校学生档案中……", "subTitle": "校外实习考勤签到" }] ], "dataid": "6786865654", "header": { "curpage": 1, "errmsg": "", "errno": "", "pageSize": 100, "res": "", "total": 12, "totalpage": 1 } } ``` res 请求结果 data 数组, [0] 填写实习信息时的相关参数。签到接口中的经纬度可直接从此获取。 [1] 数组,包含所有签到结果。 ### 签到 地址:http://gzdk.gzisp.net:8082/sign/addSignIn 请求方法:GET 必要参数 ADDR 位置文本信息 AXIS 位置经纬度 格式:{Y}-{X} 值为18 具体含义不了解,不加报错:java.lang.reflect.InvocationTargetException authorization 身份验证,值为登录请求时的id_token ISEVECTION 是否出差 0 为否 错误返回结果 ```JSON { "res": "err", "desc": "方法调用失败,请检查请求数据合规性", "errormsg": "java.lang.reflect.InvocationTargetException" } ``` 正确返回结果 ```JSON { "res": "success", "dataid": "6786865654" } ``` 目前就这么多,后有再补。 ## 总结 整体效果做完了,放到了服务器上,供同学使用,蛮方便的。 地址 http://hzj.nanshaobit.top/ 1 请求登录接口 获取id_token、userid 2 请求签到列表接口 获取签到时所需要的ADDR、locationX、locationY 3 请求签到接口 提交签到记录 app使用的是腾讯TBS签到了一个webview,而该web定位又是使用百度地图的sdk,使用百度坐标系,当然你直接用签到列表的数据就不用考虑这些了,至于火星坐标系还是啥其他的 就不用管了。 将签到接口提取出来,写成了一个python文件,放在服务器上,系统定时任务自动运行,美滋滋。 ### End 上一篇:IIS 反向代理 header location问题 下一篇:【爬坑】iOS端对select标签有独特的适配,如何取消这些默认样式呢 文章评论 [ 聊聊技术 聊聊自己 ] 在巴甫洛夫条件反射 试验中:给定一条狗,每次摇铃后喂食,足够次数后,狗则听到铃声将会习惯性的分泌唾液,由此引发对铃声的依恋。延伸到实际,给定一个喜欢的妹子,每次见面赠与巴甫洛夫式 的礼品或者零食,由此引发妹子的依恋。引入薛定谔的猫 理论,在未表白前,妹子与自己一直处于一种“概率云”的状态,一旦表白则“概率云”将消失成为实际。在 巴甫洛夫式 后且未表白前,自己与妹子的关系为“既是恋人又不是恋人”的矛盾体。返回巴甫洛夫式 试验中,在妹纸形成足够的依恋过后,则可以打破薛定谔 “概率云”的状态。这个谜一样的自己,这一刻 薛定谔 附体,带着量子论般深沉的哀愁,让她从此不能自拔! 自此创作 巴甫洛夫薛定谔把妹法,深藏功与名。