CQUT APP , treat or trick ?

  • 内容
  • 评论
  • 相关

今天早上起来得知学校发布了官方的APP,随便刷了几下后发现功能全面的比以往都要多,包含了校园卡信息以及课程信息等等。想想之前光一个教务系统写爬虫都要死不活的,这会儿突然这么多功能应该是开放了接口,于是开始折腾抓接口,顺便折腾折腾这荒废掉的时光。

0x00 开刀开刀!

通过反编译发现APK没壳没混淆,而且看着中文的Package名一种莫名的违和感。。。

QQ截图20160616213436

反编译AndroidManifest,找APP入口,以及一些关键字,及其对应的Activity,以便下手分析。从XML获取到的信息来看,程序会执行LoginActivity进行登陆,于是找到对应的Class,然而不太走运的是貌似因为我很久没更新反编译工具了,关键部分的代码全部是error,找不到一点有用的东西。于是干脆导出源代码从Eclipse找重点(其实是没有代码高亮看的不爽)

登录操作位于yh.app.tool.uiengine的Login类,被逼无奈之下还是看了错误的字节码来找点信息。看了半圈之后发现两个关键东西:Constant.number和Constant.code,然后定位到Constant类,顾名思义,常量类。打开以后Ctrl Alt H展开调用引用,发现一个可疑的用于初始化信息的类

QQ截图20160616214324

然而转到以后并没有什么卵用,代码显示只不过是从数据库初始化罢了,并没有其他的意思。然而对code字段同样操作后,得到另一个关键方法:getFunctionTicket,这个方法用于计算登录用的Ticket字段(类似于身份标识)

QQ截图20160616214448

然后很意外的得到了Ticket的算法。

QQ截图20160616214629

也就是说Ticket计算为:yunhua+学号+code+FunctionKey,我还在纳闷这个code是什么的时候,同在研究APP的大白说了一句,这个code是密码。

顺藤摸瓜,为了搞清楚FunctionKey是什么玩意儿,开承载网络当中间人抓包。至于抓包过程嘛因为没留记录,当时只顾着整理去了,所以就干脆留个结果吧

QQ截图20160616214939

可以看到,程序通过请求list.action来获取功能表,并且每个功能包含其名称,以及FunctionKey,等等。

对getLoginTicket执行引用查看,可以得知两个参数分别为学号和MD5后的密码。不再赘述。

通过抓包发现对功能的实际调用是在服务器端的302跳转。通过rout.action进行,此action角色类似于一个SSO,起到鉴权和真正功能指向的作用。

0x01 流程分析

好了,大致反编译完成以后这点东西也就比较明显了,其实APP并不复杂(其实是因为没混淆没壳2333333),而且这东西实在是太。。。。。忽悠了。至于为啥,放后面再说。

程序在打开以后要求进行登陆,输入学号和密码。初始密码为身份证后6位或者6个0。用户点击登陆以后,程序会进行两个请求,一个是请求login.action来获取学生的个人信息(学院,班级,学号,等等),然后请求list.action获取功能表以及对应的KEY。如果信息错误则无法获取这些信息,表现为错误信息“无权限访问”。login.action需求学号和密码,提交的密码为MD5(密码),list.action需求学号以及Ticket,Ticket算法为MD5("yunhua"+学号+MD5(密码))

list.action根据大白的描述并不是每次都会请求,因为正如之前所提到的,他在本地有一个SQLite数据库保存数据,这些菜单放在了SQLite进行缓存。

然后,对于每一个功能,根据其FUNCTION_TYPE决定其进行的操作。目前的列表中包含了两种(1或者2),根据情况可以推出,1指代Native或者第三方SDK功能,2指代WEB VIEW。

对于Web View的功能,APP请求rout.action,(GET方式),参数为function_id,学号,ticket,其中ticket算法为MD5(“yunhua”+学号+MD5(密码)+FunctionKey),服务器端SSO鉴权成功后进行302跳转到正式业务服务器(比如一卡通,等等)进行处理。在正式业务服务器中通过Cookie进行身份鉴权(因为SSO跳转的时候带了sid和ticket),否则提示无权限操作

0x02 不得不吐槽的东西

看完了上面的内容你应该知道我要吐槽什么了吧?

第一点:安全问题。

APP是今天才上线的,然而非常尴尬的是学校的初始密码为身份证后6位,这种乍一看非常安全的东西实际上并不安全。实际上,学校每次大型考试前都会发布一个表格,其中包含了身份证信息和学号姓名这些玩意儿,也就是说如果有心之人一开始就收集数据的话,要拉取用户的信息一点都不困难。

