[Translation] Architecture of Ransomware Part 1

안녕하세요! idioth입니다. 오랜만에 번역글을 하나 들고 왔습니다. 최근 ghidra 시리즈를 진행 + 학교 과제 + 그 외의 개인 사정으로 인해 보려고 했던 글을 좀 미뤄놔서 좀 제 자신을 환기시킬 겸 읽으면서 번역을 쫙해봤습니다.

랜섬웨어가 유행이라고 해야 하나 보안 필드의 사람들 뿐만 아니라 일반적인 사람한테도 많이 익숙해진 지는 꽤 되었다고 생각을 합니다. 하지만 랜섬웨어는 계속해서 발전하고 있죠! 파트 1 부분은 너무 어렵지 않은 이야기가 주를 이루니 가벼운 마음으로(?) 읽어주시면 될 것 같습니다!

번역글은 늘…ㅎㅎ 의역과 오역이 존재할 수 있고 잘못된 부분은 지적해주시면 감사하겠습니다!


원문 글 : Architecture of a ransomware (1/2)

COVID-19로 인해 원격 업무가 증가함에 따라 랜섬웨어와 관련된 사건이 증가하고 있다. 모든 랜섬웨어는 같은 방식으로 동작하지 않으며 공격에 더 나은 대응을 하기 위해서는 내부적으로 어떻게 동작하는지 이해하는 것이 중요하다. 이 게시글이 랜섬웨어의 암호 메커니즘을 리버싱하거나 감염을 막는데 도움이 되길 바란다.

어떤 방식으로 동작하는지 파악하는데 가장 좋은 방법은 직접 만들어보는 것이다. 따라서 파트 1에서는 원리와 개념에 대해 설명하고 파트 2에서는 원리를 적용시켜 랜섬웨어를 만들어 볼 것이다.

기본 원리

랜섬웨어에서 가장 중요한 개념은 사용되는 암호화 유형이다. 주로 사용되는 두 가지가 있고 괜찮은 랜섬웨어들에서도 사용된다. 간단하게 설명하고 스스로 공부할 수 있는 reference를 제공할 것이다.

대칭키 암호화

대칭키 암호화는 대부분 사람들에게 익숙하다. 한 개의 키를 가지고 데이터 암호화, 복호화에 모두 사용한다. zip 파일와 office 문서 등에 사용되며 암호화할 때 사용한 password와 복호화에 사용하는 password가 같다.

비대칭키 암호화

비대칭키 암호화는 대부분 사람들이 혼란스러워하는 개념이다. 하지만 특정 구현을 생각하지 않으면 이해하기 쉽다.

일반적으로 비대칭키 암호화는 두 개의 키를 사용한다. 모든 키를 사용해서 파일을 암호화할 수 있지만 다른 키를 사용해서 복호화를 해야 한다.

secret key와 public key에 대해서 들어봤을 것이다. 이것들은 이름처럼 단순하게 public 하거나 secret 하게 보관되는 키이다. 누구나 public key에 접근할 수 있고 암호화에 사용할 수 있지만 복호화에 secret key가 필요하기 때문에 해당 키의 소유자만이 복호화할 수 있다. 그리고 secret key를 사용해 모든 정보를 암호화할 수 있으며 해당 키 소유자의 public key를 통해 누구나 읽을 수 있다. 이러한 행위를 signing이라 부르며 비밀 목적이 아니라 해당 메시지를 보낸 사람을 증명하기 위해서 사용된다.

랜섬웨어 관련 애플리케이션

regular infection의 흐름을 생각해보자. 랜섬웨어 페이로드는 여러 가지 벡터(피싱, 소프트웨어 취약점 등) 중 하나에 의해 전달되고 실행되어 모든 파일이 암호화된다. 그 후 파일을 복호화하기 위해 무언가를 지불하라는 창이 뜬다. 이를 어떻게 수행할 수 있을까?

첫 번째는 대칭키 암호화를 통해 파일을 암호화하는 것이다. 하지만 이는 좋은 방법이 아니다. 괜찮은 랜섬웨어들은 한 가지 중요한 이유로 이 방법을 사용하지 않는다. 랜섬웨어가 파일을 암호화할 때, 어딘가에 암호화 키가 존재할 것이다. 대칭키 암호화를 사용한다면 암호화에 사용된 키가 복호화에 사용될 수 있다. 포렌식 분석가가 암호화에 사용된 키를 복구하여 파일을 복호화할 수 있다. 비대칭 key를 사용하면 암호화와 복호화에 다른 키를 사용하므로 복호화 키만 잘 보호하면 victim의 컴퓨터에 암호화 키가 있는 것은 큰 문제가 되지 않는다.

