记一次逆向某医院挂号软件的经历

news2024/10/5 6:19:58

背景

最近家里娃需要挂专家号的儿保,奈何专家号实在过于抢手,身为程序员的我也没有其他的社会资源渠道可以去弄个号,只能发挥自己的技术力量来解决这个问题了。

出师不利

首先把应用安装到我已经 Root 过的 Pixel 3 上面,点击应用图标打开的时候提示该手机已经Root过,请慎用,然后闪退,看来应该是加固保护做了 Root 检测了。

先截取下发送的数据请求,看下大致的流程。Android 7.0 以后,应用不会信任用户安装的根证书了,所以要抓包要么把根证书加到系统证书目录,要么就是通过Hook的手段强行绕过证书,我这边选第二种方法。安装 TrustmeAlready 以后,在 Lsposed 里面配置绕过证书。
 

顺利抓到数据。 

接下来就是分析参数,这里面多数接口的信息都是比较明确的,比如获取医生信息、就诊信息等,基本上都是明文的信息,这些略过不表。比较关键的是一些涉及用户信息的,比如 tempCustId 以及 userCustId ,从实践来看,tempCustId 应该是就诊人的 ID,而 userCustId 应该是账号登录的人的 ID,因为可以登录自己账号帮别人挂号,这个也是合理的。然后 appKey 应该是登录的 token 信息,这边实践也是证明每次登录都是不一样的。最后有个关键的是 uuid,看起来就是平时理解的 uuid,可以到时候尝试随机生成试下。好了,基本参数分析完以后,开始构造参数来模拟请求,看看对不对。

很不幸,失败了。从尝试来看,唯一影响的就是上面的 uuid,因为从抓包的请求中扣下来填入模拟请求的话,这个请求是成功的,但是自己随机构造的话,就是失败的。看起来这个 uuid 应该涉及到一些加密算法的校验,解密失败在服务端认为异常的请求。

 所以开起来还是要分析源代码看下这个参数的构建过程,使用 JADX 打开,看下源代码。

使用了阿里的加固方案,而且是把 Dex 转成了 SO 的文件,然后在运行时使用自定义的 ClassLoader 去加载的,看来要解决这个问题还是要先脱壳了。暂时先止步于此。

柳岸花明

等等!在再次查看抓包的数据,发现在请求的过程中加载了大量的 HTML 的文件,所以我猜测这个 APP 只是一个套壳的网页应用,在分析可能的入口网址后,我拿地址在网页中打开。果然,跟我想象的一样。

 那么 uuid 的生成是否可能在网页应用的源码里面呢,打开 devtools 尝试搜索 uuid 相关的字符串,果然找到了相应的代码。

至此,搞定了 uuid 的生成逻辑,距离成功又迈进了一大步。

最后的守卫

现在距离最后的成功还差一步,就是在发起预约的时候,有个图形验证码需要校验。

 通过多次调用请求图形验证码的接口,我发现它生成的规则比较固定,基本都是数字的组合,而且有一点就是,数字在图片上的布局也是固定的。所以这个地方如果用TensorFlow去做识别就比较简单了。

首先收集数据集。 

然后对采集到的数据做标注提取以及灰度化处理。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

def paa(file):

    img = Image.open(file).convert('L'# 读取图片并灰度化

    img = img.crop((01010036)) # 120*44图片裁剪为100*26

    # 分离数字

    img1 = img.crop((001926)) # 单个数字图片大小为19*26

    img2 = img.crop((3004926))

    img3 = img.crop((6007926))

    img4 = img.crop((8009926))

    img1 = np.array(img1).flatten() # 扁平化,把二维弄成一维度

    img1 = list(map(lambda x: 1 if x <= 180 else 0, img1))

    img2 = np.array(img2).flatten()

    img2 = list(map(lambda x: 1 if x <= 180 else 0, img2))

    img3 = np.array(img3).flatten()

    img3 = list(map(lambda x: 1 if x <= 180 else 0, img3))

    img4 = np.array(img4).flatten()

    img4 = list(map(lambda x: 1 if x <= 180 else 0, img4))

    return (img1, img2, img3, img4)

单张图片采集出来的数字图片。

构建拟合函数并保存训练模型。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

import tensorflow.compat.v1 as tf

tf.compat.v1.disable_eager_execution()

from data import train_images, train_labels

DLEN = len(train_images.data[0])

DNUM = len(train_images.data)

= tf.placeholder(tf.float32, [None, DLEN])

= tf.Variable(tf.zeros([DLEN, 10]))

= tf.Variable(tf.zeros([10]))

= tf.nn.softmax(tf.matmul(x, W) + b)

y_ = tf.placeholder("float", [None10])

cross_entropy = -tf.reduce_sum(y_*tf.log(y))

train_step = tf.train.GradientDescentOptimizer(0.001).minimize(cross_entropy)

saver = tf.train.Saver()

sess = tf.Session()

sess.run(tf.global_variables_initializer())

for in range(DNUM):

    batch_xs = [train_images.data[i]]

    batch_ys = [train_labels.data[i]]

    sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})

correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))

accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

saver.save(sess, 'model/model')

sess.close()

验证下训练的模型。

 

告捷

最后模拟请求发送,完成预约挂号。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1032980.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

共享剪切板小工具

共享剪切板小工具 使用场景&#xff1a;手机/平板/其他设备发送消息到电脑剪切板。使用于电脑不能联网或者不方便使用微信等其他方式发送文字。例如&#xff1a;不能跳出当前页面可以通过其他设备直接发送到剪切板上&#xff0c;ctrlV 完美 使用限制&#xff1a;目前仅支持在局…

大数据——Spark SQL

1、Spark SQL是什么 Spark SQL是Spark中用于处理结构化数据的一个模块&#xff0c;前身是Shark&#xff0c;但本身继承了前身Hive兼容和内存列存储的一些优点。Spark SQL具有以下四个特点&#xff1a; 综合性(Integrated)&#xff1a;Spark中可以加入SQL查询&#xff0c;也可…

啥子是DOM???总听,不晓得啥

远古时代&#xff0c;浏览器加载完HTML页面就没了&#xff0c;也就是加载一个文本。 但是之后JS出现&#xff0c;要修改HTML文本&#xff0c;这么大的文本&#xff0c;你咋晓得要修改那个地方&#xff1f;就算修改完了浏览器还要在重新解析加载一遍&#xff0c;耗时耗性能啊&a…

oracle11g-图形安装(centos7)

目录 一.环境准备1.关闭防火墙2.关闭SELINUX3.配置本地yum源4.安装ORACLE先决条件的软件包5.修改LINUX的内核文件6.添加下列参数到/etc/security/limits.conf7.添加下列条目到/etc/pam.d/login8.环境变量中添加下列语句9.创建文件目录和相应的用户10.配置oracle用户的环境变量1…

Java笔记:垃圾回收

1 判断算法垃圾 主要是2种&#xff1a;引用计数法和根搜索算法 1.1 引用计数法&#xff08; Reference Counting&#xff09; 1. 概念 给对象中添加一个引用计数器&#xff0c;每当有一个地方引用它时&#xff0c;计数器值就加1&#xff1a;当引用失效时&#xff0c;计数器值…

【Linux】系统编程生产者消费者模型(C++)

目录 【1】生产消费模型 【1.1】为何要使用生产者消费者模型 【1.2】生产者消费者模型优点 【2】基于阻塞队列的生产消费者模型 【2.1】生产消费模型打印模型 【2.2】生产消费模型计算公式模型 【2.3】生产消费模型计算公式加保存任务模型 【2.3】生产消费模型多生产多…

行行AI人工智能大会 | LTD荣获“AI强应用创新TOP50代表企业”

LTDAI重新定义下一代网站。9月20日&#xff0c;由行行AI和见实科技、梅花创投联合主办&#xff0c;以“强应用多模型——人工智能落地大潮”为主题的“2023年度见实大会”在京顺利召开。 9月20日&#xff0c;由行行AI和见实科技、梅花创投联合主办&#xff0c;以“强应用多模型…

python使用apscheduler每隔一段时间自动化运行程序

apscheduler使用比较简单&#xff0c;每隔一段时间自动化运行的步骤是&#xff1a; 创建调度器scheduler BlockingScheduler()添加任务scheduler.add_job(函数名, interval, minutes30) # 每隔30分钟运行一次直接执行&#xff1a;scheduler.start()示例代码 from datetime i…

一花落,万物生,AIGC为国货复兴注入新活力

在最近的商业新闻中&#xff0c;国货们发“花难财”的热度持续在涨&#xff0c;“花西子”曾经是中国国货的代表之一&#xff0c;以其独特的美妆产品而闻名于世。然而&#xff0c;近期因为李佳琦“79块钱哪里贵了”事件的原因&#xff0c;让不少网友扒出这支79的眉笔算下来一克…

BeanUtils.copyProperties的使用场景

