Synology이 C3RB3R로 암호화된 후 자구책: 키 없이 Btrfs 이전 데이터 블록 복구
결론부터 말하자
만약 당신의 Synology NAS가 C3RB3R(파일 확장자 .L0CK3D, 남겨진 read-me3.txt 몸값 요구서)에 의해 암호화되었다면, 먼저 포기하지 말고 몸값도 지불하지 마라. 당신의 공유가 Btrfs 파일 시스템이고, 아직 defrag / balance / 강제 복구 같은 파괴적 작업을 하지 않았다면,상당 부분의 파일은 키 없이도 되찾을 수 있다. 이유는 직관에 반한다: C3RB3R은 파일을 「제자리에서 덮어쓰기」하는데, Btrfs의 CoW(쓰기 시 복사)는 덮어쓰기된 이전 내용을 디스크에 남겨두므로, 원본 파일의 평문이 회수되지 않은 이전 데이터 블록에 숨어 있게 된다.
오픈소스 커뮤니티는 이미 이 복구 과정을 도구로 만들어 놓았다:crt106/c3rb3r-btrfs-recovery(MIT 라이선스, 읽기 전용, 당신이 처리 권한이 있는 데이터 복구에만 사용). 이 글에서는 그 원리, 경로 선택, 단계별 조작 및 실제 사례 데이터를 명확히 설명한다. 아직 감염되지 않았다면, 먼저전편 《Synology NAS 랜섬웨어 공격: 먼저 DSM 업그레이드, 그다음 불변 snapshot 활성화》를 읽어라——예방이 사후 복구보다 훨씬 중요하다.
1. 두 가지 자구 경로, 먼저 올바르게 선택하라
파일을 되찾을 수 있는지는 첫 단계가 도구를 찾는 것이 아니라 판단하는 것이다암호화 프로세스가 아직 살아 있는지. 이 두 경로의 수익 차이는 매우 크다:
경로 A: 암호화 프로세스가 아직 살아 있음 (수익 최대)
사건 발생 얼마 안 되었고 NAS 재시작하지 않았다면, 암호화 프로세스 (예:/usr/bin/libgld -n 308, 프로그램 파일은 이미 디스크에서 삭제되었을 수 있음)가 메모리에서 실행 중일 가능성이 높다. 이때 가장 먼저 해야 할 일은:
- 用
kill -STOP <pid>그것을 동결시키는 것이다, kill하지 말고, 더더욱 재시작하지 마라. - 그런 다음 다른 두 저장소의 방법에 따라 프로세스 메모리에서세션 마스터 키를 추출한다 — 이렇게 하면모든 파일을 해독할 수 있다, 수익은 아래 Btrfs 경로보다 훨씬 큽니다:
- soimy/c3rb3r-rescue: 증거 보전, RAM에서 키 복구, 복호화 복사
- Benjamin-zlt/c3rb3r-baremetal-rescue: 물리 머신 DSM에서 암호화기 동결, 프로세스 메모리 내보내기, 세션 키 추출, 전체 복호화 (이미 두 번째 독립 피해자의 완전한 복호화 사례가 있음)
경로 B: 암호화 프로세스가 이미 종료됨 (본 저장소가 보완한 공백)
만약 NAS 가 이미 재시작되었거나, 사건 발생 후 이미 십여 시간이 지났다면 메모리에서 키를 거의 찾을 수 없습니다 (해당 프로젝트 작성자가 한 번 철저한 메모리 스캔을 수행한 결과 zero였습니다). 이때는 본 저장소의 Btrfs 이전 데이터 블록 복구경로를 따릅니다: 키에 의존하지 않고 파일 시스템에 남아 있는 이전 평문에만 의존합니다.
본문은 경로 B에 중점을 둡니다. 두 경로는 조합할 수 있습니다: 먼저 키 획득을 시도하고, 얻지 못하면 Btrfs로 갑니다.
二, 원리: 왜 키 없이도 평문을 되찾을 수 있는가
한 문장으로:C3RB3R은 파일의 몇 개 구간만 덮어썼고, 덮어쓰인 이전 내용은 Btrfs에서 블록 전체로 남아 있습니다.
구체적으로 어떻게 암호화하는가:
- 작은 파일: 전체 암호화;
- 1–5MB 파일: 앞 1MiB만 암호화;
- 큰 파일: 「머리, 중간, 꼬리」 세 구간을 암호화하며, 합계 약 12%.
Btrfs는 copy-on-write 파일 시스템이다. 파일이 제자리에서 덮어써질 때, 새 내용은새로운 위치에 기록되고, 반면원래의 데이터 블록(extent)은 파일에서 「암호화되지 않은 부분」이 여전히 참조하는 한 통째로 디스크에 보존된다. 이 오래된 extent들은 책받침처럼 파일 양 끝을 끼고 있으며, 저자는 이런 현상을 「bookend extent」라고 부른다。
복구 도구가 하는 일은: Btrfs의 extent 트리에 따라, 덮어써진每一个 바이트를원래의 옛 extent로 매핑하고, 블록 디바이스에서 읽기 전용으로 직접 읽어 원래 바이트를 재구성하는 것이다. 더 흥미로운 점은, 「데이터 체크섬」이 활성화된 공유에서 Btrfs 자체의 CRC32C 체크섬으로 블록별로 증명할 수 있어복구된 내용이 실제로 올바르다는 것을 확인할 수 있다.
구체적인 예를 들면 더 이해하기 쉽다: 100MB의 가정용 비디오에서 C3RB3R은 헤더, 중간, 꼬리 세 구간 약 12MB만 암호화했고, 나머지 약 88MB의 평문은 이전 extent에 그대로 남아 있다; 반면 50KB의 문서는 1MiB보다 작아서 전체가 암호화되었기 때문에 디스크에서 이전 평문을 찾을 수 없다. 그래서파일이 클수록, 체크섬이 켜져 있을수록, 쓰기가 이를수록(가장 최근 snapshot보다 이르게), 복구할 수 있는 비율이 높아진다; 반대로 대량의 작은 파일과 데이터베이스는 상황이 가장 나쁘다.
쉽게 오해하는 점 하나:「데이터 체크섬」을 체크하지 않은 NoCOW 공유도 복구 불가능을 의미하지는 않는다. 데이터 쓰기 시간이 해당 하위 볼륨의마지막 snapshot보다 이르기만 하면(설령 snapshot이 나중에 삭제되었더라도), 덮어쓸 때 여전히 copy-on-write를 거치므로 snapshot 이전의 오래된 데이터도 그대로 복구할 수 있다.
三, 이 도구는 무엇인가
crt106/c3rb3r-btrfs-recovery 본질적으로 AI Agent 스킬(SKILL.md)이며, Claude Code, Codex, Cursor처럼 스킬 메커니즘을 지원하는 agent용이다. 실제 복구 한 번의 전체 흐름, 읽기 전용 도구, 검증 방법을 범용 가이드로 정리했다. 핵심 설계 원칙은 세 가지다:
- 읽기 전용: NAS 측에서는 ioctl 조회, 파일 읽기, 블록 디바이스 읽기만 수행하고, 결과는 NAS 외부 디스크에 기록하며, 데이터 볼륨에는 절대 파일을 남기지 않고, 어떤 것도 절대 덮어쓰지 않는다;
- 검증 가능: 복구된 각 블록을 Btrfs 체크섬과 대조하여 「정밀 복구」와 「추측 디코딩」을 구분할 수 있다;
- 롤백 가능: 로컬에서 후보 바이트를 교체할 때
*.c3rbak백업을 생성하여 바이트 단위 롤백이 가능하다.
4. 상세 단계 (Btrfs 복구 경로)
0단계: 먼저 레드라인을 지켜라 (이 단계는 복구 자체보다 중요하다)
아무것도 건드리기 전에, 다음 몇 가지는절대 하지 마라:
- 어떤
.L0CK3D파일도 삭제하거나 덮어쓰지 말고, 휴지통도 비우지 마라.기존 데이터 블록은 바로 이 암호문 파일들이 「붙잡고」 있어서 파일 시스템에 의해 회수되지 않은 것이다 — 네가 삭제하는 순간 기존 평문이 즉시 덮어씌워져 정말로 사라질 수 있다; - defrag, balance,
btrfs check --repair를 수행하지 마라, 이들은 데이터를 재작성하여 기존 블록을 직접 파괴한다; - 몸값을 지불하지 마라또한 출처가 불분명한 "복호화기"를 실행하지 마십시오(대부분 2차 사기입니다);
- 가능한 한 빨리 NAS의 전원을 끄거나 네트워크를 차단하여 현장을 보존하고 쓰기를 줄이십시오.
1단계: 설치
skills CLI 사용:
# 安装到当前项目
npx skills add crt106/c3rb3r-btrfs-recovery
# 全局安装,或指定 agent
npx skills add crt106/c3rb3r-btrfs-recovery -g
npx skills add crt106/c3rb3r-btrfs-recovery -a claude-code
수동 설치: 다음을 skills/c3rb3r-btrfs-recovery/ 전체 디렉터리를 agent의 스킬 디렉터리(예: Claude Code의 ~/.claude/skills/)。
2단계: 환경 자체 점검 preflight
모든 장치에서먼저 이 단계를 실행하십시오, 각 항목별로 OK / WARN / FAIL 및 처리 권장 사항을 제시합니다:
cd skills/c3rb3r-btrfs-recovery/scripts
python mkjob.py -- preflight /volume1/某个文件.jpg.L0CK3D > job.sh
{ printf '%sn' "$SUDO_PW"; cat job.sh; } | ssh admin@NAS "sudo -S -p '' sh -s"
여기서 mkjob.py 도구 및 경로 목록을 패키징하여 SSH 표준 입력을 통해 NAS에 전달해 실행하며,데이터 볼륨에 파일을 남기지 않습니다。
3~6단계: 세대 확인 → 단일 파일 검증 → 전체 조사 → 내보내기 검증
이 단계는 상황을 agent에 직접 맡기면 SKILL.md에 따라 자동 실행되며, 수동으로 스크립트를 실행할 수도 있습니다. 흐름은:
- 공격 대수 G_ATTACK 확인: 세대별 암호화 포맷에 약간 차이가 있으므로 먼저 정렬한다;
- 알려진 원본 파일로 단일 파일 검증: 로컬에 아직 원본이 남아 있는 동일 이름 파일을 가져다 대조하여 복구 로직이 올바른지 확인한 후 배치 작업;
- 전체 조사 survey: 전체 볼륨을 스캔하여 각 파일에서 어떤 바이트가 변경되었는지, 이전 extent에서 복구 가능한지 표시;
- 스트리밍 내보내기 + 다중 검증: 복구된 바이트를 다시 조립하고, 로컬 다중 프로세스 디코딩 검증, 알려진 원본 대조, 최적 후보 선별, 최종 보고서 출력.
실작업 시 주의할 점:preflight 어떤 항목이든 FAIL이 발생하면(예: ext4 볼륨으로 확인되거나 NAS에서 Python 3를 찾을 수 없는 경우) 일단 중단하고 제시된 권장 사항에 따라 처리;G_ATTACK 대수는 이후 모든 매칭의 기준이므로 잘못 판정하면 전체 배치가 맞지 않게 됨; 단일 파일 검증은 반드시로컬 원본이 정확함을 확인한파일로 대조하고, 검증 통과 후 배치를 진행하며 손상 의심 사본으로 검증하지 말 것.
스크립트 역할 일람
| 스크립트 | 실행 위치 | 역할 |
|---|---|---|
c3r_btrfs.py |
NAS(root, Python 3.6+ 표준 라이브러리, 읽기 전용) | preflight、env、gens、survey、extract、patch、csum、plan |
mkjob.py |
로컬 | 도구와 경로 목록을 패키징하여 SSH 표준 입력으로 NAS에 전달해 실행하며, 데이터 볼륨에 파일을 남기지 않음 |
c3r_local.py |
로컬 | tar 스트림 언패킹, 멀티프로세스 디코딩 검증, 알려진 원본 대조, 최적 후보 선별, 패치로 후보 교체 및 롤백 가능, 통계 |
7단계: 보고서 이해하기
복구 보고서는 결과를 세 가지로 분류하므로 혼동하지 말 것:
- 정확 복구 및 체크섬 검증 완료: 가장 신뢰할 수 있으며, Btrfs CRC32C가 블록별로 일치함;
- 추측 후 디코딩 통과: 논리적으로 재구성은 성공했으나 체크섬 증거가 부족하므로 보류 및 확인 권장;
- 실패: 이 부분은 실제로 유실된 것임.
5. 호환성: 당신의 환경에서 사용할 수 있는가
프로젝트는 이미 Synology DSM 7.2.1(SHR,cachedev, Python 3.8)에서 실기 검증되었습니다. 다른 환경에서는 먼저 preflight를 실행하세요. 항목별로 권장 사항을 제시합니다. 알려진 적응/검증 대기 상황:
- DSM 6, OMV, Unraid, Python 3가 없는 장치, 디스크를 분리하여 Linux 컴퓨터에 연결해 오프라인 처리 — 문서에 각각의 맞춤 안내와 오류 처리가 있음;
- ext4에는 적용 불가(대부분의 QNAP 볼륨, Synology 구형 볼륨),ZFS는 다른 도구 체인이 필요。
6. 실제 사례: 무엇을 복구했는가
작성자가 공개한 첫 번째 사례, 복구 결과는 다음과 같음:
| 범위 | 결과 |
|---|---|
| homes, photo 등 CoW 공유 | 35,445개 파일 / 229.9GB, SHA 검증 및 완전 디코딩 검증을 거쳐 |
| 정밀 복구 부분의 체크섬 샘플링 검사 | 약 20만 개의 4K 블록, Btrfs CRC32C와 전부 일치 |
| NoCOW 공유 중, snapshot 전에 기록된 데이터 | 추가로 약 6,100개 파일 / 약 346GB 복구(별도로 약 3,800개 파일은 로컬에 원본이 있음) |
| 복구할 수 없는 부분 | 1MiB 이하로 전체 파일 암호화된 소형 파일, 데이터베이스 파일, NoCOW 공유 중 snapshot 후에 기록된 파일 |
한 줄 요약:대형 파일, 체크섬이 활성화된 공유, snapshot 전의 오래된 데이터는 복구율이 높음; 전체 파일 암호화된 소형 파일, 데이터베이스, snapshot 후에 기록된 내용은 사실상 불가능.
七, 복구할 수 없는 것, 그리고 몇 가지 주의사항
- 1MiB 이하의 소형 파일전체가 암호화되어 디스크에 남은 이전 평문을 건질 수 없습니다;
- 데이터베이스 파일(SQLite/PostgreSQL처럼 파일 전체를 빈번히 재작성하는 경우)은 보통 블록 전체를 다시 쓰기 때문에 이전 블록은 이미 덮어씌워집니다;
- NoCOW 공유에서 마지막 snapshot 이후에야 기록된 데이터는 덮어쓸 때 CoW를 거치지 않아 이전 블록이 존재하지 않습니다;
- 도구 자체는 읽기 전용이지만,모든 복구 작업에는 위험이 따릅니다: 먼저 증거를 보존하고, 알려진 원본으로 소규모 샘플 검증을 한 뒤에 일괄 작업하십시오;
- 이것은 「모든 파일을 원클릭 복원」하는 방안이 아니라, 파일 시스템에 우연히 남은 이전 평문을 최대한 건져내는 것이며,얼마나 건질 수 있는지는 쓰기량과 시간에 달려 있습니다— 볼륨이 가득 찰수록, 사건 발생 후 오래될수록 덮어씌워진 이전 블록이 많아집니다.
세 개의 저장소를 조합하여 사용할 수 있습니다:soimy/c3rb3r-rescue 和 Benjamin-zlt/c3rb3r-baremetal-rescue 는 「프로세스가 아직 살아 있을 때 메모리에서 키를 가져오는」 역할을, 본 저장소는 「키가 사라진 뒤 Btrfs 이전 데이터 블록에 의존하는」 역할을 담당합니다.
8. 몇 가지 흔한 오해
- "랜섬 노트를 지우고 이름만 바꾸면 쓸 수 있다": 파일 내용은 이미 암호화되어改写되었으므로 이름을 바꿔도 데이터는 달라지지 않는다; 삭제하면
.L0CK3D오히려旧 데이터 블록이 참조를 잃고 파일 시스템에 의해 회수되는 속도가 빨라져, 원래 건질 수 있었던 것도 건지지 못할 수 있다. - "스냅샷을 켜 뒀으니 분명 복원할 수 있다": snapshot이 구하는 것은 snapshot 시점 이후의 추가 및 변경이며, 이번 사안은 암호화 프로세스가 "현재 버전" 파일을 직접改写한 것이므로 snapshot이 이미改写된 현재 파일을 커버하지 못한다; 본 방안은 바로 "snapshot 이전의旧 블록"을 이용하는 것이며, snapshot이 없을 때도 CoW로 인해旧 블록이 남아 있을 수 있으니 snapshot을 유일한 희망으로 여기지 말라.
- "돈을 내고 전문가에게 복호화를 맡기는 게 더 편하다": 출처가 불분명한 "복호화 서비스"는 대부분 2차 사기이며, 데이터도 되찾지 못하고 프라이버시도 유출된다; 본문의 방안은 읽기 전용, 무료, 자체 검증 가능하므로 우선 이것을 이용하라.
- "ext4의 Synology 구형 볼륨, QNAP에서도 쓸 수 있다": 적용되지 않는다. ext4에는 copy-on-write가 없어旧 블록이 보존되지 않으므로 전혀 다른 접근이 필요하다.
면책 조항
본 프로젝트는 "있는 그대로" 제공되며,자신이 처분할 권리가 있는 데이터 복구에만 사용해야 한다. 도구 자체는 읽기 전용이지만 모든 복구 작업에는 위험이 따른다: 먼저 증거를 보전하고, 알려진 원본으로 소규모 샘플 검증을 먼저 한 뒤 일괄 작업하라. 작성자는 데이터 손실에 대해 책임지지 않는다. 본문은 해당 오픈소스 방안에 대한 정리와 설명일 뿐이며, 어떠한 전문 기술 서비스 약속도 구성하지 않는다; 실제로 착수하기 전에 반드시 저장소의 SKILL.md와 references 디렉터리를 먼저 읽어야 한다.