해커로서 고민해야 할 다른 중요한 점은 victim이 지불했을 경우를 위한 키가 필요한 것이다. 대칭키 암호화를 사용하면 바이너리 코드에 키를 하드코딩(리버싱할 수 있으므로 안 좋은 방법이다)하거나 키를 생성해서 우리의 서버에 전송할 방법(intercept 당할 수 있고 연결이 끊어지면 키가 없어서 키를 줄 수 없다)을 찾아야 한다. 이런 형태의 첫 번째 랜섬웨어는 CryptoDefense의 변종으로 생성된 키를 서버로 전송한 후 victim의 로컬에 파일을 남기는 바람에 복호화가 가능했다.

이러한 점은 파일을 암호화할 때 비대칭키 암호화를 사용해야 한다는 걸 알려준다. 하지만 key pair를 생성한 후 public key를 코드에 하드 코딩하여 모든 파일을 암호화하는 것은 불가능하다.

비대칭키 암호화는 대칭키 암호화에 비해서 느리다. 파일을 암호화는 것이 오래 걸리면 victim이 알아차리고 컴퓨터를 꺼서 암호화가 실패할 수 있다. 그러면 어떻게 해야 할까?

하이브리드 접근법

이 문제를 해결하기 위해 하이브리드 접근법을 사용할 수 있다. 페이로드를 생성할 때 페이로드와 관련된 public/private key도 생성한다. 페이로드에 public key를 하드 코딩하고 infection이 발생할 때마다 페이로드는 대칭 암호화에 사용될 키를 생성한다. 암호화가 되면 하드 코딩된 public key로 대칭 키를 암호화한다(물론 메모리/디스크의 평문 대칭키는 없앤다). 암호화된 대칭 키는 어딘가에 저장된다. 하지만 다른 문제가 존재한다.

Key re utilization / chosen plaintext attack

Chosen plaintext attack은 암호화 전 평문을 알고 있고 암호화된 샘플이 많을 경우 암호화된 결과에서 키를 유추할 수 있는 암호화 공격이다. 잘 알려진 포맷을 가진 대부분 파일의 헤더에서 발생할 수 있다. 모든 파일에 같은 키를 사용한다면 특정 조건에서 복호화될 수 있다. 이 문제는 실제로 DirCrypt에서 발생했다. 잘못된 암호화 구현과 key 재사용으로 인해 암호화가 리버싱 되었다.

이 이슈는 각 파일에 다른 키를 사용하여 해결할 수 있다. 파일마다 대칭키를 생성해서 암호화하고 페이로드에 있는 public key로 키를 암호화한 후 암호화된 대칭 키를 저장하고 평문으로 된 대칭 키를 삭제할 수 있다.

많은 랜섬웨어들은 이 방법을 사용하여 암호화된 파일 이름 + 암호화된 public key가 적힌 텍스트 파일을 생성한다. 복호화 툴을 사용하면 이 텍스트 파일을 읽어서 private key로 각 키를 복호화한 후 파일을 복호화한다. 우리는 다른 것을 사용할 것이다.

Technical note: 이러한 유형의 공격은 기본적으로 각 파일 스트림에 다른 randomized initialization vector(IV)를 사용하므로 우리가 사용할 AES-256에는 영향을 받지 않지만, 모든 랜섬웨어에 대한 일반적인 개념을 설명하고 싶었다. 악성코드 개발자가 실수하면 데이터를 복구하는데 도움이 되었으면 한다.

이 공격은 기본적으로 randomize 되지 않기 때문에 RSA 암호화에 영향을 줄 수 있다. 다음의 이유 때문에 우리에 대해서는 문제가 되지 않을 것이다:
a) RSA를 사용하여 암호화할 것은 AES 암호화 키뿐이며 분석할 샘플을 구성하지 않는다.
b) 암호화에 randomziation을 추가하는 Optimal asymmetric encryption padding과 결합된 RSA를 사용할 것이다.

