Java SignedObject-gated Deserialization na Upatikanaji wa Pre-auth kupitia Njia za Makosa

Reading time: 7 minutes

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Ukurasa huu unaelezea muundo wa kawaida wa Java deserialization "iliyolindwa" unaojengwa karibu na java.security.SignedObject na jinsi sinks zinazojionyesha kuwa zisizofikika zinaweza kuwa zinapatikana kabla ya uthibitisho kupitia mtiririko wa kushughulikia makosa. Mbinu hii ilionekana katika Fortra GoAnywhere MFT (CVE-2025-10035) lakini inaweza kutumika kwa miundo inayofanana.

Mfano wa tishio

  • Mshambuliaji anaweza kufikia endpoint ya HTTP ambayo hatimaye inashughulikia byte[] iliyotolewa na mshambuliaji iliyokusudiwa kuwa serialized SignedObject.
  • Msimbo unatumia validating wrapper (mf. Apache Commons IO ValidatingObjectInputStream au adapter maalum) kukandamiza aina ya nje kabisa kwa SignedObject (au byte[]).
  • Kitu cha ndani kilichorudishwa na SignedObject.getObject() ndiko ambapo gadget chains zinaweza kuzinduka (mf. CommonsBeanutils1), lakini ni baada tu ya lango la uhakiki wa saini.

Mfano wa kawaida wenye hatari

Mfano uliorahisishwa unaotokana na com.linoma.license.gen2.BundleWorker.verify:

java
private static byte[] verify(byte[] payload, KeyConfig keyCfg) throws Exception {
String sigAlg = "SHA1withDSA";
if ("2".equals(keyCfg.getVersion())) {
sigAlg = "SHA512withRSA";        // key version controls algorithm
}
PublicKey pub = getPublicKey(keyCfg);
Signature sig = Signature.getInstance(sigAlg);

// 1) Outer, "guarded" deserialization restricted to SignedObject
SignedObject so = (SignedObject) JavaSerializationUtilities.deserialize(
payload, SignedObject.class, new Class[]{ byte[].class });

if (keyCfg.isServer()) {
// Hardened server path
return ((SignedContainer) JavaSerializationUtilities.deserializeUntrustedSignedObject(
so, SignedContainer.class, new Class[]{ byte[].class }
)).getData();
} else {
// 2) Signature check using a baked-in public key
if (!so.verify(pub, sig)) {
throw new IOException("Unable to verify signature!");
}
// 3) Inner object deserialization (potential gadget execution)
SignedContainer inner = (SignedContainer) so.getObject();
return inner.getData();
}
}

Key observations:

  • The validating deserializer at (1) blocks arbitrary top-level gadget classes; only SignedObject (or raw byte[]) is accepted.
  • The RCE primitive would be in the inner object materialized by SignedObject.getObject() at (3).
  • A signature gate at (2) enforces that the SignedObject must verify against a product-baked public key. Unless the attacker can produce a valid signature, the inner gadget never deserializes.

Mizingatio ya unyonyeshaji

Ili kufikia utekelezaji wa msimbo, muadui lazima awasilishe SignedObject iliyosainiwa ipasavyo ambayo inafunga gadget chain yenye madhara kama inner object. Hii kwa kawaida inahitaji mojawapo ya yafuatayo:

  • Private key compromise: obtain the matching private key used by the product to sign/verify license objects.
  • Signing oracle: coerce the vendor or a trusted signing service to sign attacker-controlled serialized content (e.g., if a license server signs an embedded arbitrary object from client input).
  • Alternate reachable path: find a server-side path that deserializes the inner object without enforcing verify(), or that skips signature checks under a specific mode.

Bila mojawapo ya haya, uthibitisho wa saini utazuia unyonyeshaji licha ya kuwepo kwa deserialization sink.

Pre-auth reachability via error-handling flows

Hata wakati endpoint ya deserialization inaonekana kuhitaji authentication au token iliyounganishwa na session, msimbo wa kushughulikia makosa unaweza kwa bahati mbaya kuunda na kushika token kwenye session isiyotambuliwa.

Example reachability chain (GoAnywhere MFT):

  • Target servlet: /goanywhere/lic/accept/ requires a session-bound license request token.
  • Error path: hitting /goanywhere/license/Unlicensed.xhtml with trailing junk and invalid JSF state triggers AdminErrorHandlerServlet, which does:
  • SessionUtilities.generateLicenseRequestToken(session)
  • Redirects to vendor license server with a signed license request in bundle=<...>
  • The bundle can be decrypted offline (hard-coded keys) to recover the GUID. Keep the same session cookie and POST to /goanywhere/lic/accept/ with attacker-controlled bundle bytes, reaching the SignedObject sink pre-auth.

