iOS逆向之微信——还搁这抢号呢?

2,036 阅读3分钟

背景

自动今年疫情后,杭州余杭区所有的儿童疫苗都需要网上预约后才能接种,余杭政府也提供了一个微信和支付宝小程序“健康余杭”进行取号预约。但是每次基本都是僧多粥少,如果遇到节假日放假后的几个工作日更是一号难求。每次给女儿预约疫苗接种都是一次战斗!

好在是线上系统和线下还未打通,每次去医院接种的时候,出示手机上面的小程序预约单,保安给你换一个纸质的挂号接种号。嘿嘿,于是这里就存在了可操作性的空间——那是不是只要手机上的小程序能够正常显示预约单就能接种呢?

方案

  1. PS 一张预约单 这个方案虽然简单,但是存在问题,万一保安让你操作下小程序岂不是炸了?

  2. 逆向微信小程序,在相应的界面将以前的预约单改成你想要的时间
    这个方案相对安全,只要线上线下不打通基本不会被识破。

微信砸壳

直接使用AloneMonkey大神的工具frida-ios-dump进行一个砸壳,顺利得到微信的砸壳后的ipa文件。

新建MonkeyApp

我们继续站在巨人的肩膀上,使用AloneMonkey大神的MonkeyDev,新建一个MonkeyApp 并将刚刚得到的微信ipa文件拖入TargetApp文件夹,然后点击运行按钮。

查看小程序布局


我们很容易看到这个页面是一个WKWebView实现的,那我们是不是只需要将接种时间改成我们想要时间就行了呀,比如“2020-12-10 13:40-14:10”,严谨点顺便可以改预约成功时间和下面的取号密码,为了教程清晰,这里演示我们仅仅修改接种时间。

替换文字

我们使用Safari查看下WKWebView的布局

我们看到body的属性值is应该就是路由,我们可以用这个来判断界面,并修改相应的元素文档,js代码如下

if (document.body.getAttribute('is') === 'pages/booking/orderDetail/index') {
    console.log('replace text');
    let eles = document.getElementsByClassName('value _span data-v-c39257b4');
    eles[0].innerText = '小肥阳';
    eles[2].innerText = '2020-12-10 13:40-14:10';
}

在Safari的控制台下面测试了下,果然成功更改了相应的时间。

集成到APP

在调试环境下我们已经做到了,可是怎么让他持久化呢?回到上面刚刚新建的MonkeyApp,我们只要在WKWebView实例化的时候植入一段js脚本,用来替换相应的文档是不是就行了?OK!MonkeyApp已经集成了Logos Tweak,我们直接使用Logos语法Hook WKWebView

%hook WKWebView
- (id)initWithFrame:(CGRect)frame configuration:(id)configuration {
    NSLog(@"This is a WKWebView  initWithFrame method ");
    WKWebView *wkWebView = %orig();
    NSString *js = @"var replace = function () {\n"
                   "    if (document.body.getAttribute('is') === 'pages/booking/orderDetail/index') {\n"
                   "        console.log('replace text');\n"
                   "        let eles = document.getElementsByClassName('value _span data-v-c39257b4');\n"
                   "        eles[0].innerText = '小肥阳';\n"
                   "        eles[2].innerText = '2020-12-10 13:40-14:10';\n"
                   "    }else{\n"
                   "        setTimeout(replace, 100);\n"
                   "    }\n"
                   "}\n"
                   "replace();";
    WKUserScript *userScript = [[WKUserScript alloc] initWithSource:js
                                                      injectionTime:WKUserScriptInjectionTimeAtDocumentEnd
                                                   forMainFrameOnly:NO];

    [wkWebView.configuration.userContentController addUserScript:userScript];
    return wkWebView;
}
%end

注意,js注入的时机一定要选择在WKUserScriptInjectionTimeAtDocumentEnd,不然获取到的元素会为null。我们重新运行微信,并跳转到相应的小程序界面。

总结

这次我们了解到原来微信小程序就是一个普通的WebView,还以为另有玄机。
其实站在巨人的肩膀上,我们虽然能做到简单的逆向,但是知其然不知其所以然,菜鸟还是需要有很长的路需要走。