然而可以拉取的信息有哪些呢?校园卡消费记录、余额、考试信息、课程信息、图书信息、成绩。毫不夸张的说,一个晚上拉遍所有信息应该不成问题。(毕竟模拟登陆的API我写了不到3小时的样子

所以说学校在安全方面简直就是在感人。。。当然我估计也是考虑到初始密码没法好好玩,因为这套协议。。。这套协议本身就是明文密码取MD5,估计教务系统密码是带了SALT没法玩。

第二点:设计缺陷

不知道是不是外包公司的问题,这套Ticket协议在我看来其实本身就是一个缺陷比较明显的协议。

首先,综合第一点里面提到的,初始密码身份证后6位,加上在login.action用的密码为不加salt的MD5,那么任何一个想搞大新闻的都可以试图抓到数据后进行爆破。

其次,Ticket这种东西没有一个时间概念。简单来说,一个中间人只要抓到了一次所用的Ticket,那么后面这块内容只要原用户不改密码,服务器的FunctionKey不变,那么这个Ticket永久有效。

这个意思就是:假如某一天我为了追一个妹子故意中间人骗她登录APP以后抓到了这个Ticket,而不巧的是呢他正好是点的一卡通之类的东西,那我是不是可以搞什么“消费记录数据分析”推测她经常在哪里吃饭?然后经常去那里能看到她?最后用各种奇怪的方式让她惊呼“哇为什么每次都这么巧”然后赢取白富美走向人生巅峰?

Ticket本身应该是作为一个鉴权标志,应当带有其时效性才对,不然那些网站过几小时不活动就登出了难道是脑子有坑吗。。。。

此外,你们直接在list.action返回的内容里面,指定了具体负责操作的反射类和Package名称来完成具体任务。。。灵活倒是灵活,然而。。。。你们就不怕出事儿吗。。。。

而且我在实际抓包的时候你们Web View每一个rout.action都是双重请求啊卧槽!

第三点:学校你能好好上HTTPS嘛?

不是我说啥,校园卡消费记录,银行卡绑定,密码这些东西涉及到了,你还明文传输,真的大丈夫?

上次听说学校的人懒到SSL证书都懒得管了,说要签就签十年,不然学校没人管。然而现在普遍都是2-3年的时效,2-3年换一次证书真的就这么麻烦?学校万年IIS党X个证书也麻烦不到哪儿去吧?

啥?你跟我说备案?难不成备案了两年他就查不到了吗?

0x03 API LIST

域名:app.cqut.edu.cn 222.178.158.49(222.178.158.48)

Ticket计算:LoginTicket : MD5("yunhua" + number + code);

FunctionTicket : MD5("yunhua" + number + code + KEY)

number = 学号

code = MD5(密码)

1.软件更新:GET /UIA/update/updateVersion.action?mobileType=android&versionCode=120

返回: "{\"message\":\"\",\"update\":false}"

2.拉取菜单 : GET /UIA/function/list.action?userid=《学号》&ticket=《LoginTicket》&Version=1

返回示例:"{\"functionrow_2\":{\"FUNCTION_TYPE\":1,\"FUNCTION_ID\":20150116,\"CLASS_NAME\":\"yh.app.function.WisdomClass\",\"FUNCTION_NAME\":\"智慧课堂\",\"FUNCTION_FACE\":\"http:\/\/dc.app.cqut.edu.cn\/DC\/Image\/zhkt.png\",\"IOS_NOTICE\":\"segueForWisdomClass\",\"PX\":9,\"INTEGRATE_KEY\":\"AF067B8593174537853C4136586312CC\",\"PACKAGE_NAME\":\"yh.app.appstart.lg\",\"FUNCTION_TYBJ\":0},\"VERSION_NUM\":10}"

3.用户登录:POST  /UIA/login/login.action    userid=学号&password=原始密码MD5

返回:"[{\"usertype\":1,\"userinfo\":{\"ZYDM\":\"0306\",\"XBDM\":\"1\",\"TXDZ\":null,\"BMMC\":\"计算机科学与工程学院\",\"BJDM\":\"班级号码\",\"BMDM\":\"03\",\"SR\":null,\"ZYMC\":\"软件工程\",\"QQ\":null,\"SFZH\":\"身份证号码\",\"USERNAME\":\"姓名\",\"XBMC\":\"男\",\"NJDM\":\"2013\",\"MZMC\":null,\"MCDM\":null,\"DH\":null,\"USERID\":\"学号\"},\"islogin\":\"true\"}]"

4.功能表(Web View) : GET /UIA/rout/rout.action?userid=学号&function_id=<功能ID>&ticket=<FunctionTicket>

 

0x04 写在最后

不否认学校这次开明的上了APP来帮助教学。然而我还是希望老师们能够好好评估一下其中可能存在的风险。毕竟学校的系统各种漏洞已经多的不行了,某系统的权限漏洞2年前至今仍在,未被修复。

我就不想说各种抓照片抓XX记录的权限不严的碧油鸡了。毕竟你们喜欢吃的话,你们高兴就好。

我还是想起两年前,在信息处帮老师部署某网站的时候,我说了一句“隔壁学校教务系统被注入了”,然后旁边老师就在笑“什么年代了还玩注入,好笑”

然后我不知道就我们学校这千疮百孔的系统,如果这几年不是防火墙挡着的话,这个老师是不是真的还笑得出来。

骄傲,自大,嗯哼,这个学校从来都不少这种。

我非常高兴的是学校这次敢于跟上信息时代,并且推广。然而我希望你们对学生的信息负点责任,谢谢。

评论

7条评论
  1. Gravatar 头像

    执一 回复

    可以的,你问我滋瓷不滋瓷,我当然是滋瓷的。

  2. Gravatar 头像

    Mike Miao 回复

    然后老陈明天去校长办公室喝茶了,校长说,文章删了,再谈py交易

  3. Gravatar 头像

    蓝胖子 回复

    这两天主站改版了。看个新闻还需要权限,不知道谁想出来的。五分钟写个钓鱼,十分钟钓了20个账号。

  4. Gravatar 头像

    阿泽 回复

    陈大佬你好,SN新版有个小bug,就是注册的时候如果输错信息,验证码不会自动更新~大佬有时间可以改一下。

    向大佬学习!

  5. Gravatar 头像

    宋诗雨 回复

    我现在才知道我和chen大同一个学校?😱惭愧惭愧😂

发表评论

电子邮件地址不会被公开。 必填项已用*标注