在最近的业务项目中,有一些app样本需要抓取数据包进行重放,但是因为有sign的存在,使得这一过程进行的话并不是很顺利。因此要对该sign进行解密。刚开始观察一下sign的格式,发现跟md5很相似,当然了不能说相似,只能说是一模一样。可以口算md5的303不在,所以需要一个可以验证我这一想法的frida脚本。
首先我们知道md5算法是消息摘要算法,Android中是java.security.MessageDigest这一个类为应用程序提供消息摘要算法的功能。如果开发人员是使用md5进行加密,并且没有进行魔改,那么理论上抓取的数据包中的sign值就是一个数据直接md5进行加密得到的结果,这个数据可以是时间戳跟用户名进行拼接,也可以是时间戳与一个固定的Key值进行拼接。拼接完成后,调用该类,然后md5加密完成。接下来就开始验证想法。
// MD5
Java.perform(function(){
var MessageDigest= Java.use('java.security.MessageDigest');
MessageDigest.getInstance.overload('java.lang.String').implementation=function(arg1){
// console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
console.log(arg1);
var ret = this.getInstance(arg1);
return ret;
}
MessageDigest.update.overload('[B').implementation=function(arg1){
console.log("use update.overload('[B') ");
parseIn(arg1);
var ret = this.update(arg1);
return ret;
}
MessageDigest.digest.overload().implementation=function(){
console.log('use digest.overload()');
var ret = this.digest();
parseOut(ret);
return ret;
}
MessageDigest.digest.overload("[B","int","int").implementation=function(buf,offset,len){
console.log('use digest.overload("[B","int","int")');
parseIn(buf);
var ret = this.digest(buf,offset,len);
parseOut(ret);
return ret;
}
MessageDigest.digest.overload("[B").implementation=function(buf){
console.log('use digest.overload("[B")');
parseIn(buf);
var ret = this.digest(buf);
parseOut(ret);
return ret;
}
});
function parseIn(input){
var Integer= Java.use('java.lang.Integer');
var String= Java.use('java.lang.String');
try{
console.log("original:"+String.$new(input));
}
catch(e){
console.log(parseHex(input));
}
}
function parseOut(ret){
var Integer= Java.use('java.lang.Integer');
var String= Java.use('java.lang.String');
var result = "";
for(var i = 0;i<ret.length;i++){
var val = ret[i];
if(val < 0){
val += 256;
}
var str = Integer.toHexString(val);
if(String.$new(str).length()==1){
str = "0" + str;
}
result += str;
}
console.log( "(32)字母小写输出:" + result);
console.log( "(32)字母大写输出:" + result.toUpperCase());
console.log( "(16)字母小写输出:" + result.substring(8,24));
console.log( "(16)字母大写输出:" + result.substring(8,24).toUpperCase());
console.log("");
}
function parseHex(input){
var Integer= Java.use('java.lang.Integer');
var byte_array = "";
for(var j = 0;j<input.length;j++){
var hex = Integer.toHexString(input[j]);
if(hex.length == 1){
hex = "0" + hex;
}
byte_array += hex;
}
console.log("original(hex):");
var pair = "";
var hex_table = "";
for(var k = 0;k<byte_array.length;k++){
pair += byte_array.charAt(k);
if((k+1)%2 == 0){
pair += " "
hex_table += pair;
pair = ""
}
if((k+1)%32 == 0){
hex_table += "\n"
}
}
return hex_table;
}
frida -UF -l Hookmd5.js -o xxx.txt(数据必然会很多,所以需要存储一下)
与抓包得到的数据进行比对,是一模一样。sign值是标准md5值。所以可以直接根据这一结果,再加上数据的堆栈直接定位到加密算法进行分析就可以了。