런타임 암호화 문자열
오늘은 런타임 암호화 문자열의 기초, 왜 문자열을 암호화해야 하는지, 그리고 직접 암호화를 만드는 방법에 대해 알아보겠습니다.
이 글에서 이해하고 배울 내용:
- 런타임 암호화 및 복호화란 무엇인가
- 왜 문자열을 암호화해야 하는가
- 누구나 민감한 데이터를 볼 수 있다는 것을 확인하기
- 자신만의 커스텀 암호화 만들기
런타임 암호화 및 복호화란
프로그램(소프트웨어, 애플리케이션) 실행 중에 암호화 및/또는 복호화되는 데이터를 말합니다. 데이터는 메모리 블록, 네트워크 트래픽, 문자열 등 모든 종류가 될 수 있습니다.
이 목적으로 사용되는 가장 일반적인 방법 중 하나는 (기본적인) 난독화입니다. 다른 (고급) 메커니즘에는 컴파일된 코드의 변형/가상화가 포함됩니다.
오늘은 XOR 난독화 를 사용하는 메커니즘에 초점을 맞추겠습니다.
왜 문자열을 암호화해야 하는가?
소프트웨어를 실행하는 순간, 모든 것이 메모리에서 보입니다. 이는 최종 사용자에게도 해당되며, 모든 것을 볼 수 있다는 것을 의미합니다.
공격자가 가장 먼저 하는 일 중 하나는 소프트웨어 내의 문자열을 검색하는 것입니다. 이를 통해 최소한의 노력으로 소프트웨어의 모든 것을 이해할 수 있습니다.
민감한 데이터(비밀번호나 라이선스 등)를 저장하고 있다면, 평문으로 저장하지 않는 것이 매우 중요합니다. 평문으로 저장하면 공격자의 작업이 쉬워집니다.
소프트웨어를 분석하는 여러 가지 방법이 있습니다. 가장 잘 알려진 일반적인 방법은 정적 분석과 런타임 분석입니다.
콘솔 앱을 사용한 간단한 예를 살펴보겠습니다:
Release 모드로 컴파일합시다(디버그 정보를 피하기 위해). 계속해서 정적 분석과 런타임 분석을 테스트해 봅시다.
정적 분석 테스트
정적 분석에서는 소프트웨어를 실행할 필요가 없습니다. 그러면 Ghidra 에서 샘플을 열어봅시다.
아래 스크린샷에서 샘플이 디버그 정보 없이 컴파일되었음을 확인할 수 있습니다:
문자열을 검색하면 모든 민감한 정보가 보이는 것을 확인할 수 있습니다:
문자열을 하이라이트하면 디컴파일러 뷰를 열어 관련 코드를 모두 확인할 수 있습니다:
꽤 슬프지 않나요? 😕 몇 달 동안 멋진 소프트웨어를 작업하고 판매할 준비가 되었다고 상상해 보세요.
나머지는 자명하다고 생각하지만, 요점은 이해하셨을 것입니다.
더 슬픈 것은 이것이 너무 간단해서 12살짜리도 할 수 있다는 것입니다. (실제로 하는 아이들도 있습니다)
런타임 분석 테스트
런타임 분석에서는 소프트웨어가 실행 중이어야 합니다. 즉, 프로세스를 열어 읽는 소프트웨어(보통 디버거)를 사용해야 합니다.
하지만 이 목적에는 디버거가 꼭 필요하지 않습니다. Process Hacker 와 같은 무료 도구를 다운로드하고 프로세스를 열기만 하면 됩니다:
꽤 간단했죠? 그리고 디버거를 연결하지도 않았다는 점을 기억하세요. 숙련되고 결의가 있는 사람은 디버거를 사용할 것입니다.
디버거를 연결하면 훨씬 더 많은 것을 볼 수 있지만, 그 논의는 다른 날로 미루겠습니다.
런타임 암호화 문자열 만들기
이를 달성하는 방법은 여러 가지가 있습니다:
처음 두 옵션은 여러분의 요구에 맞지 않을 수 있습니다. 각각에 대한 많은 장단점이 있지만, 현재로서는 논의하지 않겠습니다.
이해해야 할 한 가지는 인기는 위험을 의미한다는 것입니다. Google에서 무작위로 찾은 것을 사용하면, 누군가가 이미 그것을 알고 있습니다.
대부분의 사람들은 여러분의 도구에 대한 도구를 개발했습니다. 그것이 현실입니다. 도전을 위해, 또는 여러분의 작업을 훔치기 위해 하지만, 어쨌든 합니다.
이를 염두에 두고, 커스텀으로 가야 합니다. 기본 수준에서 고급 수준까지 자체 문자열 암호화를 만들 수 있습니다.
계획
- 사용하기 쉬운 솔루션 만들기
- 문자열을 항상 암호화된 상태로 유지
- 필요할 때만 복호화
- 문자열을 임의의 위치에 배치 (선택사항 - 미다룸)
- 사용 후 문자열 파괴 (선택사항 - 미다룸)
솔루션
문자열을 하나씩 배열로 정의하는 것부터 시작합니다:
배열에는 길이 제한 256으로 무제한의 문자열을 포함할 수 있습니다.
특히 문자열이 긴 경우 이것이 힘든 작업이라는 것을 알고 있습니다. 이것은 데모 목적으로만 사용되며, 나중에 더 실용적인 솔루션을 만들 것입니다.
아이디어는 문자열의 각 문자를 암호화하는 것입니다. 이를 위해 간단한 XOR 암호화를 사용하겠습니다.
아래에서 이것이 어떻게 작동하는지의 예를 볼 수 있습니다:
위 내용에는 복잡한 것이 없습니다. 간단하고 직관적이지만 꽤 강력합니다. 콘솔 애플리케이션 내에서 사용할 수 있습니다.
컴파일하고 실행하면, 결과는 사람의 눈으로 읽을 수 없는 바이트입니다:
이것으로 런타임 암호화 문자열을 만드는 작은 소프트웨어가 완성되었습니다. 😏
결과
솔루션을 실전에 적용할 시간입니다. 이를 위해 다른 샘플을 만들고 코드를 추가합시다:
2가지 중요한 점에 주목하세요:
- 차이를 보여주기 위해 의도적으로 일부 문자열을 평문으로 남겼습니다
- 복호화 함수는 길이가 필요합니다 (나중에 논의하겠습니다)
위 코드를 Release 모드로 컴파일하고 실행합니다. 새 샘플은 정상적으로 작동합니다:
새 샘플을 IDA(또는 Ghidra)에서 열면 암호화된 문자열은 보이지 않습니다:
이 샘플에 의도적으로 평문 문자열을 남겨두었다고 말씀드렸습니다. 그 이유는 이를 따라가 코드를 볼 수 있기 때문입니다:
위 이미지의 텍스트에 도달하기 위해 아래로 스크롤해야 했습니다. 컴파일된 코드가 얼마나 다른지 알 수 있습니다.
정적 분석 문제를 해결했습니다. 이제 런타임으로 넘어갑시다.
Process Hacker에서 열어봅시다:
성공! 런타임 분석 문제도 해결했습니다 😎
암호화 문자열에 대해 더 알아보기
위의 예제는 그다지 실용적이지 않습니다. 각 문자열을 수동으로 정의하는 것은 고된 작업이며, 매번 문자열 길이를 지정하는 것도 마찬가지입니다.
이상적으로는 다음이 필요합니다:
- 텍스트 파일에서 문자열 읽기
- 결과 문자열을 텍스트 파일에 쓰기
- 매번 길이를 지정하지 않기 위해 문자열에 이스케이프 시퀀스 를 추가하기
- 더 복잡한 XOR 또는 다른 방법 추가하기 (선택사항)
- 문자열을 임의의 위치에 배치하기 (선택사항)
실험할 수 있는 좋은 솔루션을 준비했습니다. 이 글에 작성된 모든 것을 테스트하고 런타임 암호화 문자열을 만들기 위한 자체 도구를 바로 사용할 수 있습니다.
4개의 프로젝트가 포함되어 있습니다:
- RuntimeStringEcryptor는 텍스트 파일에서 문자열을 읽고, 암호화한 후 다른 텍스트 파일에 씁니다.
- Sample은 IDA로 시연하는 데 사용되는 간단한 콘솔입니다.
- SampleEncryptedStrings는 IDA로 시연하기 위한 암호화된 문자열이 포함된 간단한 콘솔입니다.
- SimpleRuntimeStringEncryption은 이 방법을 테스트할 수 있는 초기 플레이그라운드입니다.
참고사항:
- 이스케이프 시퀀스를 추가하지 않으면, 복호화는 언제 “멈춰야” 하는지 알 수 없습니다. 결과는 정의된 배열 크기에 도달할 때까지 읽을 수 없는/null 데이터가 됩니다.
- 예제에서 사용한 XOR 키를 반드시 변경하세요.
- 같은 단어를 여러 번 사용하지 마세요. 같은 바이트가 생성되며 탐지될 위험이 있습니다.
다운로드
바로 사용할 수 있는 솔루션을 다운로드하려면, 이 블로그를 후원해 주세요 😘
댓글