实战:某App登录协议分析

工具及设备: Iphone5,ios9.0.2,lldb,Cycript,IDA 等等


通过cycript找到登录函数
[KKLoginViewController loginWithMobile:]
没啥可说的,跟过去就行了 来到 loginWithPhone:countryID:password:complete:函数

经过RSAEncrypotoTheData:时

看到密码应该是xx加密算法

接着跟进POST:parameters:callback:函数
来看看它传入的参数


账号密码都有了
这个函数体很小 接着分析它调用的函数 requestWithMethod:urlString:parameters:callback:
此函数略过 (数据丢失了,应该是对参数的进一步优化组装)
我们来看下一个函数 requestWithMethod:URLString:parameters:error:

通过它传过来的参数就很明了是登录流程了

这个函数里有个很重要的函数 用来组装■■网址后面的一些参数
来看看伪代码

v8 = objc_msgSend(&OBJC_CLASS___NSMutableDictionary, "dictionaryWithDictionary:", v6);
  v9 = (void *)objc_retainAutoreleasedReturnValue(v8);
  objc_msgSend(v9, "setObject:forKey:", CFSTR("3.6.0"), CFSTR("appv"));
  objc_msgSend(v9, "setObject:forKey:", CFSTR("iOS"), CFSTR("osn"));
  v10 = objc_msgSend(&OBJC_CLASS___UIDevice, "currentDevice");
  v11 = (void *)objc_retainAutoreleasedReturnValue(v10);
  v12 = v11;
  v13 = objc_msgSend(v11, "systemVersion");
  v14 = objc_retainAutoreleasedReturnValue(v13);
  objc_msgSend(v9, "setObject:forKey:", v14, CFSTR("osv"));
  objc_release(v14);
  objc_release(v12);
  v15 = objc_msgSend(&OBJC_CLASS___KKDeviceID, "dID");
  v16 = objc_retainAutoreleasedReturnValue(v15);
  v17 = objc_msgSend(&OBJC_CLASS___KKAccountManager, "currentAccount");
  v18 = (void *)objc_retainAutoreleasedReturnValue(v17);
  v19 = v18;
  v20 = objc_msgSend(v18, "authority_token");
  v21 = objc_retainAutoreleasedReturnValue(v20);
  objc_release(v19);
  if ( v21 )
    objc_msgSend(v9, "setObject:forKey:", v21, CFSTR("token"));
  v107 = v21;
  v22 = objc_msgSend(&OBJC_CLASS___KKAnalysisManager, "sharedManager");
  v23 = (void *)objc_retainAutoreleasedReturnValue(v22);
  v24 = v23;
  v25 = objc_msgSend(v23, "sessionID");
  v26 = objc_retainAutoreleasedReturnValue(v25);
  objc_msgSend(v9, "kk_setObject:forKey:", v26, CFSTR("seid"));
  objc_release(v26);
  objc_release(v24);
  objc_msgSend(v9, "setObject:forKey:", v16, CFSTR("did"));
  v27 = objc_msgSend(&OBJC_CLASS___NSDate, "timestampString");
  v28 = objc_retainAutoreleasedReturnValue(v27);
  objc_msgSend(v9, "setObject:forKey:", v28, CFSTR("ts"));
  objc_release(v28);
  v29 = objc_msgSend(&OBJC_CLASS___KKDeviceID, "adID");
  v30 = objc_retainAutoreleasedReturnValue(v29);
  objc_msgSend(v9, "kk_setSafeObject:forKey:", v30, CFSTR("im"));
  objc_release(v30);
  v31 = objc_msgSend(&OBJC_CLASS___UIScreen, "mainScreen");
  v32 = (const char *)objc_retainAutoreleasedReturnValue(v31);

部分伪代码
这个时候发送网址就组装好了

http://删掉了/account/login?appv=3.6.0&ch=AppStore_3.6.0.2&did=删掉了&dt=iPhone5%2C2&im=删掉了&la=cn&latitude=删掉了&lm=sina&longitude=删掉了&lp=-1.000000&net=0-0-wifi&osn=iOS&osv=9.0.2&seid=删掉了&sh=568.000000&sw=320.000000&tpid=login&ts=1447132463223

