This commit is contained in:
chiteroman 2023-12-17 19:32:49 +01:00
parent 9152f7d661
commit 40cc836ae3
No known key found for this signature in database
GPG Key ID: 19171A27D600CC72
3 changed files with 246 additions and 141 deletions

View File

@ -11,8 +11,8 @@ android {
applicationId "es.chiteroman.bootloaderspoofer"
minSdk 26
targetSdk 34
versionCode 30
versionName '3.0'
versionCode 32
versionName '3.2'
multiDexEnabled false
}

View File

@ -7,6 +7,47 @@ public final class Data {
AwEHoUQDQgAEwCzLu4AL1c86SRwHKjgGlk3L16fbU3U8zWUa1hB+OwCxwqvyD686
HLsIKAgZluKMIAQQKRalYapz+tPSdJ4mig==
-----END EC PRIVATE KEY-----""";
public static final String RSA_PRIVATE_KEY = """
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----""";
public static final String CERT_1 = """
-----BEGIN CERTIFICATE-----
MIIB9DCCAXqgAwIBAgIRAM/Qn0kkZ6jXjzyH+K6CsO0wCgYIKoZIzj0EAwIwOTEM

View File

@ -4,14 +4,18 @@ import org.bouncycastle.asn1.ASN1Boolean;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Enumerated;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Null;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DLSequence;
import org.bouncycastle.asn1.DLSet;
import org.bouncycastle.asn1.DLTaggedObject;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
@ -25,17 +29,19 @@ import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
import java.io.StringReader;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.KeyStoreSpi;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodReplacement;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
@ -43,8 +49,10 @@ import de.robv.android.xposed.callbacks.XC_LoadPackage;
public final class Xposed implements IXposedHookLoadPackage {
private static final KeyPair EC_KEYPAIR;
private static final X509CertificateHolder holder_cert_1, holder_cert_2, holder_cert_3;
private static ASN1Sequence swEnforcedAuthList, teeEnforcedAuthList;
private static final Map<Integer, ASN1Primitive> map = new HashMap<>();
private static final SecureRandom random = new SecureRandom();
private static byte[] attestationChallengeBytes = new byte[0];
private static boolean brokenTEE = false;
static {
try {
@ -56,109 +64,58 @@ public final class Xposed implements IXposedHookLoadPackage {
EC_KEYPAIR = new JcaPEMKeyConverter().getKeyPair(pemKeyPair);
PemReader reader_cert_1 = new PemReader(new StringReader(Data.CERT_1));
PemObject pemObject = reader_cert_1.readPemObject();
parser.close();
holder_cert_1 = new X509CertificateHolder(pemObject.getContent());
PemReader reader_cert_2 = new PemReader(new StringReader(Data.CERT_2));
pemObject = reader_cert_2.readPemObject();
parser.close();
holder_cert_2 = new X509CertificateHolder(pemObject.getContent());
PemReader reader_cert_3 = new PemReader(new StringReader(Data.CERT_3));
pemObject = reader_cert_3.readPemObject();
parser.close();
holder_cert_3 = new X509CertificateHolder(pemObject.getContent());
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
private static List<Certificate> getOtherCertList() throws Throwable {
List<Certificate> certificates = new ArrayList<>();
private static X509CertificateHolder parseOtherCert(int num) {
String str = "";
var c1 = new JcaX509v3CertificateBuilder(
holder_cert_1.getSubject(),
holder_cert_1.getSerialNumber(),
holder_cert_1.getNotBefore(),
holder_cert_1.getNotAfter(),
holder_cert_1.getSubject(),
EC_KEYPAIR.getPublic()
);
if (num == 1) str = Data.CERT_1;
else if (num == 2) str = Data.CERT_2;
else if (num == 3) str = Data.CERT_3;
var c2 = new JcaX509v3CertificateBuilder(
holder_cert_2.getSubject(),
holder_cert_2.getSerialNumber(),
holder_cert_2.getNotBefore(),
holder_cert_2.getNotAfter(),
holder_cert_2.getSubject(),
EC_KEYPAIR.getPublic()
);
try {
PemReader reader = new PemReader(new StringReader(str));
PemObject pemObject = reader.readPemObject();
reader.close();
var c3 = new JcaX509v3CertificateBuilder(
holder_cert_3.getSubject(),
holder_cert_3.getSerialNumber(),
holder_cert_3.getNotBefore(),
holder_cert_3.getNotAfter(),
holder_cert_3.getSubject(),
EC_KEYPAIR.getPublic()
);
return new X509CertificateHolder(pemObject.getContent());
ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256withECDSA").build(EC_KEYPAIR.getPrivate());
X509CertificateHolder holder1 = c1.build(contentSigner);
X509CertificateHolder holder2 = c2.build(contentSigner);
X509CertificateHolder holder3 = c3.build(contentSigner);
certificates.add(new JcaX509CertificateConverter().getCertificate(holder1));
certificates.add(new JcaX509CertificateConverter().getCertificate(holder2));
certificates.add(new JcaX509CertificateConverter().getCertificate(holder3));
return certificates;
} catch (Exception e) {
XposedBridge.log("ERROR, couldn't parse other cert " + num + " : " + e);
throw new RuntimeException();
}
}
private static ASN1Primitive getEncodableFromList(int tagNo) {
private static Certificate[] getOtherCerts() throws Throwable {
for (ASN1Encodable asn1Encodable : teeEnforcedAuthList) {
ASN1TaggedObject taggedObject = (ASN1TaggedObject) asn1Encodable;
var holder_cert_1 = parseOtherCert(1);
var holder_cert_2 = parseOtherCert(2);
var holder_cert_3 = parseOtherCert(3);
if (taggedObject.getTagNo() == tagNo) {
return taggedObject.getBaseObject().toASN1Primitive();
}
}
Certificate c1 = new JcaX509CertificateConverter().getCertificate(holder_cert_1);
Certificate c2 = new JcaX509CertificateConverter().getCertificate(holder_cert_2);
Certificate c3 = new JcaX509CertificateConverter().getCertificate(holder_cert_3);
XposedBridge.log("Couldn't found " + tagNo + " object in TEE list");
return new Certificate[]{c1, c2, c3};
}
for (ASN1Encodable asn1Encodable : swEnforcedAuthList) {
ASN1TaggedObject taggedObject = (ASN1TaggedObject) asn1Encodable;
private static ASN1Primitive getPrimitiveFromList(int tagNo) {
if (taggedObject.getTagNo() == tagNo) {
return taggedObject.getBaseObject().toASN1Primitive();
}
}
XposedBridge.log("Couldn't found " + tagNo + " object in SW list");
if (map.containsKey(tagNo)) return map.get(tagNo);
return null;
}
private static Extension addHackedExtension(ASN1Sequence keyDescription) {
private static Extension addHackedExtension() {
try {
swEnforcedAuthList = (ASN1Sequence) keyDescription.getObjectAt(6).toASN1Primitive();
teeEnforcedAuthList = (ASN1Sequence) keyDescription.getObjectAt(7).toASN1Primitive();
byte[] bytes1 = new byte[32];
byte[] bytes2 = new byte[32];
SecureRandom secureRandom = new SecureRandom();
secureRandom.nextBytes(bytes1);
secureRandom.nextBytes(bytes2);
random.nextBytes(bytes1);
random.nextBytes(bytes2);
ASN1Encodable[] rootOfTrustEncodables = {
new DEROctetString(bytes1),
@ -169,54 +126,90 @@ public final class Xposed implements IXposedHookLoadPackage {
ASN1Sequence rootOfTrustSeq = new DLSequence(rootOfTrustEncodables);
var Apurpose = getEncodableFromList(1);
var Aalgorithm = getEncodableFromList(2);
var AkeySize = getEncodableFromList(3);
var AecCurve = getEncodableFromList(10);
var AnoAuthRequired = getEncodableFromList(503);
var AcreationDateTime = getEncodableFromList(701);
var Aorigin = getEncodableFromList(702);
var AosVersion = getEncodableFromList(705);
var AosPatchLevel = getEncodableFromList(706);
var AattestationApplicationId = getEncodableFromList(709);
var AvendorPatchLevel = getEncodableFromList(718);
var AbootPatchLevel = getEncodableFromList(719);
ASN1Integer[] purposesArray = {
new ASN1Integer(2),
new ASN1Integer(3)
};
DLSet Apurpose = new DLSet(purposesArray);
ASN1Integer Aalgorithm = new ASN1Integer(3);
ASN1Integer AkeySize = new ASN1Integer(256);
ASN1Integer AecCurve = new ASN1Integer(1);
ASN1Null AnoAuthRequired = DERNull.INSTANCE;
ASN1Integer AosVersion = new ASN1Integer(140000);
ASN1Integer AosPatchLevel = new ASN1Integer(202312);
ASN1Integer AvendorPatchLevel = new ASN1Integer(20231217);
ASN1Integer AbootPatchLevel = new ASN1Integer(20231217);
ASN1Primitive AcreationDateTime = null;
ASN1Primitive Aorigin = null;
ASN1Primitive AattestationApplicationId = null;
if (!brokenTEE) {
AcreationDateTime = getPrimitiveFromList(701);
Aorigin = getPrimitiveFromList(702);
AattestationApplicationId = getPrimitiveFromList(709);
}
var purpose = new DLTaggedObject(true, 1, Apurpose);
var algorithm = new DLTaggedObject(true, 2, Aalgorithm);
var keySize = new DLTaggedObject(true, 3, AkeySize);
var ecCurve = new DLTaggedObject(true, 10, AecCurve);
var noAuthRequired = new DLTaggedObject(true, 503, AnoAuthRequired);
var creationDateTime = new DLTaggedObject(true, 701, AcreationDateTime);
var origin = new DLTaggedObject(true, 702, Aorigin);
var rootOfTrust = new DLTaggedObject(true, 704, rootOfTrustSeq);
var osVersion = new DLTaggedObject(true, 705, AosVersion);
var osPatchLevel = new DLTaggedObject(true, 706, AosPatchLevel);
var attestationApplicationId = new DLTaggedObject(true, 709, AattestationApplicationId);
var vendorPatchLevel = new DLTaggedObject(true, 718, AvendorPatchLevel);
var bootPatchLevel = new DLTaggedObject(true, 719, AbootPatchLevel);
ASN1Encodable[] teeEnforcedEncodables = {
purpose,
algorithm,
keySize,
ecCurve,
noAuthRequired,
creationDateTime,
origin,
rootOfTrust,
osVersion,
osPatchLevel,
attestationApplicationId,
vendorPatchLevel,
bootPatchLevel
};
ASN1TaggedObject creationDateTime = null;
ASN1TaggedObject origin = null;
ASN1TaggedObject attestationApplicationId = null;
if (!brokenTEE) {
creationDateTime = new DLTaggedObject(true, 701, AcreationDateTime);
origin = new DLTaggedObject(true, 702, Aorigin);
attestationApplicationId = new DLTaggedObject(true, 709, AattestationApplicationId);
}
ASN1Encodable[] teeEnforcedEncodables;
if (brokenTEE) {
teeEnforcedEncodables = new ASN1Encodable[]{
purpose,
algorithm,
keySize,
ecCurve,
noAuthRequired,
rootOfTrust,
osVersion,
osPatchLevel,
vendorPatchLevel,
bootPatchLevel
};
} else {
teeEnforcedEncodables = new ASN1Encodable[]{
purpose,
algorithm,
keySize,
ecCurve,
noAuthRequired,
creationDateTime,
origin,
rootOfTrust,
osVersion,
osPatchLevel,
attestationApplicationId,
vendorPatchLevel,
bootPatchLevel
};
}
ASN1Integer attestationVersion = new ASN1Integer(4);
ASN1Enumerated attestationSecurityLevel = new ASN1Enumerated(2);
ASN1Integer keymasterVersion = new ASN1Integer(41);
ASN1Enumerated keymasterSecurityLevel = new ASN1Enumerated(2);
ASN1OctetString attestationChallenge = (ASN1OctetString) keyDescription.getObjectAt(4).toASN1Primitive();
ASN1OctetString attestationChallenge = new DEROctetString(attestationChallengeBytes);
ASN1OctetString uniqueId = new DEROctetString("".getBytes());
ASN1Sequence softwareEnforced = new DLSequence();
ASN1Sequence teeEnforced = new DLSequence(teeEnforcedEncodables);
@ -245,6 +238,56 @@ public final class Xposed implements IXposedHookLoadPackage {
return null;
}
private static void parseKeyDescription(ASN1Sequence keyDescription) {
ASN1Sequence swEnforcedAuthList = (ASN1Sequence) keyDescription.getObjectAt(6).toASN1Primitive();
ASN1Sequence teeEnforcedAuthList = (ASN1Sequence) keyDescription.getObjectAt(7).toASN1Primitive();
for (ASN1Encodable encodable : swEnforcedAuthList) {
ASN1TaggedObject taggedObject = (ASN1TaggedObject) encodable;
int tagNo = taggedObject.getTagNo();
ASN1Primitive asn1Primitive = taggedObject.getBaseObject().toASN1Primitive();
if (asn1Primitive == null) {
XposedBridge.log("ERROR, couldn't parse " + tagNo + " object!");
} else {
map.put(tagNo, asn1Primitive);
}
}
for (ASN1Encodable encodable : teeEnforcedAuthList) {
ASN1TaggedObject taggedObject = (ASN1TaggedObject) encodable;
int tagNo = taggedObject.getTagNo();
ASN1Primitive asn1Primitive = taggedObject.getBaseObject().toASN1Primitive();
if (asn1Primitive == null) {
XposedBridge.log("ERROR, couldn't parse " + tagNo + " object!");
} else {
map.put(tagNo, asn1Primitive);
}
}
}
private static Certificate brokenTeeLeafCert() throws Throwable {
var certBuilder = new JcaX509v3CertificateBuilder(
new X500Name("CN=chiteroman"),
new BigInteger(128, random),
new Date(System.currentTimeMillis()),
new Date(System.currentTimeMillis() + 365L * 24 * 60 * 60 * 1000),
new X500Name("CN=Android Keystore Key"),
EC_KEYPAIR.getPublic()
);
certBuilder.addExtension(addHackedExtension());
ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256withECDSA").build(EC_KEYPAIR.getPrivate());
X509CertificateHolder certHolder = certBuilder.build(contentSigner);
return new JcaX509CertificateConverter().getCertificate(certHolder);
}
private static Certificate hackLeafCert(X509Certificate certificate) throws Throwable {
var holder = new X509CertificateHolder(certificate.getEncoded());
@ -272,7 +315,9 @@ public final class Xposed implements IXposedHookLoadPackage {
ASN1Sequence keyDescription = ASN1Sequence.getInstance(extension.getExtnValue().getOctets());
certBuilder.addExtension(addHackedExtension(keyDescription));
parseKeyDescription(keyDescription);
certBuilder.addExtension(addHackedExtension());
ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256withECDSA").build(EC_KEYPAIR.getPrivate());
@ -284,34 +329,53 @@ public final class Xposed implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) {
try {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
KeyStoreSpi keyStoreSpi = (KeyStoreSpi) XposedHelpers.getObjectField(keyStore, "keyStoreSpi");
XposedHelpers.findAndHookMethod(keyStoreSpi.getClass(), "engineGetCertificateChain", String.class, new XC_MethodHook() {
Class<?> keyGenBuilder = XposedHelpers.findClass("android.security.keystore.KeyGenParameterSpec.Builder", lpparam.classLoader);
XposedHelpers.findAndHookMethod(keyGenBuilder, "setAttestationChallenge", byte[].class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) {
attestationChallengeBytes = (byte[]) param.args[0];
XposedBridge.log("attestationChallenge: " + Arrays.toString(attestationChallengeBytes));
}
});
Class<?> keyPairGenerator = XposedHelpers.findClass("android.security.keystore2.AndroidKeyStoreKeyPairGeneratorSpi", lpparam.classLoader);
XposedHelpers.findAndHookMethod(keyPairGenerator, "generateKeyPair", XC_MethodReplacement.returnConstant(EC_KEYPAIR));
Class<?> keyStoreSpi = XposedHelpers.findClass("android.security.keystore2.AndroidKeyStoreSpi", lpparam.classLoader);
XposedHelpers.findAndHookMethod(keyStoreSpi, "engineGetCertificateChain", String.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) {
try {
Certificate[] certificates = (Certificate[]) param.getResultOrThrowable();
Certificate leaf = certificates[0];
if (!(leaf instanceof X509Certificate x509Certificate)) return;
byte[] bytes = x509Certificate.getExtensionValue("1.3.6.1.4.1.11129.2.1.17");
if (bytes == null || bytes.length == 0) {
XposedBridge.log("Leaf certificate doesn't contain attestation extensions... Ignoring it.");
return;
}
List<Certificate> otherCerts = getOtherCertList();
Certificate[] otherCerts = getOtherCerts();
Certificate[] hackCerts = new Certificate[4];
hackCerts[0] = hackLeafCert(x509Certificate);
System.arraycopy(otherCerts, 0, hackCerts, 1, otherCerts.length);
hackCerts[1] = otherCerts.get(0);
hackCerts[2] = otherCerts.get(1);
hackCerts[3] = otherCerts.get(2);
Certificate[] certificates = (Certificate[]) param.getResult();
if (certificates == null || certificates.length == 0) {
brokenTEE = true;
XposedBridge.log("Uhhh, seems like you have a broken TEE.");
hackCerts[0] = brokenTeeLeafCert();
} else {
brokenTEE = false;
Certificate leaf = certificates[0];
if (!(leaf instanceof X509Certificate x509Certificate)) return;
byte[] bytes = x509Certificate.getExtensionValue("1.3.6.1.4.1.11129.2.1.17");
if (bytes == null || bytes.length == 0) {
XposedBridge.log("Leaf certificate doesn't contain attestation extensions... Ignoring it.");
return;
}
hackCerts[0] = hackLeafCert(x509Certificate);
}
param.setResult(hackCerts);
@ -321,7 +385,7 @@ public final class Xposed implements IXposedHookLoadPackage {
}
});
} catch (Throwable t) {
XposedBridge.log(t);
XposedBridge.log("ERROR: " + t);
}
}
}