인프런 커뮤니티 질문&답변
frida --codeshare를 통한 루팅 탐지 우회 문의
작성
·
1.4K
0
안녕하세요.
알려주신
https://codeshare.frida.re에서 코드를 확인하여 연습중입니다.
근데 rooting 우회와 ssl Pinning 탐지가 둘 다 적용되어있는 경우는 어떻게해야할지해서 여쭤봅니다.
https://codeshare.frida.re/@dzonerzy/fridantiroot/
-> 루팅 우회 (정상 작동)
https://codeshare.frida.re/@limyout/root-detection-and--ssl-pinning/
-> 루팅우회, SSL피닝우회
( 루팅 우회 작동으로 예상, SSL 탐지에서 걸리는 듯 하나 어느정도는 작동하다가 실패하는 듯)
혹시
https://codeshare.frida.re/@dzonerzy/fridantiroot/
-> 루팅 우회 (정상 작동)
이것과
SSL 피닝 우회가 되는 코드 2개를 사용하려하는데 잘안되는것같습니다.
혹시 방법이 없을까요?
퀴즈
Frida가 안드로이드 보안 우회 기법에서 주로 활용되는 근본적인 기술은 무엇일까요?
코드 정적 분석 (Static code analysis)
네트워크 패킷 암호화 (Network packet encryption)
동적 계측 (Dynamic instrumentation) 또는 후킹 (Hooking)
앱 스토어 인증 우회 (App store authentication bypass)
답변 2
0
안녕하세요. 보안프로젝트 김태영입니다.
답변이 많이 늦었네요.. 죄송합니다.
일반적으로 두 개의 우회 코드를 사용하실 때는,
Java.perform(function () { }) 안에 적어주시면 됩니다.
예를 들어, 아래 코드는 "FRIDA 활용-루팅 탐지 우회"와 "FRIDA 활용-암호 복호화" 기능을 한번에 묶은 것입니다. Java.perform()안에 각 기능을 하는 코드를 추가해주시면 사용 가능합니다.
import frida, sys
jscode= """
setImmediate(function(){
Java.perform(function() {
console.log("[*] Hooking System.exit()");
var exitBypass = Java.use("java.lang.System");
exitBypass.exit.implementation = function () {
console.log("[*] Hooking Success");
}
console.log("[*] Hooking Decrypted Secret");
var decrypteClass = Java.use("sg.vantagepoint.a.a");
decrypteClass.a.overload('[B','[B').implementation = function(arg1, arg2) {
retval = this.a(arg1, arg2);
secret = ''
for(i=0; i<retval.length; i++) {
secret += String.fromCharCode(retval[i]);
}
console.log("[*] Decrypted : " + secret);
return retval;
}
})
})
"""
session = frida.get_usb_device().attach("owasp.mstg.uncrackable1")
script = session.create_script(jscode)
script.load()
sys.stdin.read()
따라서, 아래와 같이 합쳐서 사용할 수 있을거 같습니다.
Java.perform(function() {
var RootPackages = ["com.noshufou.android.su", "com.noshufou.android.su.elite", "eu.chainfire.supersu",
"com.koushikdutta.superuser", "com.thirdparty.superuser", "com.yellowes.su", "com.koushikdutta.rommanager",
"com.koushikdutta.rommanager.license", "com.dimonvideo.luckypatcher", "com.chelpus.lackypatch",
"com.ramdroid.appquarantine", "com.ramdroid.appquarantinepro", "com.devadvance.rootcloak", "com.devadvance.rootcloakplus",
"de.robv.android.xposed.installer", "com.saurik.substrate", "com.zachspong.temprootremovejb", "com.amphoras.hidemyroot",
"com.amphoras.hidemyrootadfree", "com.formyhm.hiderootPremium", "com.formyhm.hideroot", "me.phh.superuser",
"eu.chainfire.supersu.pro", "com.kingouser.com"
];
var RootBinaries = ["su", "busybox", "supersu", "Superuser.apk", "KingoUser.apk", "SuperSu.apk"];
var RootProperties = {
"ro.build.selinux": "1",
"ro.debuggable": "0",
"service.adb.root": "0",
"ro.secure": "1"
};
var RootPropertiesKeys = [];
for (var k in RootProperties) RootPropertiesKeys.push(k);
var PackageManager = Java.use("android.app.ApplicationPackageManager");
var Runtime = Java.use('java.lang.Runtime');
var NativeFile = Java.use('java.io.File');
var String = Java.use('java.lang.String');
var SystemProperties = Java.use('android.os.SystemProperties');
var BufferedReader = Java.use('java.io.BufferedReader');
var ProcessBuilder = Java.use('java.lang.ProcessBuilder');
var StringBuffer = Java.use('java.lang.StringBuffer');
var loaded_classes = Java.enumerateLoadedClassesSync();
send("Loaded " + loaded_classes.length + " classes!");
var useKeyInfo = false;
var useProcessManager = false;
send("loaded: " + loaded_classes.indexOf('java.lang.ProcessManager'));
if (loaded_classes.indexOf('java.lang.ProcessManager') != -1) {
try {
//useProcessManager = true;
//var ProcessManager = Java.use('java.lang.ProcessManager');
} catch (err) {
send("ProcessManager Hook failed: " + err);
}
} else {
send("ProcessManager hook not loaded");
}
var KeyInfo = null;
if (loaded_classes.indexOf('android.security.keystore.KeyInfo') != -1) {
try {
//useKeyInfo = true;
//var KeyInfo = Java.use('android.security.keystore.KeyInfo');
} catch (err) {
send("KeyInfo Hook failed: " + err);
}
} else {
send("KeyInfo hook not loaded");
}
PackageManager.getPackageInfo.implementation = function(pname, flags) {
var shouldFakePackage = (RootPackages.indexOf(pname) > -1);
if (shouldFakePackage) {
send("Bypass root check for package: " + pname);
pname = "set.package.name.to.a.fake.one.so.we.can.bypass.it";
}
return this.getPackageInfo.call(this, pname, flags);
};
NativeFile.exists.implementation = function() {
var name = NativeFile.getName.call(this);
var shouldFakeReturn = (RootBinaries.indexOf(name) > -1);
if (shouldFakeReturn) {
send("Bypass return value for binary: " + name);
return false;
} else {
return this.exists.call(this);
}
};
var exec = Runtime.exec.overload('[Ljava.lang.String;');
var exec1 = Runtime.exec.overload('java.lang.String');
var exec2 = Runtime.exec.overload('java.lang.String', '[Ljava.lang.String;');
var exec3 = Runtime.exec.overload('[Ljava.lang.String;', '[Ljava.lang.String;');
var exec4 = Runtime.exec.overload('[Ljava.lang.String;', '[Ljava.lang.String;', 'java.io.File');
var exec5 = Runtime.exec.overload('java.lang.String', '[Ljava.lang.String;', 'java.io.File');
exec5.implementation = function(cmd, env, dir) {
if (cmd.indexOf("getprop") != -1 || cmd == "mount" || cmd.indexOf("build.prop") != -1 || cmd == "id" || cmd == "sh") {
var fakeCmd = "grep";
send("Bypass " + cmd + " command");
return exec1.call(this, fakeCmd);
}
if (cmd == "su") {
var fakeCmd = "justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled";
send("Bypass " + cmd + " command");
return exec1.call(this, fakeCmd);
}
return exec5.call(this, cmd, env, dir);
};
exec4.implementation = function(cmdarr, env, file) {
for (var i = 0; i < cmdarr.length; i = i + 1) {
var tmp_cmd = cmdarr[i];
if (tmp_cmd.indexOf("getprop") != -1 || tmp_cmd == "mount" || tmp_cmd.indexOf("build.prop") != -1 || tmp_cmd == "id" || tmp_cmd == "sh") {
var fakeCmd = "grep";
send("Bypass " + cmdarr + " command");
return exec1.call(this, fakeCmd);
}
if (tmp_cmd == "su") {
var fakeCmd = "justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled";
send("Bypass " + cmdarr + " command");
return exec1.call(this, fakeCmd);
}
}
return exec4.call(this, cmdarr, env, file);
};
exec3.implementation = function(cmdarr, envp) {
for (var i = 0; i < cmdarr.length; i = i + 1) {
var tmp_cmd = cmdarr[i];
if (tmp_cmd.indexOf("getprop") != -1 || tmp_cmd == "mount" || tmp_cmd.indexOf("build.prop") != -1 || tmp_cmd == "id" || tmp_cmd == "sh") {
var fakeCmd = "grep";
send("Bypass " + cmdarr + " command");
return exec1.call(this, fakeCmd);
}
if (tmp_cmd == "su") {
var fakeCmd = "justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled";
send("Bypass " + cmdarr + " command");
return exec1.call(this, fakeCmd);
}
}
return exec3.call(this, cmdarr, envp);
};
exec2.implementation = function(cmd, env) {
if (cmd.indexOf("getprop") != -1 || cmd == "mount" || cmd.indexOf("build.prop") != -1 || cmd == "id" || cmd == "sh") {
var fakeCmd = "grep";
send("Bypass " + cmd + " command");
return exec1.call(this, fakeCmd);
}
if (cmd == "su") {
var fakeCmd = "justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled";
send("Bypass " + cmd + " command");
return exec1.call(this, fakeCmd);
}
return exec2.call(this, cmd, env);
};
exec.implementation = function(cmd) {
for (var i = 0; i < cmd.length; i = i + 1) {
var tmp_cmd = cmd[i];
if (tmp_cmd.indexOf("getprop") != -1 || tmp_cmd == "mount" || tmp_cmd.indexOf("build.prop") != -1 || tmp_cmd == "id" || tmp_cmd == "sh") {
var fakeCmd = "grep";
send("Bypass " + cmd + " command");
return exec1.call(this, fakeCmd);
}
if (tmp_cmd == "su") {
var fakeCmd = "justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled";
send("Bypass " + cmd + " command");
return exec1.call(this, fakeCmd);
}
}
return exec.call(this, cmd);
};
exec1.implementation = function(cmd) {
if (cmd.indexOf("getprop") != -1 || cmd == "mount" || cmd.indexOf("build.prop") != -1 || cmd == "id" || cmd == "sh") {
var fakeCmd = "grep";
send("Bypass " + cmd + " command");
return exec1.call(this, fakeCmd);
}
if (cmd == "su") {
var fakeCmd = "justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled";
send("Bypass " + cmd + " command");
return exec1.call(this, fakeCmd);
}
return exec1.call(this, cmd);
};
String.contains.implementation = function(name) {
if (name == "test-keys") {
send("Bypass test-keys check");
return false;
}
return this.contains.call(this, name);
};
var get = SystemProperties.get.overload('java.lang.String');
get.implementation = function(name) {
if (RootPropertiesKeys.indexOf(name) != -1) {
send("Bypass " + name);
return RootProperties[name];
}
return this.get.call(this, name);
};
Interceptor.attach(Module.findExportByName("libc.so", "fopen"), {
onEnter: function(args) {
var path = Memory.readCString(args[0]);
path = path.split("/");
var executable = path[path.length - 1];
var shouldFakeReturn = (RootBinaries.indexOf(executable) > -1)
if (shouldFakeReturn) {
Memory.writeUtf8String(args[0], "/notexists");
send("Bypass native fopen");
}
},
onLeave: function(retval) {
}
});
Interceptor.attach(Module.findExportByName("libc.so", "system"), {
onEnter: function(args) {
var cmd = Memory.readCString(args[0]);
send("SYSTEM CMD: " + cmd);
if (cmd.indexOf("getprop") != -1 || cmd == "mount" || cmd.indexOf("build.prop") != -1 || cmd == "id") {
send("Bypass native system: " + cmd);
Memory.writeUtf8String(args[0], "grep");
}
if (cmd == "su") {
send("Bypass native system: " + cmd);
Memory.writeUtf8String(args[0], "justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled");
}
},
onLeave: function(retval) {
}
});
/*
TO IMPLEMENT:
Exec Family
int execl(const char *path, const char *arg0, ..., const char *argn, (char *)0);
int execle(const char *path, const char *arg0, ..., const char *argn, (char *)0, char *const envp[]);
int execlp(const char *file, const char *arg0, ..., const char *argn, (char *)0);
int execlpe(const char *file, const char *arg0, ..., const char *argn, (char *)0, char *const envp[]);
int execv(const char *path, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]);
*/
BufferedReader.readLine.implementation = function() {
var text = this.readLine.call(this);
if (text === null) {
// just pass , i know it's ugly as hell but test != null won't work :(
} else {
var shouldFakeRead = (text.indexOf("ro.build.tags=test-keys") > -1);
if (shouldFakeRead) {
send("Bypass build.prop file read");
text = text.replace("ro.build.tags=test-keys", "ro.build.tags=release-keys");
}
}
return text;
};
var executeCommand = ProcessBuilder.command.overload('java.util.List');
ProcessBuilder.start.implementation = function() {
var cmd = this.command.call(this);
var shouldModifyCommand = false;
for (var i = 0; i < cmd.size(); i = i + 1) {
var tmp_cmd = cmd.get(i).toString();
if (tmp_cmd.indexOf("getprop") != -1 || tmp_cmd.indexOf("mount") != -1 || tmp_cmd.indexOf("build.prop") != -1 || tmp_cmd.indexOf("id") != -1) {
shouldModifyCommand = true;
}
}
if (shouldModifyCommand) {
send("Bypass ProcessBuilder " + cmd);
this.command.call(this, ["grep"]);
return this.start.call(this);
}
if (cmd.indexOf("su") != -1) {
send("Bypass ProcessBuilder " + cmd);
this.command.call(this, ["justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled"]);
return this.start.call(this);
}
return this.start.call(this);
};
if (useProcessManager) {
var ProcManExec = ProcessManager.exec.overload('[Ljava.lang.String;', '[Ljava.lang.String;', 'java.io.File', 'boolean');
var ProcManExecVariant = ProcessManager.exec.overload('[Ljava.lang.String;', '[Ljava.lang.String;', 'java.lang.String', 'java.io.FileDescriptor', 'java.io.FileDescriptor', 'java.io.FileDescriptor', 'boolean');
ProcManExec.implementation = function(cmd, env, workdir, redirectstderr) {
var fake_cmd = cmd;
for (var i = 0; i < cmd.length; i = i + 1) {
var tmp_cmd = cmd[i];
if (tmp_cmd.indexOf("getprop") != -1 || tmp_cmd == "mount" || tmp_cmd.indexOf("build.prop") != -1 || tmp_cmd == "id") {
var fake_cmd = ["grep"];
send("Bypass " + cmdarr + " command");
}
if (tmp_cmd == "su") {
var fake_cmd = ["justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled"];
send("Bypass " + cmdarr + " command");
}
}
return ProcManExec.call(this, fake_cmd, env, workdir, redirectstderr);
};
ProcManExecVariant.implementation = function(cmd, env, directory, stdin, stdout, stderr, redirect) {
var fake_cmd = cmd;
for (var i = 0; i < cmd.length; i = i + 1) {
var tmp_cmd = cmd[i];
if (tmp_cmd.indexOf("getprop") != -1 || tmp_cmd == "mount" || tmp_cmd.indexOf("build.prop") != -1 || tmp_cmd == "id") {
var fake_cmd = ["grep"];
send("Bypass " + cmdarr + " command");
}
if (tmp_cmd == "su") {
var fake_cmd = ["justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled"];
send("Bypass " + cmdarr + " command");
}
}
return ProcManExecVariant.call(this, fake_cmd, env, directory, stdin, stdout, stderr, redirect);
};
}
if (useKeyInfo) {
KeyInfo.isInsideSecureHardware.implementation = function() {
send("Bypass isInsideSecureHardware");
return true;
}
}
/*
setImmediate(function(){
Java.perform(function(){
var exit_bypass = Java.use("android.content.DialogInterface.OnClickListener");
exit_bypass.onClick.implementation = function(arg, arg2){
console.log("[*] Exit Bypass");
}
})
})
*/
setImmediate(function(){
/*
var naver = Java.use("java.lang.Object");
naver.onCreate.implementation = function(agr) {
console.log("1111")
}
*/
/* var getVDR;
Java.choose("com.lgeha.nuts.security.module.SecurityModule",{
onMatch : function(instance){
getVDR = instance;
},
onComplete : function(){
console.log("[*] mSecurityModule apply Success");
}
});
getVDR.getVerifyDoneResult().implementation = function(){
return true;
};
*/
})
})
function SSLContext()
{
var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
var SSLContext = Java.use('javax.net.ssl.SSLContext');
// build fake trust manager
var TrustManager = Java.registerClass({
name: 'com.sensepost.test.TrustManager',
implements: [X509TrustManager],
methods: {
checkClientTrusted: function (chain, authType) {
},
checkServerTrusted: function (chain, authType) {
},
getAcceptedIssuers: function () {
return [];
}
}
});
// pass our own custom trust manager through when requested
var TrustManagers = [TrustManager.$new()];
var SSLContext_init = SSLContext.init.overload(
'[Ljavax.net.ssl.KeyManager;', '[Ljavax.net.ssl.TrustManager;', 'java.security.SecureRandom'
);
SSLContext_init.implementation = function (keyManager, trustManager, secureRandom) {
console.log('! Intercepted trustmanager request');
SSLContext_init.call(this, keyManager, TrustManagers, secureRandom);
};
console.log('* Setup custom trust manager');
}
function okhttp3()
{
try {
var CertificatePinner = Java.use('okhttp3.CertificatePinner');
CertificatePinner.check.overload('java.lang.String', 'java.util.List').implementation = function (str) {
console.log('! Intercepted okhttp3: ' + str);
return;
};
console.log('* Setup okhttp3 pinning')
} catch(err) {
console.log('* Unable to hook into okhttp3 pinner')
}
}
function trustkit()
{
try {
var Activity = Java.use("com.datatheorem.android.trustkit.pinning.OkHostnameVerifier");
Activity.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function (str) {
console.log('! Intercepted trustkit{1}: ' + str);
return true;
};
Activity.verify.overload('java.lang.String', 'java.security.cert.X509Certificate').implementation = function (str) {
console.log('! Intercepted trustkit{2}: ' + str);
return true;
};
console.log('* Setup trustkit pinning')
} catch(err) {
console.log('* Unable to hook into trustkit pinner')
}
}
function TrustManagerImpl()
{
try {
var TrustManagerImpl = Java.use('com.android.org.conscrypt.TrustManagerImpl');
TrustManagerImpl.verifyChain.implementation = function (untrustedChain, trustAnchorChain, host, clientAuth, ocspData, tlsSctData) {
console.log('! Intercepted TrustManagerImp: ' + host);
return untrustedChain;
}
var ArrayList = Java.use("java.util.ArrayList");
TrustManagerImpl.checkTrustedRecursive.implementation = function(certs, host, clientAuth, untrustedChain,
trustAnchorChain, used) {
console.log("[+] Bypassing TrustManagerImpl->checkTrustedRecursive()");
return ArrayList.$new();
};
console.log('* Setup TrustManagerImpl pinning')
} catch (err) {
console.log('* Unable to hook into TrustManagerImpl')
}
}
function Appcelerator()
{
try {
var PinningTrustManager = Java.use('appcelerator.https.PinningTrustManager');
PinningTrustManager.checkServerTrusted.implementation = function () {
console.log('! Intercepted Appcelerator');
}
console.log('* Setup Appcelerator pinning')
} catch (err) {
console.log('* Unable to hook into Appcelerator pinning')
}
}
Java.perform(function () {
console.log("");
console.log("[*] Universal SSL Bypass");
console.log("[1] javax.net.ssl.SSLContext.init()");
console.log("[2] okhttp3.CertificatePinner.check()");
console.log("[3] com.datatheorem.android.trustkit.pinning.OkHostnameVerifier.verify()");
console.log("[4] com.android.org.conscrypt.TrustManagerImpl.verifyChain()");
console.log("[5] appcelerator.https.PinningTrustManager.checkServerTrusted()");
console.log("");
//TODO: TrustManagerImpl.checkTrustedRecursive()
SSLContext();
okhttp3();
trustkit();
TrustManagerImpl();
Appcelerator();
var RootPackages = [
"com.noshufou.android.su",
"com.noshufou.android.su.elite",
"eu.chainfire.supersu",
"com.koushikdutta.superuser",
"com.thirdparty.superuser",
"com.yellowes.su",
"com.koushikdutta.rommanager",
"com.koushikdutta.rommanager.license",
"com.dimonvideo.luckypatcher",
"com.chelpus.lackypatch",
"com.ramdroid.appquarantine",
"com.ramdroid.appquarantinepro",
"com.devadvance.rootcloak",
"com.devadvance.rootcloakplus",
"de.robv.android.xposed.installer",
"com.saurik.substrate",
"com.zachspong.temprootremovejb",
"com.amphoras.hidemyroot",
"com.amphoras.hidemyrootadfree",
"com.formyhm.hiderootPremium",
"com.formyhm.hideroot",
"me.phh.superuser",
"eu.chainfire.supersu.pro",
"com.kingouser.com",
];
var RootBinaries = [
"su",
"busybox",
"supersu",
"Superuser.apk",
"KingoUser.apk",
"SuperSu.apk",
];
var RootProperties = {
"ro.build.selinux": "1",
"ro.debuggable": "0",
"service.adb.root": "0",
"ro.secure": "1",
};
var RootPropertiesKeys = [];
for (var k in RootProperties) RootPropertiesKeys.push(k);
var PackageManager = Java.use("android.app.ApplicationPackageManager");
var Runtime = Java.use("java.lang.Runtime");
var NativeFile = Java.use("java.io.File");
var String = Java.use("java.lang.String");
var SystemProperties = Java.use("android.os.SystemProperties");
var BufferedReader = Java.use("java.io.BufferedReader");
var ProcessBuilder = Java.use("java.lang.ProcessBuilder");
var StringBuffer = Java.use("java.lang.StringBuffer");
var loaded_classes = Java.enumerateLoadedClassesSync();
send("Loaded " + loaded_classes.length + " classes!");
var useKeyInfo = false;
var useProcessManager = false;
send("loaded: " + loaded_classes.indexOf("java.lang.ProcessManager"));
if (loaded_classes.indexOf("java.lang.ProcessManager") != -1) {
try {
//useProcessManager = true;
//var ProcessManager = Java.use('java.lang.ProcessManager');
} catch (err) {
send("ProcessManager Hook failed: " + err);
}
} else {
send("ProcessManager hook not loaded");
}
var KeyInfo = null;
if (loaded_classes.indexOf("android.security.keystore.KeyInfo") != -1) {
try {
//useKeyInfo = true;
//var KeyInfo = Java.use('android.security.keystore.KeyInfo');
} catch (err) {
send("KeyInfo Hook failed: " + err);
}
} else {
send("KeyInfo hook not loaded");
}
PackageManager.getPackageInfo.implementation = function (pname, flags) {
var shouldFakePackage = RootPackages.indexOf(pname) > -1;
if (shouldFakePackage) {
send("Bypass root check for package: " + pname);
pname = "set.package.name.to.a.fake.one.so.we.can.bypass.it";
}
return this.getPackageInfo.call(this, pname, flags);
};
NativeFile.exists.implementation = function () {
var name = NativeFile.getName.call(this);
var shouldFakeReturn = RootBinaries.indexOf(name) > -1;
if (shouldFakeReturn) {
send("Bypass return value for binary: " + name);
return false;
} else {
return this.exists.call(this);
}
};
var exec = Runtime.exec.overload("[Ljava.lang.String;");
var exec1 = Runtime.exec.overload("java.lang.String");
var exec2 = Runtime.exec.overload("java.lang.String", "[Ljava.lang.String;");
var exec3 = Runtime.exec.overload(
"[Ljava.lang.String;",
"[Ljava.lang.String;"
);
var exec4 = Runtime.exec.overload(
"[Ljava.lang.String;",
"[Ljava.lang.String;",
"java.io.File"
);
var exec5 = Runtime.exec.overload(
"java.lang.String",
"[Ljava.lang.String;",
"java.io.File"
);
exec5.implementation = function (cmd, env, dir) {
if (
cmd.indexOf("getprop") != -1 ||
cmd == "mount" ||
cmd.indexOf("build.prop") != -1 ||
cmd == "id" ||
cmd == "sh"
) {
var fakeCmd = "grep";
send("Bypass " + cmd + " command");
return exec1.call(this, fakeCmd);
}
if (cmd == "su") {
var fakeCmd =
"justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled";
send("Bypass " + cmd + " command");
return exec1.call(this, fakeCmd);
}
return exec5.call(this, cmd, env, dir);
};
exec4.implementation = function (cmdarr, env, file) {
for (var i = 0; i < cmdarr.length; i = i + 1) {
var tmp_cmd = cmdarr[i];
if (
tmp_cmd.indexOf("getprop") != -1 ||
tmp_cmd == "mount" ||
tmp_cmd.indexOf("build.prop") != -1 ||
tmp_cmd == "id" ||
tmp_cmd == "sh"
) {
var fakeCmd = "grep";
send("Bypass " + cmdarr + " command");
return exec1.call(this, fakeCmd);
}
if (tmp_cmd == "su") {
var fakeCmd =
"justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled";
send("Bypass " + cmdarr + " command");
return exec1.call(this, fakeCmd);
}
}
return exec4.call(this, cmdarr, env, file);
};
exec3.implementation = function (cmdarr, envp) {
for (var i = 0; i < cmdarr.length; i = i + 1) {
var tmp_cmd = cmdarr[i];
if (
tmp_cmd.indexOf("getprop") != -1 ||
tmp_cmd == "mount" ||
tmp_cmd.indexOf("build.prop") != -1 ||
tmp_cmd == "id" ||
tmp_cmd == "sh"
) {
var fakeCmd = "grep";
send("Bypass " + cmdarr + " command");
return exec1.call(this, fakeCmd);
}
if (tmp_cmd == "su") {
var fakeCmd =
"justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled";
send("Bypass " + cmdarr + " command");
return exec1.call(this, fakeCmd);
}
}
return exec3.call(this, cmdarr, envp);
};
exec2.implementation = function (cmd, env) {
if (
cmd.indexOf("getprop") != -1 ||
cmd == "mount" ||
cmd.indexOf("build.prop") != -1 ||
cmd == "id" ||
cmd == "sh"
) {
var fakeCmd = "grep";
send("Bypass " + cmd + " command");
return exec1.call(this, fakeCmd);
}
if (cmd == "su") {
var fakeCmd =
"justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled";
send("Bypass " + cmd + " command");
return exec1.call(this, fakeCmd);
}
return exec2.call(this, cmd, env);
};
exec.implementation = function (cmd) {
for (var i = 0; i < cmd.length; i = i + 1) {
var tmp_cmd = cmd[i];
if (
tmp_cmd.indexOf("getprop") != -1 ||
tmp_cmd == "mount" ||
tmp_cmd.indexOf("build.prop") != -1 ||
tmp_cmd == "id" ||
tmp_cmd == "sh"
) {
var fakeCmd = "grep";
send("Bypass " + cmd + " command");
return exec1.call(this, fakeCmd);
}
if (tmp_cmd == "su") {
var fakeCmd =
"justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled";
send("Bypass " + cmd + " command");
return exec1.call(this, fakeCmd);
}
}
return exec.call(this, cmd);
};
exec1.implementation = function (cmd) {
if (
cmd.indexOf("getprop") != -1 ||
cmd == "mount" ||
cmd.indexOf("build.prop") != -1 ||
cmd == "id" ||
cmd == "sh"
) {
var fakeCmd = "grep";
send("Bypass " + cmd + " command");
return exec1.call(this, fakeCmd);
}
if (cmd == "su") {
var fakeCmd =
"justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled";
send("Bypass " + cmd + " command");
return exec1.call(this, fakeCmd);
}
return exec1.call(this, cmd);
};
String.contains.implementation = function (name) {
if (name == "test-keys") {
send("Bypass test-keys check");
return false;
}
return this.contains.call(this, name);
};
var get = SystemProperties.get.overload("java.lang.String");
get.implementation = function (name) {
if (RootPropertiesKeys.indexOf(name) != -1) {
send("Bypass " + name);
return RootProperties[name];
}
return this.get.call(this, name);
};
Interceptor.attach(Module.findExportByName("libc.so", "fopen"), {
onEnter: function (args) {
var path = Memory.readCString(args[0]);
path = path.split("/");
var executable = path[path.length - 1];
var shouldFakeReturn = RootBinaries.indexOf(executable) > -1;
if (shouldFakeReturn) {
Memory.writeUtf8String(args[0], "/notexists");
send("Bypass native fopen");
}
},
onLeave: function (retval) {},
});
Interceptor.attach(Module.findExportByName("libc.so", "system"), {
onEnter: function (args) {
var cmd = Memory.readCString(args[0]);
send("SYSTEM CMD: " + cmd);
if (
cmd.indexOf("getprop") != -1 ||
cmd == "mount" ||
cmd.indexOf("build.prop") != -1 ||
cmd == "id"
) {
send("Bypass native system: " + cmd);
Memory.writeUtf8String(args[0], "grep");
}
if (cmd == "su") {
send("Bypass native system: " + cmd);
Memory.writeUtf8String(
args[0],
"justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled"
);
}
},
onLeave: function (retval) {},
});
/*
TO IMPLEMENT:
Exec Family
int execl(const char *path, const char *arg0, ..., const char *argn, (char *)0);
int execle(const char *path, const char *arg0, ..., const char *argn, (char *)0, char *const envp[]);
int execlp(const char *file, const char *arg0, ..., const char *argn, (char *)0);
int execlpe(const char *file, const char *arg0, ..., const char *argn, (char *)0, char *const envp[]);
int execv(const char *path, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]);
*/
BufferedReader.readLine.implementation = function () {
var text = this.readLine.call(this);
if (text === null) {
// just pass , i know it's ugly as hell but test != null won't work :(
} else {
var shouldFakeRead = text.indexOf("ro.build.tags=test-keys") > -1;
if (shouldFakeRead) {
send("Bypass build.prop file read");
text = text.replace(
"ro.build.tags=test-keys",
"ro.build.tags=release-keys"
);
}
}
return text;
};
var executeCommand = ProcessBuilder.command.overload("java.util.List");
ProcessBuilder.start.implementation = function () {
var cmd = this.command.call(this);
var shouldModifyCommand = false;
for (var i = 0; i < cmd.size(); i = i + 1) {
var tmp_cmd = cmd.get(i).toString();
if (
tmp_cmd.indexOf("getprop") != -1 ||
tmp_cmd.indexOf("mount") != -1 ||
tmp_cmd.indexOf("build.prop") != -1 ||
tmp_cmd.indexOf("id") != -1
) {
shouldModifyCommand = true;
}
}
if (shouldModifyCommand) {
send("Bypass ProcessBuilder " + cmd);
this.command.call(this, ["grep"]);
return this.start.call(this);
}
if (cmd.indexOf("su") != -1) {
send("Bypass ProcessBuilder " + cmd);
this.command.call(this, [
"justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled",
]);
return this.start.call(this);
}
return this.start.call(this);
};
if (useProcessManager) {
var ProcManExec = ProcessManager.exec.overload(
"[Ljava.lang.String;",
"[Ljava.lang.String;",
"java.io.File",
"boolean"
);
var ProcManExecVariant = ProcessManager.exec.overload(
"[Ljava.lang.String;",
"[Ljava.lang.String;",
"java.lang.String",
"java.io.FileDescriptor",
"java.io.FileDescriptor",
"java.io.FileDescriptor",
"boolean"
);
ProcManExec.implementation = function (cmd, env, workdir, redirectstderr) {
var fake_cmd = cmd;
for (var i = 0; i < cmd.length; i = i + 1) {
var tmp_cmd = cmd[i];
if (
tmp_cmd.indexOf("getprop") != -1 ||
tmp_cmd == "mount" ||
tmp_cmd.indexOf("build.prop") != -1 ||
tmp_cmd == "id"
) {
var fake_cmd = ["grep"];
send("Bypass " + cmdarr + " command");
}
if (tmp_cmd == "su") {
var fake_cmd = [
"justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled",
];
send("Bypass " + cmdarr + " command");
}
}
return ProcManExec.call(this, fake_cmd, env, workdir, redirectstderr);
};
ProcManExecVariant.implementation = function (
cmd,
env,
directory,
stdin,
stdout,
stderr,
redirect
) {
var fake_cmd = cmd;
for (var i = 0; i < cmd.length; i = i + 1) {
var tmp_cmd = cmd[i];
if (
tmp_cmd.indexOf("getprop") != -1 ||
tmp_cmd == "mount" ||
tmp_cmd.indexOf("build.prop") != -1 ||
tmp_cmd == "id"
) {
var fake_cmd = ["grep"];
send("Bypass " + cmdarr + " command");
}
if (tmp_cmd == "su") {
var fake_cmd = [
"justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled",
];
send("Bypass " + cmdarr + " command");
}
}
return ProcManExecVariant.call(
this,
fake_cmd,
env,
directory,
stdin,
stdout,
stderr,
redirect
);
};
}
if (useKeyInfo) {
KeyInfo.isInsideSecureHardware.implementation = function () {
send("Bypass isInsideSecureHardware");
return true;
};
}
});
0





