## https://sploitus.com/exploit?id=F7DD09CB-9C31-5949-B77C-4791D0C4B888
# PHPGurukul Small CRM - Insecure Deserialization (PHP Object Injection)
**CVE: pending (submitted to VulDB)**
**Affected:** PHPGurukul Small CRM v3.0 - v4.0
**Vendor:** https://phpgurukul.com/small-crm-php/
**Weakness:** CWE-502 Deserialization of Untrusted Data
## Summary
The login success handler of `/crm/login.php` performs a server-side request to
the third-party geolocation service over **plaintext HTTP** and passes the
unvalidated response directly to `unserialize()` without restricting
`allowed_classes`. Any on-path attacker (ARP spoofing, DNS cache poisoning,
malicious hosting provider) can intercept or replace that response with a
crafted serialized payload, which the server then deserializes. This leads to
PHP Object Injection and, when a usable gadget chain exists, arbitrary code
execution under the web server account.
## Vulnerable code
`crm/login.php` (lines 18-22), executed on every successful login:
```php
$ip_address = $_SERVER['REMOTE_ADDR'];
$geopluginURL = 'http://www.geoplugin.net/php.gp?ip=' . $ip_address; // (1) plaintext HTTP
$addrDetailsArr = unserialize(file_get_contents($geopluginURL)); // (2) CWE-502
$city = $addrDetailsArr['geoplugin_city'];
$country = $addrDetailsArr['geoplugin_countryName'];
```
Issue (1): the request uses `http://` instead of `https://`, so the channel is
unencrypted and modifiable in transit.
Issue (2): `unserialize()` is called on data returned by a third-party network
service without `array('allowed_classes' => false)`, allowing instantiation of
arbitrary objects from the attacker-controlled stream.
## Proof of Concept
Attack preconditions:
1. Attacker can control the network path between the CRM server and
`www.geoplugin.net` (MITM), e.g.:
- ARP spoofing on the same LAN,
- DNS cache poisoning, or
- pointing the service host at an attacker-controlled host via the CRM
server's `hosts` file (local demo).
2. Attacker has valid CRM credentials (or obtains them; credentials are stored
in plaintext in the database).
Steps:
1. Start the malicious geolocation server:
```
python exploit.py --port 80
```
It answers every request with a crafted serialized payload
(`payload.ser`).
2. Redirect `www.geoplugin.net` to the attacker host (hosts file / ARP / DNS).
3. Log in to the CRM with valid credentials.
4. On `login.php` the application deserializes the attacker-controlled
response (line 20):
```php
$addrDetailsArr = unserialize(file_get_contents($geopluginURL));
```
The serialized payload is a PHP object of the attacker's choosing:
```
O:8:"GadgetClass":1:{s:4:"prop";s:3:"val";}
```
With a POP/gadget chain present in the application or its bundled libraries,
this escalates to arbitrary code execution.
## Impact
- PHP Object Injection / potential remote code execution (conditional on
gadget chain availability).
- Arbitrary object instantiation, unexpected application behaviour.
- Client IP transmitted in cleartext to a third-party service.
## Remediation
```php
$geopluginURL = 'https://www.geoplugin.net/json.gp?ip=' . $ip_address;
$addrDetails = json_decode(file_get_contents($geopluginURL), true);
```
- Use the HTTPS JSON endpoint and parse with `json_decode()`.
- If `unserialize()` must be used, always pass `['allowed_classes' => false]`.
## References
- https://securized.dev/geoplugin-insecure-unserialize/
- https://cwe.mitre.org/data/definitions/502.html
- https://www.geoplugin.com/examples
## Disclaimer
This PoC is provided for security research and authorized testing only.
Do not use against systems you do not own or have explicit permission to test.