再来分析[AFHTTPRequestSerializer requestWithMethod:URLString:parameters:error:]这个函数


分析过后之后这个函数也是对参数进行了部分优化
在requestBySerializingRequest:withParameters:error:函数中发现了■■时出现的校验信息xxx–sign-v1

我们来看看xxxSignWithContent:deviceId:salt:传入的参数

函数伪代码如下

 v7 = objc_retain(a3, a2);
  v9 = objc_retain(v6, v8);
  v11 = objc_retain(a5, v10);
  v12 = (void *)objc_retainAutorelease(v5);
  v13 = objc_msgSend(v12, "cStringUsingEncoding:", 4);
  objc_release(v7);
  v14 = (void *)objc_retainAutorelease(v6);
  v15 = (const char *)objc_msgSend(v14, "cStringUsingEncoding:", 4);
  objc_release(v9);
  v16 = (void *)objc_retainAutorelease(a5);
  v17 = (const char *)objc_msgSend(v16, "cStringUsingEncoding:", 4);
  objc_release(v11);
  v18 = (struct objc_object *)sub_3758D8((int)v13, v15, v17);   //这是加密函数
  return j__objc_msgSend(
           (struct KKHTTPRequestSerializer *)&OBJC_CLASS___NSString,
           "stringWithUTF8String:",
           v18,
           (id)&classRef_NSString,
           a5);

这就来到了加密函数sub_3758D8了

 strncpy(&v28, a2, 0x20u);
  v13 = strlen(v8);
  v14 = malloc(v13 + 65);
  if ( v14 )
  {
    v15 = strlen(v8);
    v9 = 0;
    memset(v14, 0, v15 + 65);
    strcpy((char *)v14, v8);
    v16 = sub_14AE74(&v28);
    __strcat_chk((int)v14, (int)v16, -1);
    __strcat_chk((int)v14, (int)"11b9ee698954721dfbd446072c7bd437", -1);
    v17 = sub_14AE74((const char *)v14);
    __strcpy_chk(&v26, v17, 33);
    free(v14);
    v18 = sub_4447A0(v3);
    v19 = v18;
    if ( v18 )
    {
      v20 = sub_375A24(v18);
      sub_4442AC(v19);
      v21 = strlen(v20);
      v22 = malloc(v21 + 33);
      v9 = 0;
      if ( v22 )
      {
        v23 = strlen(v20);
        memset(v22, 0, v23 + 33);
        strcpy((char *)v22, v20);
        free(v20);
        __strcat_chk((int)v22, (int)&v26, -1);
        v24 = sub_14AF14((const char *)v22);
        strncpy((char *)&unk_BCC920, v24 + 3, 0x20u);
        byte_BCC940 = 0;
        free(v22);
        v9 = &unk_BCC920;
      }
    }
  }

经过分析得知 里面调用了MD5 SHA算法 最后得到一个32位的校验值
到这里分析就完了 可以写代码进行脱机登录了。
先到这吧。
由于部分原因,帖子里隐去了部分信息。

补上却的图片



注:此贴仅限于技术交流,请不要根据此贴做违法的事情,对于那些居心叵测的人根据此帖造成违法的事情与本人无关。
此贴不得转载!!!

2 个赞

楼主,你IOS9.0.2是怎么用起来Cycript的?

那么,ios9.0.2你是怎么用dumpdecrypted砸壳的呢?我尝试了好几个ios9.0下的App,砸壳的过程都不报错,但是把xxx.decrypted scp出来,用IDA打开都提示说是encrypted的,也即是砸壳是不成功的

有个帖子讲砸壳的,我按帖子一步一步来的

你为何不直接抓包, 然后直接找到sign和密码的加密函数, 这样不是更快吗

之前已经抓包看过了

赞,谢谢分享

我的也是,只能勾住SpringBoard,其他的勾不了

楼主还在吗?我最近在逆向一个app 目的跟你差不多也是 像分析出url其中一个参数的加密方法。。。求楼主指引。。。楼主在的话 能加下我的qq吗? 小弟qq553816206