Android逆向——网易云音乐排行榜api(下)

5,057 阅读6分钟

0. 从内存中dump libpoison.so文件

前文讲到绕过libneutil.so反调试后,接着就会加载libpoison.so文件

根据上图得到的so文件的基址和大小,执行IDA script(shift+F2)可获得so文件进行静态分析(注意需要进行一些修复,参考https://bbs.pediy.com/thread-192874.htm)

static main(void)
{
auto fp, SoAddress;
fp = fopen("D:\\debug.so", "wb");
for ( SoAddress=0x7614a000; SoAddress<= 0x7614a000+0x0001d000; SoAddress++ )
fputc(Byte(SoAddress), fp);
}

1. 加密算法分析

从函数名来看,猜测是使用了AES加密方法,尝试下断动态调试

成功断下,已知AES算法需要输入待加密文本、密钥和填充模式

同时我们发现在AES解密也是使用加密时的密钥

从解密函数伪c代码中,找到其解密的主要函数

进去看看,发现有字符串

怀疑是AES加解密的密钥,尝试随便抓个包并解密params参数看看

# -*- coding:utf-8 -*-
#!/usr/bin/env python


from binascii import a2b_hex
from Crypto.Cipher import AES


def aesDecrypt(text):
    encryptor = AES.new("e82ckenh8dichen8", 1)
    deText = encryptor.decrypt(text)
    return deText
    
text = "8DC1BDC42724718D65298B7ED2FDA170E14D621EB896C63E8E0FBC1DFA867E565C8D35F127FBF70066280EE41ADA1B3797EA9214D0D0E5C57251274C872B60A767324A0FA640B95C78E004EA2CD369912376ECF26FE6D37DA7262AF3731586763600080B71393DF33876A75D4DFA602602A5EFFEAA7F138CCEE613E4A0C09FE6A450EF549E00536E78245BF989B670F529EA366BC32F056342F77F7F6DD2CCF3A9AF2FA85F2990E1A050C6B11378D5CE3306719CE0FBCFEC830C13CD81C684936EF06DFFD65D07544F078730A1669B1308B89F07913B9B7452B4B4E837872A49481EF62405520DC3443D738DDB8973CF5F0A8138A473A6F9FB4ED90C932B3B717111615FBFB6BB26379266041868838A10EEC26257E315BB92C5416825F0A02E65344BB8326481389DAFCCC7F868CABE415E4EA770879014A9DE64D5495D806E7D5EE3EEC5620D21762F458C273A476BE4C1F21AC0CD65E6ACB81C07931AC97EBA3A4572FFAF42E3C8C4D95D70CAC4E92F1C5DF3A912F43C1A891708BC8E48C2F53538FC0FE21DB4F4BED35FAE6CD679BF680DCA6136B4548C50C17C93D0AD5E7306A7DE3541B1F1B33A435133B21A7F10E21F34559BA1D77A65FD789DB94BEAE6B98BA9660A4B4CAB385948EC40DE7C8F607B27975C52DABDCDA88D6B4A0727FD3641F89CD1E040B7CDD9E6D131755CFEC46862AA1CD3FB4BA862301A2E916A9FE8DE0B646005B3711DB34F08724759B156143368D49AF7875094C41EF782119FD3951DA4EBDCB38BCC131B238BFCCAE979288FC0025406AF9CE4A07C4D4A2CE419B1DD25771DD1778A21357FB7E040A43379E9AEF94B9A2B4D88F20F52274E9EA57DEB4BBE7FD58266C38B25D50BC1EE4150D1AC9CE1E30536972AFD38A04CF16DE11F9972A7D2C8A6BB0788A28B1CB3588B2CDDF34518CB5D8F11CDDBED9E33DD0A566790A8416341132FC53904E48229E928C2D3F7C2A685F4EFA50D113B62102E69EE8D36DC4DB6D5D01B39E25F2A4DBB00732EC209CE4393981AA716D1BC2BCB0C4A7E53B249894EBF962CD6E6"

print aesDecrypt(a2b_hex(text))

运行得到,

解密出来是ok的,那么我们可以猜测加密字段构成应该是URL路径+"-36cd479b6b5-"+相关参数dict+"-36cd479b6b5-"+一个字符串MD5加密

关于MD5加密请参考我另一篇文章,这里详细分析略过

根据MD5特征值,可以判断这里是MD5初始化的地方,通过IDA的xrefs功能往上找大概就可以找到MD5加密函数,在MD5Upate的地方下个断点即可

完整加密函数如下

# -*- coding:utf-8 -*-
#!/usr/bin/env python


from binascii import b2a_hex
from Crypto.Cipher import AES
import hashlib

def md5encrypt(st):
    m1 = hashlib.md5()
    m1.update(st)
    return m1.hexdigest()

def md5forencrypt(path,DICT):
    st = ("nobody"+path+"use"+DICT+"md5forencrypt")
    return md5encrypt(st)
    
def aesEncrypt(path,DICT):
    sign = md5forencrypt(path,DICT)
    text = (path+"-36cd479b6b5-"+DICT+"-36cd479b6b5-"+sign)
    # 以<0x0f>填充
    text = text + ('' * (16 - (len(text) % 16)))
    
    encryptor = AES.new("e82ckenh8dichen8", 1)
    ciphertext = encryptor.encrypt(text)
    return b2a_hex(ciphertext).upper()
    
param = aesEncrypt('/api/v3/playlist/detail','{"id":"3778678","n":"1000","t":"0","s":"5","header":{"os":"android","MUSIC_A":"47e30a9b79cacd303faa6206c9624f7af174fd4dc1e79a245ad0c89c6f02c047241e21fec819257d186cf6d47c5b59432be083a8be0029631345e5a25a2e07b6055ecea420ae497888b724f769023877e1aa0cbe6d8d955c7f5dbdeda01813d630f43bc9c81dbc26fc93e2ea9ac9a75a44dc3cd7eec60254bd74785bfe30031e5b60d04ec53518238328c980cd21a668","requestId":"1528527808788_249","mobilename":"Nexus5","osver":"4.4.4","__csrf":"36a9564495bf790cccb3c658339ac7fe","resolution":"1776x1080","channel":"tencent","appver":"3.1.2","deviceId":"MzUzNDkwMDY3NjU1MzA0CTg4OmM5OmQwOmZjOjMwOjBkCTU3ZGZmOThmYjUyNDBkMGUJMGEyYWZiMjcwMzM3ZGQ4MA%3D%3D"}}')

print param

运行

与发包参数一致,分析完成

后记

该文章仅用于分析学习,禁止用于违法用途,侵删!!!!