记录黑客技术中优秀的内容,传播黑客文化,分享黑客技术精华

某湃新闻APP之登录验证码下发短信分析

2021-08-22 08:49


前言

分析算法,这个事情...我发现了。是真上瘾...
(PS:从某米应用商店下载了一整页的APP...)

工具

  1. fiddler(抓网络数据包用)

  2. jadx-gui(APP反编译用)

  3. 易语言(复现用)

  4. 算法助手(可用也可不用,xp模块,需root使用)

0x1 抓包

直接手机设置代{过}{滤}理,打开APP,竟然能抓到数据包。【也可以用Drony端口转发抓包、小黄鸟等】
登录下发验证码的接口为/v3/getVerCode.msp,codeParam值为32位长度,猜测是md5加密


还有另外一个/v3/getVericodek.msp的接口返回的内容为json格式


 复制代码 隐藏代码
{"resultMsg":"请求成功","resultCode":"1","vericodek":"f2G8x42F57UT"}

0x2 分析

jadx搜接口(不用助手)

直接搜/v3/getVericodek.msp


找到cn.thepaper.paper.ui.mine.registerNew.b类中的a函数。


查看调用堆栈(用助手)

直接上算法助手搜fiddler数据中codeParam值6280CE5F15B9BCC2CD0AA9C73D0A3046,出现一条数据记录


 复制代码 隐藏代码
明文为F028407907FB062579FEE0D33D155F94C27D4A1DBB53F4DC33402F13BE590D7175FFB8EBB425208A1CB86F151398D955

但是好像并没有再助手和fiddler中搜到相关的数据,猜测明文也是经过处理的,我们看调用堆栈。
找到cn.thepaper.paper.ui.mine.registerNew.b类中的a函数。

 复制代码 隐藏代码
public void a(String str, String str2, String str3, String str4, String str5) {
    String str6;
    String str7;
    if (TextUtils.isEmpty(str5)) {
        str6 = str3 + "0000";
        str7 = "0000";
    } else {
        str6 = str3 + str5;
        str7 = str5;
    }
    this.f2371c.a(str, str2, str7, EncryptUtils.encryptMD5ToString(EncryptUtils.encryptAES2HexString(("verType=" + str + "mail=" + str2 + "gCode=" + str7).getBytes(), str6.getBytes())), str4).a(new c<BaseInfo>() {
    /* 此处省略N多处理代码 */    });
}

简单看一下,根据fiddler的参数,可以得出"verType=" + str + "mail=" + str2 + "gCode=" + str7中

strstr2str7
a函数的参数1手机号变量str7
6183965555550000

查看哪里调用a函数

在a函数处右键,查找用例。有很多,但是根据上门的a函数的第一个参数str=6,可找到本次调用的位置。


双击进去查看。


 复制代码 隐藏代码
    public void t(View view) {
        if (!cn.thepaper.paper.lib.c.a.a(view)) {
            if (!PaperApp.isNetConnected()) {
                ToastUtils.showShort((int) R.string.network_fail);
                return;
            }
            cn.thepaper.paper.lib.b.a.a("294");
            String trim = this.e.getText().toString().trim();
            this.w = trim;
            if (!RegexUtils.isMobileSimple(trim)) {
                ToastUtils.showShort((int) R.string.phone_incorrect);
                return;
            }
            String str = this.v;
            if (str == null || str.length() != 12) {
                this.r.d();
                return;
            }
            this.r.a("6", this.w, this.v, "1", "");/* 此处为调用a函数 */            this.g.requestFocus();
            m(this.g);
        }
    }

由上述f函数的代码可得出a函数所有的参数(String str, String str2, String str3, String str4, String str5)

strstr2str3str4str5
a函数的参数1this.w=手机号this.v变量str4变量str5
618396555555未知1''

出现一个未知的this.v ,既然有调用,那就肯定有赋值,我们再右键查this.v的查找用例


果然找到一个,


 复制代码 隐藏代码
this.v = vericodek.getVericodek();public String getVericodek() {
    return this.vericodek;
}

