最近把原来的499 kindle卖掉了,换成了国内掌阅出的ireader plus(999),掌阅的性价比的确高一点,比(800)kwp3配置看起来高了一些。然而书城资源上,kindle的生态比掌阅好了很多。
我的主要阅读是非休闲的书籍,而且专业书籍一般也不从kindle上买,所以ireader plus更适合我的情况。
但是,ireaderp官方没有放出附件包,提供的服务也不能和kindle比,比如邮件推送,比如公众号推送等等。
了解到ireader是基于android 4.4进行“深度定制”的,但是和pc在相连的时候,是通过MTP协议,而且默认是关闭了usb调试的,万能的国民发现在开机时候,某个时刻点击右上角会弹出android系统自己的设置,并开启usb调试,这样,就可以通过adb连接pc。
但是点击的时机把握太重要了,我点了好多好多次,只点出来一次。
开启usb调试以后,就可以通过adb安装apk,ireader的一个破解群,也提供了一个桌面apk和切换桌面的epub文档。而我唯一点出的一次,竟然鬼使神差在系统设置里把桌面设置成了掌阅默认的。也就没法切换了。
于是想通过别的方法来开启。
通过MTP挂载的文件里,发现有个jar包,从文件夹路径以及名字上判断是蓝牙语音读书的插件包。然而反编译以后,并没有发现可以利用的点。
尽管没有开放出固件,但是万能的国民开启了usb调试以后,就可以获取到ota包。
同时在mtp挂载里,查看ota_log文件,发现ota包存放的位置是 /storage/emulated/0/adupsfota/update.zip
,在群里问侃侃,说mtp挂载的应该是 /storage/emulated/0/
,我尝试直接建立文件夹,并把ota包放进去,无法检测到。推测是文件夹权限的问题,但是如果的确挂载的是 /storage/emulated/0/
,而且之前升级时自动新建了一个 adupsfota/
文件夹的话,应该会冲突,不允许我建立的。这里依旧疑惑。
既然是通过ota,那么直接分析出整个ota的过程,通过伪造假的ota服务器来进行升级不就行吗,升级成自己修改过设置的包,而且我认为掌阅的开发人员在调试的时候,不会是手动找时机点右上角的设置吧。
下文皆是基于此项探索进行的。
既然要探查ota过程流量,而ireaderp是通过wifi连接的,那么就需要建立热点,并抓取热点的流量进行分析。由于我的系统是debian sid(tesing),网上流传的小米wifi的驱动无法编译,linux内核太新了,提示错误 code model kernel does not support PIC mode
,在简单搜索以后放弃解决这个问题,直接切换到别人的win下面去。小米wifi建立热点,用wireshark神器抓包分析。
由于自己建立的热点数据流量很少,只有13条,其中前6条是ireaderp android系统的服务行为,连接谷歌。后面才是在系统里点击更新时产生的流量。
但是很明显这里的流量都是单向的,从小米wifi(10.0.2.*)到ota服务器(43.254.53.99)。而且三步握手数据也不全面,但是可以看到有个HTTP响应数据,点开数据查看,会发现响应的内容如下:
{"flag":{"LUrl":"no","isInner":1,"isupgrade":1,"displayApp":0,"rand":"611708206","updateStep":0,"DUrl":"http://fotadown.mayitek.com/ota/","mid":"20161129160819WF8361","connfreq":"2940"},"status":1010}
而之前在探索1中,找可用的数据时, system/build.prop
文件里有很多有用的信息,比如版本号等等。跟这里的信息一联系,有很多可圈可点之处。而且很明显 http://fotadown.mayitek.com/ota/
是下载ota包的连接。
小米wifi最后也是通过本机的有线网卡进行的数据转发,因此抓包本机的eth网卡。
通过筛选命令 ip.src==43.254.52.99 or ip.dst==43.254.52.99
可以获取到整个交互过程。同样数据不多,可以看到一条重要的HTTP POST数据,
POST /ota/detectdown/detectSchedule.do HTTP/1.1
Bingo!这就是检测版本号的链接。
在随后的一条就是咱们上面获取到的响应数据。
同时通过 dns
筛选到底ireaderp是访问什么网址进行请求ota版本检查的,发现了 fota4.adups.cn
,(实际上是访问的 fota4.mayitek.com
,只不过被重定向了)
那么接下来只需要伪造服务器就可以了。
分析下整个访问的流程:
ireaderp(发送网址 fota4.mayitek.com
请求) —>小米wifi(转发这个请求) —>dns服务器(解析出域名的ip返回给)—>小米wifi和ota服务器进行三次握手建立链接(将请求的网址发给ota服务器)—>ota服务器(响应这个请求)—>小米wifi(转发返回的数据)—>ireaderp(自己的程序处理响应数据)
这是我大概分析的流程,我们只需要在dns服务器这里,欺骗ireaderp即可。
这个软件是很轻巧而且傻瓜式的配置,既可以作为dhcp的分发,也可以进行简单的dns服务。然而实际上最终我被它整乱了,放弃了使用。
本来我在本地pc的 /etc/hosts
里映射了那两个域名到本机,但是在测试过程中发现,dnsmasq不稳定,在其日志里,一会儿优先解析hosts文件,一会儿又通过正常的dns服务器解析。
不再赘述了(这句话饱含心酸)。
放弃dnsmasq之后,搜索搭建dns服务器,发现主要是关于bind9配置的,便学习了简单的配置方法。
不贴说明介绍了,先贴下配置的地方吧。bind的主目录是 /etc/bind/
,编辑 named.conf.local
文件,添加两个zones:
zone "adups.cn" { type master; file "/etc/bind/db.adups.cn"; }; zone "mayitek.com" { type master; file "/etc/bind/db.mayitek.com"; };
然后对照里面的file新建两个文件,直接 cp db.local db.adups.cn
用local模板建立即可。以 mayitek.com
为例,修改 db.mayitek.com
内容如下:
; ; BIND data file for local loopback interface ; $TTL 604800 @ IN SOA mayitek.com. root.mayitek.com. ( 2 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL ; @ IN NS mayitek.com. @ IN A 127.0.0.1 * IN A 你的dns服务器ip fota4 IN A 你的dns服务器ip
修改的地方可以对照着 db.local
来看。我的bind9版本是 VERSION=9.10.3-P4-Debian
。
sudo service bind9 restart
来重启服务。
修改本机的 /etc/resolv.conf
,添加你的dns服务器ip,注意这个文件是自动生成的,你做的修改在重启网络以后就会丢失。
尝试 ping fota4.mayitek.com
看看是不是你设置的dns服务器ip。如果不是,尝试修改你的dns服务器上的 /etc/hosts
文件映射域名到你的ota服务器ip。
用你的手机或者ireaderp测试,先记录下连接的wifi分配的ip,然后忘记这个网络,重新连接,设置静态地址,将dns服务器修改掉,连接以后,尝试去系统设置里更新。
搭建好了dns服务器以后,还需要搭建ota服务器,当然这两个可以是一个。由于我手头数据不多,只有上面那一个请求响应,所以只能先伪造上面那一个。
用python的tornado web框架写了简单的代码 fake_server.py
来伪造响应:
import tornado.httpserver import tornado.ioloop import tornado.options import tornado.web from tornado.options import define, options define("port", default=80, help="run on the given port", type=int) class IndexHandler2(tornado.web.RequestHandler): def get(self): greeting = self.get_argument('greeting', 'Hello') self.write(greeting + ', friendly user!') def post(self): self.write('{"flag":{"LUrl":"no","isInner":1,"isupgrade":1,"displayApp":0,"rand":"18388636","updateStep":0,"DUrl":"http://fotadown.mayitek.com/ota/","mid":"20161203160819WF9362","connfreq":"2990"},"status":1011}/n') print("get one"); if __name__ == "__main__": tornado.options.parse_command_line() app = tornado.web.Application(handlers=[(r"/ota/detectdown/detectSchedule.do", IndexHandler)]) http_server = tornado.httpserver.HTTPServer(app) http_server.listen(options.port) tornado.ioloop.IOLoop.instance().start()
由于默认是绑定80端口需要sudo, sudo python3 fake_server.py
。设置好ireaderp的dns网络配置以后,点击系统更新,会发现后台获取到了这次请求,(里面有一些杂乱的请求,不是ireaderp发出的)
修改ota包其实是中午做的,现在还存在问题,尝试伪造update.zip包不成功,解压查看的时候,我只发现了一个md5sum的校验文件,后来改完了配置,我也重新生成了md5sum,发送给别人测试(我的依旧没有开启usb调试),更新失败。这个问题尚未明朗。
目前想法,通过修改 build.prop
,添加如下内容来自动开启usb调试。
persist.servICe.adb.enable=1 persist.sys.usb.config=adb
然后使用abootimg进行了打包,参考 [android]system.img文件的打包和解包 。
整个过程,复习了我很多网络的知识,以及工具的使用。但是实在是太累了。从早上9.00在群里开始讨论这件事情,中午外卖,在宿舍一直坐到晚上6.00,然后去实验室继续做,最后总结文章,写到了第二天的0:30。只因为早上的讨论勾起了我的兴趣。
有大神破解了iReader plus
Wireshark基本介绍和学习TCP三次握手
烂泥:dnsmasq搭建简易DNS服务器
Ubuntu Bind9泛域名解析配置
DNS开源服务器BIND最小配置详解
[android]system.img文件的打包和解包
其实还有很多很多很多参考,但是实在浏览记录太多了,没有及时mark。