“Heartbleed(심장 출혈)“라고 부르는 버그가 발견되었습니다. 이 버그를 이용하면 최근 2년 동안의 OpenSSL 버전이 설치된 시스템 메모리의 64KB 데이터를 공격자가 들여다볼 수 있습니다. 정확한 취약성 이름은 CVE-2014-0160 OpenSSL Heartbleed입니다.

시스템 메모리에는 유저 이름, 암호, 신용카드 정보 같은 데이터가 들어 있고, 이것을 키를 이용해 암호화합니다. 그런데 이 버그를 통해 공격자가 그 키를 얻을 수 있고, 암호화되지 않은 상태로도 데이터를 읽을 수 있습니다. 게다가 그 키를 가지고 다른 사람 행세를 하며 서버에 침입할 수도 있습니다.

구체적인 공격 가능성은:

공격자가 https 서버의 SSL 인증서 개인키를 얻을 수 있습니다. FreeBSD 9.1에서 개인키가 보인 사례가 보고되었습니다. 이건 최악의 경우이긴 한데, 현재 사용 중인 SSL 인증서를 revoke하고 재발행하는 편이 좋습니다. 운영 중인 서버가 취약한 버전의 OpenSSL로 서비스하고 있었다면 최근 2년 동안 SSL 인증서의 개인키가 털렸을 가능성이 있습니다.

또한 https 서버 메모리에 있는 사용자 정보가 노출될 수 있습니다. 아파치에서 SSL을 처리하고 있다면 웹 애플리케이션 정보가 노출될 수 있습니다. 실제로 yahoo.com에서 다른 사람의 아이디, 비밀번호가 노출되는 사례도 있었습니다. heartbleed 취약성을 이용해 유저 세션을 하이재킹하는 방법도 공개되었습니다.

버그 분석

TLS 스펙 자체의 문제는 아니고, TLS heartbeat 기능을 OpenSSL 라이브러리가 잘못 구현한 버그입니다. heartbeat 구현 버그라서 Heartbleed라는 이름이 붙었습니다. 실제 수정한 소스코드 분석은 여기서 볼 수 있습니다.

TLS Heartbeat 스펙은 payload와 payload length를 받아서, length를 검사한 뒤 payload를 그대로 복사해 클라이언트에게 응답해야 합니다. 그런데 OpenSSL이 payload length 검사 없이 memcpy를 실행해 버려서, 메모리 안의 다른 내용까지 복사해 응답해 주는 버그였습니다. 수정 커밋은 https://github.com/openssl/openssl/commit/96db9023b881d7cd9f379b0c154650d6c108e9a3입니다.

2011년 12월 이후 버전인 OpenSSL 1.0.1 ~ 1.0.1f에 문제가 있고, 오늘(4/7) 수정되었습니다. 게다가 이 버그를 악용해도 로그에 흔적이 남지 않습니다.

내 사이트가 영향이 있는지 체크하는 방법

해당 웹 서버가 영향을 받는지를 http://filippo.io/Heartbleed/#github.com에서 테스트해 볼 수 있습니다. 이 사이트의 소스코드는 https://github.com/FiloSottile/Heartbleed에 있고, go로 작성되어 있습니다.

How to test if your OpenSSL heartbleeds 블로그를 참고하면 서버에서 직접 테스트할 수도 있습니다.

Chromebleed 라는 크롬 확장도 나왔습니다. 지금 보고 있는 사이트가 heartbleed 위험이 있는지 보여 줍니다. 사실 이런 확장들이 위험이 있는 사이트들을 수집하고 있는 것은 아닌가 하는 의심도 살짝 듭니다.

파이썬으로 작성된 테스트 스크립트도 있습니다. heartbleed-masstest입니다.

OpenSSL 1.0.1 ~ 1.0.1f를 사용하지 않으면 안전합니다.

sangwook@main:~$ openssl version -a
OpenSSL 1.0.1 14 Mar 2012

AWS EC2 에서 대응하는 방법

Amazon Linux에서는 아래 명령을 실행한 뒤 서비스를 restart 하면 됩니다.

sudo yum clean all 
sudo yum update OpenSSL

ELB에서 SSL termination을 사용하는 경우에는 취약점이 여전히 남아 있습니다. 관련 이슈는 아래 링크들에서 확인할 수 있습니다.

Ubuntu 에서 대응하는 방법

http://www.ubuntu.com/usn/usn-2165-1/

sudo apt-get update
sudo apt-get upgrade

또는

sudo apt-get update
sudo apt-get install libssl1.0.0

Node.js 에서 대응

Node.js v0.10.2 이상, 그리고 v0.8이라면 취약성이 없습니다. OPENSSL_NO_HEARTBEATS가 설정된 상태로 heartbeat 기능이 disable 되어 있기 때문입니다. 관련 정보는 https://twitter.com/nodejs/status/453298698714230784https://github.com/joyent/node/commit/28c6e42e에서 볼 수 있는데, “의도하지 않은 보안 기능"이라는 댓글이 인상 깊습니다.

테크 기업들의 대응들

텀블러의 대응이 올라왔고, 텀블러 한글 블로그에도 “긴급 보안 업데이트"라는 제목의 글이 올라왔습니다. GitHub의 대응heroku의 대응도 함께 참고할 만합니다.

링크