this.vericodek这不巧了吗这不是,这不就是/v3/getVericodek.msp中得到的吗?
又根据

 复制代码 隐藏代码
        if (TextUtils.isEmpty(str5)) {
            str6 = str3 + "0000";
            str7 = "0000";
        } else {
            str6 = str3 + str5;
            str7 = str5;
        }

str5为空,所以得出:

 复制代码 隐藏代码
    str6 = str3 + "0000";str7 = "0000";
strstr2str3str4str5str6str7
a函数的参数1this.w=手机号this.v=getVericodek.msp中的vericodek变量str4变量str5str6=str3+"0000"str7="0000"
618396555555f2G8x42F57UT1''f2G8x42F57UT00000000

得出所有参数和变量之后,查看处理过程,现实encryptAES2HexString,然后再用encryptMD5ToString。(PS:那就是先AES加密,在用MD5加密,得出的6280CE5F15B9BCC2CD0AA9C73D0A3046)

分析

明文经过处理,得到md5值

 复制代码 隐藏代码
  EncryptUtils.encryptAES2HexString(("verType=" + str + "mail=" + str2 + "gCode=" + str7).getBytes(), str6.getBytes())

也就等于

 复制代码 隐藏代码
  EncryptUtils.encryptAES2HexString(("verType=" + "6" + "mail=" + "18396555555" + "gCode=" + "0000").getBytes(), str6.getBytes())

先看encryptAES2HexString

 复制代码 隐藏代码
public static String encryptAES2HexString(byte[] bArr, byte[] bArr2) {
    return bytes2HexString(encryptAES(bArr, bArr2));/* 看样子应该是AES加密,编码为hex而不是base64 */}

再看下encryptAES

 复制代码 隐藏代码
    private static final String AES_Algorithm = "AES";
    public static String AES_Transformation = "AES/ECB/PKCS5Padding";

    public static byte[] encryptAES(byte[] bArr, byte[] bArr2) {
        return desTemplate(bArr, bArr2, AES_Algorithm, AES_Transformation, true);/* AES_Algorithm= */    }
    public static byte[] desTemplate(byte[] bArr, byte[] bArr2, String str, String str2, boolean z) {
        if (!(bArr == null || bArr.length == 0 || bArr2 == null || bArr2.length == 0)) {
            try {
                SecretKeySpec secretKeySpec = new SecretKeySpec(bArr2, str);
                Cipher instance = Cipher.getInstance(str2);
                instance.init(z ? 1 : 2, secretKeySpec, new SecureRandom());
                return instance.doFinal(bArr);
            } catch (Throwable th) {
                th.printStackTrace();
            }
        }
        return null;
    }

由desTemplate可得出AES/ECB算法参1为明文,参2为秘钥
所以用在线AES加密网站测试


加密结果为:F028407907FB062579FEE0D33D155F94C27D4A1DBB53F4DC33402F13BE590D7175FFB8EBB425208A1CB86F151398D955
再MD5结果为:6280CE5F15B9BCC2CD0AA9C73D0A3046,正好是fiddler里面的codeParam值

0x3 需要注意的事项

  1. 秘钥的一部分this.v=f2G8x42F57UT  并不是固定的,而是每一次下发验证码之前就要先获取的,

  2. AES加密的结果中的字母必须为大写,小写的话直接MD5,结果会不一样哦

  3. 请求的时候,记得要添加协议头哦,要不然的话会提示没找到uuid

0x4 易语言实现下发短信

因为vericodek不一样,所以易语言之后的codeParam值也和之前fiddler抓到的不一样了。



END



知识来源: https://mp.weixin.qq.com/s?__biz=MzIxOTM2MDYwNg==&mid=2247507734&idx=1&sn=be0157496b58ddf955c8e99b3a48dc6c

阅读:148864 | 评论:0 | 标签:app 验证码 分析

想收藏或者和大家分享这篇好文章→复制链接地址

“某湃新闻APP之登录验证码下发短信分析”共有0条留言

发表评论

姓名:

邮箱:

网址:

验证码:

黑帝公告 📢

永久免费持续更新精选优质黑客技术文章Hackdig,帮你成为掌握黑客技术的英雄

广而告之 💖

标签云 ☁