Proof-of-reachability (impact-less) probe:

http
GET /goanywhere/license/Unlicensed.xhtml/x?javax.faces.ViewState=x&GARequestAction=activate HTTP/1.1
Host: <target>
  • Unpatched: 302 Location header to https://my.goanywhere.com/lic/request?bundle=... na Set-Cookie: ASESSIONID=...
  • Patched: redirect bila bundle (hakuna token generation).

Blue-team detection

Viashiria katika stack traces/logs vinaonyesha kwa nguvu majaribio ya kufikia SignedObject-gated sink:

java.io.ObjectInputStream.readObject
java.security.SignedObject.getObject
com.linoma.license.gen2.BundleWorker.verify
com.linoma.license.gen2.BundleWorker.unbundle
com.linoma.license.gen2.LicenseController.getResponse
com.linoma.license.gen2.LicenseAPI.getResponse
com.linoma.ga.ui.admin.servlet.LicenseResponseServlet.doPost

Mwongozo wa kuimarisha

  • Hakikisha uthibitishaji wa saini unafanyika kabla ya mwito wowote wa getObject() na uhakikishe uthibitisho unatumia ufunguo/algoritimu ya umma iliyokusudiwa.
  • Badilisha miito ya moja kwa moja ya SignedObject.getObject() na wrapper uliosimamiwa (hardened) ambao unatendee tena uchujaji kwenye stream ya ndani (mfano: deserializeUntrustedSignedObject ikitumia ValidatingObjectInputStream/ObjectInputFilter orodha za kuruhusu).
  • Ondoa mitiririko ya error-handler ambayo hutoa token zinazounganishwa na session kwa watumiaji wasiojathibitishwa. Chukulia njia za makosa kama uso wa shambulio.
  • Tumia kwa upendeleo Java serialization filters (JEP 290) zenye orodha kali za kuruhusu kwa deserialization za nje na za ndani. Mfano:
java
ObjectInputFilter filter = info -> {
Class<?> c = info.serialClass();
if (c == null) return ObjectInputFilter.Status.UNDECIDED;
if (c == java.security.SignedObject.class || c == byte[].class) return ObjectInputFilter.Status.ALLOWED;
return ObjectInputFilter.Status.REJECTED; // outer layer
};
ObjectInputFilter.Config.setSerialFilter(filter);
// For the inner object, apply a separate strict DTO allow-list

Muhtasari wa mnyororo wa shambulio (CVE-2025-10035)

  1. Pre-auth token minting kupitia meneja wa makosa:
http
GET /goanywhere/license/Unlicensed.xhtml/watchTowr?javax.faces.ViewState=watchTowr&GARequestAction=activate

Pokea 302 na bundle=... na ASESSIONID=...; decrypt bundle offline ili kupata GUID.

  1. Fikia sink pre-auth na cookie sawa:
http
POST /goanywhere/lic/accept/<GUID> HTTP/1.1
Cookie: ASESSIONID=<value>
Content-Type: application/x-www-form-urlencoded

bundle=<attacker-controlled-bytes>
  1. RCE inahitaji SignedObject iliyosainiwa kikamilifu inayozunguka gadget chain. Watafiti hawakuweza kupitisha uthibitishaji wa saini; unyonyaji unategemea upatikanaji wa private key inayolingana au signing oracle.

Toleo zilizosahihishwa na mabadiliko ya tabia

  • GoAnywhere MFT 7.8.4 and Sustain Release 7.6.3:
  • Imarisha deserialization ya ndani kwa kubadilisha SignedObject.getObject() na wrapper (deserializeUntrustedSignedObject).
  • Ondoa uzalishaji wa token za error-handler, kukata ufikiaji wa pre-auth.

Maelezo kuhusu JSF/ViewState

Mbinu ya kufikia inatumia ukurasa wa JSF (.xhtml) na javax.faces.ViewState isiyo halali ili kupitisha kwenye error handler iliyo na mamlaka. Ingawa sio tatizo la deserialization ya JSF, ni mtindo unaojirudia kabla ya uthibitisho (pre-auth): ingia kwenye error handlers zinazofanya vitendo vyenye mamlaka na kuweka attributes za session zinazohusiana na usalama.

References

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks