Spoof software attestation

This commit is contained in:
chiteroman 2023-12-11 23:03:10 +01:00
parent ec68625b96
commit a987e0ebb9
No known key found for this signature in database
GPG Key ID: 19171A27D600CC72
1 changed files with 76 additions and 8 deletions

View File

@ -6,9 +6,18 @@ import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import java.io.StringReader;
import java.lang.reflect.Method;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.KeyStoreSpi;
import java.security.cert.Certificate;
@ -23,6 +32,24 @@ import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
public final class Xposed implements IXposedHookLoadPackage {
private static final String SW_RSA_ATTEST_ROOT_KEY = """
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCia63rbi5EYe/VDoLmt5TRdSMfd5tjkWP/96r/C3JHTsAsQ+wz
fNes7UA+jCigZtX3hwszl94OuE4TQKuvpSe/lWmgMdsGUmX4RFlXYfC78hdLt0GA
ZMAoDo9Sd47b0ke2RekZyOmLw9vCkT/X11DEHTVm+Vfkl5YLCazOkjWFmwIDAQAB
AoGAU8dxXchmqzVNbbvff7zgUa63YErk51Yem/EXzhkMaIXRkMO0edaCtZtnkRvg
9OQ2qEiLWaCTlUoyU7H/HUn2lwTQsOXyZI7dHijVDRMIv1mmrHCrGW/JC8FXfPLS
r3L3KoHXQVYL2mslbR8Rpogxq4WwnwK6XqSTH9mynFwQwEkCQQDMX3EZk3ricWVH
ruXD0BpXOMMpZuLu4rg5+1L51WEJvItIMeSjLuNa+g3AI8AYTYYi/aSLk6XEv82L
iXFGmJ2XAkEAy3M8k8Z0QzHae4olduqoHVWEarBtDE+fqFQBWgdm8fZhdHWrvlAc
qwJIXMUVc+dWm/FAQarCjbqWqhCRdaYgnQJBAJ7z7GdUCVNtlrQ2F4ZAqPwFreTZ
nM7njxmpm1Os3hhQiJPSGl3A7huoOGGkbJd6VEWKuRvF7jwkYZ2RfITH1mkCQAvh
X9E1Toa5+4spRwTJsSV9X+0m/kcwwx7+QNH0CrPockptsKi9Xt8xk+4u6BDLmogi
r2DmStQh6DhoHUZkfBUCQQCOgBkqH/15drpdR+BQH3VaP4/ALFfxR9E3G+lS+M5a
IqJEk9kh8vjuGzTaAZyU5keUmpWNc1gI7OvDMaH4+8vQ
-----END RSA PRIVATE KEY-----
""";
private static volatile boolean hardwareAttesatation = true;
private static int indexOf(byte[] array, byte[] target) {
outer:
@ -45,10 +72,24 @@ public final class Xposed implements IXposedHookLoadPackage {
ASN1Sequence keyDescription = ASN1Sequence.getInstance(extension.getExtnValue().getOctets());
ASN1Sequence swEnforcedAuthList = (ASN1Sequence) keyDescription.getObjectAt(6).toASN1Primitive();
ASN1Sequence teeEnforcedAuthList = (ASN1Sequence) keyDescription.getObjectAt(7).toASN1Primitive();
ASN1Sequence rootOfTrustAuthList = null;
for (ASN1Encodable encodable : swEnforcedAuthList) {
if (!(encodable instanceof ASN1TaggedObject asn1TaggedObject)) continue;
if (asn1TaggedObject.getTagNo() != 704) continue;
rootOfTrustAuthList = (ASN1Sequence) asn1TaggedObject.getBaseObject().toASN1Primitive();
hardwareAttesatation = false;
break;
}
for (ASN1Encodable encodable : teeEnforcedAuthList) {
if (!(encodable instanceof ASN1TaggedObject asn1TaggedObject)) continue;
@ -56,6 +97,8 @@ public final class Xposed implements IXposedHookLoadPackage {
rootOfTrustAuthList = (ASN1Sequence) asn1TaggedObject.getBaseObject().toASN1Primitive();
hardwareAttesatation = true;
break;
}
@ -72,12 +115,35 @@ public final class Xposed implements IXposedHookLoadPackage {
X509CertificateHolder modCert = new X509CertificateHolder(bytes);
if (hardwareAttesatation) {
JcaX509CertificateConverter converter = new JcaX509CertificateConverter();
return converter.getCertificate(modCert);
} else {
PEMParser parser = new PEMParser(new StringReader(SW_RSA_ATTEST_ROOT_KEY));
PEMKeyPair pemKeyPair = (PEMKeyPair) parser.readObject();
parser.close();
JcaPEMKeyConverter jcaPEMKeyConverter = new JcaPEMKeyConverter();
KeyPair keyPair = jcaPEMKeyConverter.getKeyPair(pemKeyPair);
X509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(certificateHolder.getSubject(), certificateHolder.getSerialNumber(), certificateHolder.getNotBefore(), certificateHolder.getNotAfter(), certificateHolder.getSubject(), keyPair.getPublic());
certBuilder.copyAndAddExtension(extension.getExtnId(), extension.isCritical(), modCert);
ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WithRSAEncryption").build(keyPair.getPrivate());
X509CertificateHolder certHolder = certBuilder.build(contentSigner);
return new JcaX509CertificateConverter().getCertificate(certHolder);
}
} catch (Exception e) {
XposedBridge.log("ERROR in creating certificate: " + e);
XposedBridge.log("ERROR creating certificate: " + e);
}
return certificate;
@ -95,14 +161,16 @@ public final class Xposed implements IXposedHookLoadPackage {
protected void afterHookedMethod(MethodHookParam param) {
Certificate[] certificates = (Certificate[]) param.getResult();
for (Method declaredMethod : certificates[0].getClass().getDeclaredMethods()) {
if (declaredMethod.getName().toLowerCase(Locale.ROOT).contains("verify")) {
XposedBridge.hookMethod(declaredMethod, XC_MethodReplacement.DO_NOTHING);
}
}
certificates[0] = doLogic(certificates[0]);
if (hardwareAttesatation) {
for (Method method : certificates[0].getClass().getMethods()) {
if (method.getName().toLowerCase(Locale.ROOT).contains("verify")) {
XposedBridge.hookMethod(method, XC_MethodReplacement.DO_NOTHING);
}
}
}
param.setResult(certificates);
}
});