특정 조건 아래서 PHP가 해시 값을 0으로 해석
[보안뉴스 문가용] PHP가 특정 상황에서 해시된 스트링을 다룰 때에 발생하는 취약점 때문에 해커들이 인증 과정을 공격해 암호도 탈취하고 해시 비교와 관련된 다른 기능까지 점령할 수 있다고 화이트햇 시큐리티(WhiteHat Security)에서 발표했다.
화이트햇의 부회장인 로버트 핸슨(Robert Hansen)은 이번 사안에 대해 설명하며 PHP 내에서 해시를 비교하기 위해 두 개의 특정 오퍼레이터를 사용하는 웹사이트라면 죄다 취약점에 노출되었다고 보면 된다고 밝혔다.
이번 취약점으로 가장 큰 타격을 받는 건 권한 인증이지만 ‘암호를 잊었을 때’ 기능, 넌스(nonce), 바이너리 확인, 쿠키, 암호 등까지도 악영향의 범위 안에 들어간다. “어디까지 공격받을 수 있는가 하는 문제는 웹 사이트마다 천지차이라 일반화시킬 수가 없습니다.”
해당 취약점은 PHP가 해시 스트링을 다루는 방법에서부터 발생하는데, 특히 “==”나 “!=”라는 비교 오퍼레이터가 주요 원인이다. 이 두 가지 오퍼레이터가 각각 사용될 경우, PHP는 0e로 시작되는 해시 값을 전부 0으로 해석한다.
이게 무슨 말이냐 하면, 두 개의 다른 암호가 해시되고, 해시 값이 둘 다 0e로 시작될 때 PHP는 이 둘을 다 0으로 확인한다는 것이다. 즉 둘의 해시 값이 완전히 다르다고 해도 PHP 자체는 둘을 같은 0으로 본다. 해시 값이 0e로 시작하고 ==나 !=라는 오퍼레이터가 사용되었을 때라는 조건 하에서 말이다. “그러면 스트링 값이 정수로 변하게 됩니다.”
이에 대한 결과는 상당히 심각해질 수 있다. PHP가 해시 값을 0으로 받아들이게끔 조작함으로써 사용자 계정을 탈취하는 게 가능해지기 때문이다. 사실 핸슨에 따르면 이 문제는 새롭게 발견된 게 아니다. 다만 0e로 시작되는 해시 값이 0으로 변환되어 해석되는 예가 드러나지 않았을 뿐이다. 핸슨은 자신의 블로그를 통해 이런 조건에 성립하는 ‘마법의 숫자’들을 공개하기도 했다.
이런 숫자들 및 조합을 찾아내기 위해 핸슨은 10억개가 넘는 해시 정수들을 반복해서 대입했다고 한다. 비효율적이긴 했지만 소득이 분명히 있었고, 그것이 바로 블로그에 공개된 번호들이다. 물론 이 숫자들조차 최대 32개 글자들로 이루어진 해시 알고리즘에만 해당한다.
PHP 기반으로 구축되어 있는 웹 사이트의 관리자들은 ==나 !=를 사용한 해시 비교 코드를 분석하면서 해당 오퍼레이터를 각각 ===나 !==로 교체해봄으로써 문제 확인이 가능하다.
@DARKReading
[국제부 문가용 기자(globoan@boannews.com)]
<저작권자: 보안뉴스(http://www.boannews.com/) 무단전재-재배포금지>