Wednesday, June 2, 2021

Hooking McAfee Security

What do people say about you when you’re not around? oh god is he died ? ! or oh thank god finally he died 
Welcome Back Guys , after long time get motivation from Pepper to write this blog ( ah i am using Tony Stark profile pic everywhere ) 😂 . i am big fan of Robert Downey, Jr. thats why.
Lets start todays topic - 
"Hooking Signature Verification With Frida For McAfee Security App on android" 
why i choosed this app ? my dream is to join there as malware analysist so why not start hooking from company's own app 

Lets download McAfee Security App from play store McAfee 
and take backup of its apk somewhere . i used MT Manager 
lets resign it to test its anti tamper - specifically Signature Check .
resign it with signature scheme v1+v2 and install it and open .
its surprisingly closed , no idea why ! 
lets fireup frida and use already available script StopExit to stop apk from closing .

console give us very useful info

`KillProcess():-->>2686
[*] KillProcess() Called
#######################
 java.lang.Exception
        at android.os.Process.killProcess(Native Method)
        at com.mcafee.activityplugins.ValidCertificatePlugin.killSelf(SourceFile:2)
        at com.mcafee.activityplugins.ValidCertificatePlugin.b(SourceFile:2)
...............

this line get my attention 
com.mcafee.activityplugins.ValidCertificatePlugin.killSelf(SourceFile:2)
 is this some short of certificate check and if certificate not match then killself . it is totally suicide , don't do it McAfee ( trying to do suicide is crime in india 😅) 

lets jump to this method in dex 

find its xref method which is calling this killSelf method
again goto deep and find who have xref to this "b" method
that red method is b which will eventually call killSelf but a green method named validateAppSignature draw attention because name look good , lets jump to that method 
validateAppSignature
 this seems app getting current signature and converting to byte array and doing some process and at last it compares something with java/lang/String;->equals method. 
lets get value to that toByteArray method so we can see original signature value.

a minute work gives us this script 

var PMS = Java.use('android.content.pm.Signature');  PMS["toByteArray"].overload().implementation = function() {
    var output = this["toByteArray"](); 
    console.warn("toByteArrayoutput",output);   
    return output;
  };

Amazingly frida give this output

toByteArrayoutput [object Object]

something wring , bytes are not displaying correctly . searching on google give us idea about code from Stackoverflow

function encodeHex(byteArray) {
    const HexClass = Java.use('org.apache.commons.codec.binary.Hex');
    const StringClass = Java.use('java.lang.String');
    const hexChars = HexClass.encodeHex(byteArray);
    return StringClass.$new(hexChars).toString();
}
and using this code with above script give us a complete working 

var PMS = Java.use('android.content.pm.Signature')  PMS["toByteArray"].overload().implementation = function() {
    var output = this["toByteArray"](); 
    var encode = encodeHex(output);
    console.log(encode);    
    return output;
  };
  
  function encodeHex(byteArray) {
    const HexClass = Java.use('org.apache.commons.codec.binary.Hex');
    const StringClass = Java.use('java.lang.String');
    const hexChars = HexClass.encodeHex(byteArray);
    return StringClass.$new(hexChars).toString();
}

it give output as 

308202b730820220a00302010202044a3f3778300d06092a864886f70d010105050030819e310b3009060355040613025347311230100603550408130953696e6761706f7265311230100603550407130953696e6761706f726531193017060355040a131074656e4375626520507465204c74642e3131302f060355040b13284469676974616c20494420436c6173732033202d204a617661204f626a656374205369676e696e67311930170603550403131074656e4375626520507465204c74642e3020170d3039303632323037343931325a180f32323833303430373037343931325a30819e310b3009060355040613025347311230100603550408130953696e6761706f7265311230100603550407130953696e6761706f726531193017060355040a131074656e4375626520507465204c74642e3131302f060355040b13284469676974616c20494420436c6173732033202d204a617661204f626a656374205369676e696e67311930170603550403131074656e4375626520507465204c74642e30819f300d06092a864886f70d010101050003818d003081890281810088fe995718bb255fa5bd361a8541bb4b10bd24a732a4d2b63b5919ce345f20a0341a2ce7a5619f1114986afe9a8f1e3e3295b0763227523b7323fa722cee8e99d25663169605ebb85f44b18e87c003647dfb9fa13086be12f32d5a0ff9b15552ecac7a185cf2ab8885f0f1c6d285964d460e25fa7a14d761318011e11a6c8b930203010001300d06092a864886f70d01010505000381810052e41884cbef13eefbe35af21cb8415ae63df376d9c87d522d10bcc04599d6c04ac28f9a20bd510f8d7811d56795341b6f191eaef8efa5d37963429ab1d30133e37bfd0e5ddfbb7c47578f4b9191117f267b6124a154748be1da1cce0a728610cc52e1d35171ab1f0350972331b47561085ebd8b405ef649587220cf1525b43e

this seems original signature in hex . lets use it against the app itself . whenever app asking to toByteArray we give it this long code so hopefully app things its original . taking 1 more minutes and below script is ready 

var OriginalSign = "308202b730820220a00302010202044a3f3778300d06092a864886f70d010105050030819e310b3009060355040613025347311230100603550408130953696e6761706f7265311230100603550407130953696e6761706f726531193017060355040a131074656e4375626520507465204c74642e3131302f060355040b13284469676974616c20494420436c6173732033202d204a617661204f626a656374205369676e696e67311930170603550403131074656e4375626520507465204c74642e3020170d3039303632323037343931325a180f32323833303430373037343931325a30819e310b3009060355040613025347311230100603550408130953696e6761706f7265311230100603550407130953696e6761706f726531193017060355040a131074656e4375626520507465204c74642e3131302f060355040b13284469676974616c20494420436c6173732033202d204a617661204f626a656374205369676e696e67311930170603550403131074656e4375626520507465204c74642e30819f300d06092a864886f70d010101050003818d003081890281810088fe995718bb255fa5bd361a8541bb4b10bd24a732a4d2b63b5919ce345f20a0341a2ce7a5619f1114986afe9a8f1e3e3295b0763227523b7323fa722cee8e99d25663169605ebb85f44b18e87c003647dfb9fa13086be12f32d5a0ff9b15552ecac7a185cf2ab8885f0f1c6d285964d460e25fa7a14d761318011e11a6c8b930203010001300d06092a864886f70d01010505000381810052e41884cbef13eefbe35af21cb8415ae63df376d9c87d522d10bcc04599d6c04ac28f9a20bd510f8d7811d56795341b6f191eaef8efa5d37963429ab1d30133e37bfd0e5ddfbb7c47578f4b9191117f267b6124a154748be1da1cce0a728610cc52e1d35171ab1f0350972331b47561085ebd8b405ef649587220cf1525b43e";
  var PMS = Java.use('android.content.pm.Signature')
  PMS["toByteArray"].overload().implementation = function() {
    var output = this["toByteArray"](); 
    output = Java.array('byte', hexToBytes(OriginalSign));    
    return output;
  };
  
  function hexToBytes(hex) {
  for (var bytes = [], c = 0; c < hex.length; c += 2)
  bytes.push(parseInt(hex.substr(c, 2), 16));
  return bytes;
   }

lets run it with resigned McAfee Security app and boom
it started fine . we could make that equal compare also true but its good to go to actual method which should target . 
complete script is available here GitHub
Hopefully you are not bored while reading all this shits because i am not good in writing blogs .
Regards 
@apkunpacker