1. 常见场景 我们如果有两个具有很多相同属性名的JavaBean对象a和b&#xff0c;想把a中的属性赋值到b&#xff0c;例如 接口中将接收到的前端请求参数XxxReqVo,我们想把这个入参转化为XxxQuery对象作为数据库的查询条件对象 传统做法是手动set&#xff0c;即 XxxBean xxxBea…

算法笔记——循环链表

带环链表 算法题中&#xff0c;会有一种题目让我们去判断链表里的是否有循环。 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 这里就需要我们要用快慢指针来进行搜索&#xff0c;直接提供代码 class Solution { public:bool hasCycle(ListNode *…

zabbix自定义监控、钉钉、邮箱报警

目录 一、实验准备 二、安装 三、添加监控对象 四、添加自定义监控项 五、监控mariadb 1、添加模版查看要求 2、安装mariadb、创建用户 3、创建用户文件 4、修改监控模版 5、在上述文件中配置路径 6、重启zabbix-agent验证 六、监控NGINX 1、安装NGINX&#xff0c…

抖音seo源码关键词霸屏搜索

抖音seo源码mvg框架依据关键词霸屏搜索引擎机制技术代开发&#xff0c;抖音seo优化系统&#xff0c;抖音seo优化系统最终也是类比百度seo关键词霸屏搜索引擎来搭建&#xff0c;从短视频ai创意制作&#xff0c;发布&#xff0c;多账号平台管理。 1&#xff1a;抖音SEO霸屏系统的…

在对bbox 进行坐标系转换时heading的处理--使用向量的旋转

实际做题中我们可能会遇到很多有关及计算几何的问题&#xff0c;其中有一类问题就是向量的旋转问题&#xff0c;下面我们来具体探讨一下有关旋转的问题。 首先我们先把问题简化一下&#xff0c;我们先研究一个点绕另一个点旋转一定角度的问题。已知A点坐标(x1,y1)&#xff0c;…

打开常用软件出现msvcp140.dll丢失的解决方法,msvcp140.dll是什么东西?

在我们使用计算机的过程中&#xff0c;有时候会遇到一些错误提示&#xff0c;其中“找不到 msvcp140.dll”就是比较常见的一种。那么&#xff0c;msvcp140.dll 到底是什么呢&#xff1f;为什么会出现找不到的情况&#xff1f;丢失 msvcp140.dll 又会对计算机产生什么影响&#…

Flask配合Echarts写一个动态可视化大屏

ch 技术 后端&#xff1a;flask 可视化&#xff1a;echarts 前端&#xff1a;HTMLJavaScriptcss 大屏布局 大屏拆分 案例项目中大屏可按版块进行拆解&#xff0c;会发现这里大屏主要由标题、折线图、柱状图、地图、滚动图和词云等组成&#xff0c;整体可切分为8个版块&…

RK358支持全链路ECC的DDR和普通内存有何区别?

ECC内存&#xff08;ErrorCorrection Code Memory&#xff09;和普通内存是计算机存储技术中常见的两种类型的内存。它们在设计和功能上有一些重要区别。接下来我们将详细解释ECC内存和普通内存&#xff0c;并列举它们之间的区别以及ECC内存的纠错原理。 普通内存通常被称为非E…

MQ - 16 集群篇_分布式集群的数据一致性方案

文章目录 导图Pre分区、副本和数据倾斜副本间数据同步方式同步复制异步复制CAP 和一致性模型集群数据一致性和可靠性实现ZooKeeper 数据一致性和可靠性Kafka 数据一致性和可靠性Pulsar 数据一致性和可靠性总结导图 Pre MQ - 14 集群篇_如何构建分布式的消息队列集群&#

FOXBORO FBM233 P0926GX控制脉冲模块

FOXBORO FBM233 P0926GX 是一种控制脉冲模块&#xff0c;通常用于工业自动化和控制系统中。这个模块的主要功能是生成和控制脉冲信号&#xff0c;以用于执行特定的操作或控制过程。以下是可能适用于 FOXBORO FBM233 P0926GX 控制脉冲模块的一些常见特点&#xff1a; 脉冲生成&a…

【力扣-每日一题】213. 打家劫舍 II

class Solution { public:int getMax(int n,vector<int> &nums){int a0,bnums[n],c0;for(int in1;i<nums.size()n-1;i){ //sizen-1,为0时&#xff0c;第一个可以偷&#xff0c;最后一个不能偷size-1&#xff1b;n为1时&#xff0c;最后一个可偷&#xff0c;计算…