파일마다 다른 키를 사용해서 오는 다른 이득은 각 파일을 암호화한 후 암호화 키를 삭제할 수 있는 것이다. 따라서 분석가가 키를 복구하려고 하면 마지막 파일에 사용된 키만 복구할 수 있다. 모든 파일에 같은 키를 사용하면 암호화 과정의 어떤 부분에서든 키를 복구할 수 있고 모든 파일을 복구할 수 있다.

속도 고려

위에서 설명한 모든 특징을 적용시켜 코딩한 랜섬웨어는 만족스럽지 않았다. 32비트 키(AES-256)를 사용할 때 초기 벤치마크에서 1분에 1GB 암호화 속도가 나왔다. 이 속도는 victim의 하드웨어 의존성이 높고, 필자의 컴퓨터를 암호화할 수 없으므로 VM에서 실행했지만 여전히 1TB를 암호화하는데 16분이 걸렸다.

현대의 랜섬웨어들은 어떻게 몇 기가바이트의 정보를 초 단위로 암호화할까? 정답은 파일 구조(file structure)에 있다.

사실상 파일의 모든 부분을 사용할 수 없게 암호화할 필요가 없다. 파일 포맷에 따라 헤더와 initial bytes만 암호화해도 사용할 수 없게 만들 수 있다. 아마도 파일의 첫 5MB만 암호화하면 된다. 무슨 생각을 하는지 알고 있다. txt/ascii 파일 같은 간단한 파일은 strings 같은 툴을 사용해서 읽을 수 있지만 그런 파일들은 대부분 2kb를 넘지 않는다. 게다가 victim에게 중요한 파일 대부분은 문서, 사진, 비디오이다. 파일에 대해 포렌식 분석을 시도하고 내용 일부를 복구할 수 있지만 개별적인 파일에 대해 수행하는 수동적인 방법이고 현실적이지 않다.

파일의 마지막 부분을 바꾸는 것도 이상적이며 끝 부분에 2개의 구조를 추가하여 활용할 수 있다.

  1. Initalization vector: AES로 파일을 암호화할 때 initialization vector가 필요하다. 이는 암호화 프로세스를 시작할 때 생성된다.
  2. Encrypted decryption key: 각 파일의 끝에 암호화된 복호화 키를 추가할 수 있다. 이는 파일들의 암호화 키를 담은 text 파일의 필요성을 없애준다.

이런 것들이 추가된 암호화된 파일 구조는 다음과 같다:

“파일의 일부만 암호화하는 것”의 또 다른 이점은 원본 파일을 지우고 암호화된 파일을 생성할 필요가 없는 것이다. 새 파일을 생성할 필요 없이 존재하는 파일에 쓰기 권한만 있으면 된다. 또한 500gb MySQL 데이터베이스 같은 매우 큰 파일을 빠르게 암호화할 수 있다.

마지막 고려사항

각 과정에 대해 적절한 암호화를 선택하면 악성코드를 배포하기 위한 프레임워크를 디자인해야 한다. 모든 victim이 같은 키를 공유하는 걸 원하지 않으므로 페이로드마다 키를 자동적으로 생성하는 process를 포함해야 한다(한 명이 ransom을 지불하고 key를 배포하면 모두가 암호화할 수 있는 걸 방지해야한다). 각 victim에 대한 키를 저장하는 데이터베이스도 필요하다.

이 부분은 나쁜 목적으로 사용될 수 있으므로 코딩하지 않고 어떻게 수행할 수 있는지도 설명하지 않을 것이다. 이 글의 아이디어는 보안 팀들이 이전 랜섬웨어가 잘못되었고, 감염 발생/확산을 막을 수 있음을 보여줄 것이다.

단일 페이로드에 사용할 비대칭 키를 생성하기 위해 ssh-keygen을 사용할 것이다.

ssh-keygen -b 2048 -m pem -f pem

이 명령어는 pem 포맷으로 public(pem.pub)과 private key(pem)을 생성한다. pem.pub를 완성된 실행 파일과 합쳐서 테스트해보자.

Generating both keys

Public key

Private key

파트 1은 여기까지이다. 파트 2에서는 멀웨어를 코딩하고 얼마나 빠르게 파일을 암호화할 수 있는지 시연해 볼 것이다.