2020-05-27 05:15 (수)
PHP 리모트 익스플로잇 가능한 버그 발견돼!
상태바
PHP 리모트 익스플로잇 가능한 버그 발견돼!
  • 길민권
  • 승인 2012.02.02 17:15
이 기사를 공유합니다

PHP DoS 공격 막기 위해 추가한 패치코드 때문에 발생
PHP에서 무려 리모트 익스플로잇이 가능한 버그가 발견되었다. 2011년 우리나라의 SECUINSIDE 컨퍼런스에서 발표를 하기도 한 Stefan Esser가 발견했다. 버그 자체는 무척 단순하다. 오늘 날짜로 패치가 올라왔는데, 코드를 잠깐 보면 아래와 같다.  
 
- php_register_variable_ex() in php_variables.php (아래 URL 패치 파일에서 발췌한 코드다.)
(svn.php.net/viewvc/php/php-src/branches/PHP_5_3)

위에서 9 ~ 12줄의 코드가 해당 버그를 막기 위해서 추가한 패치다. 취약점 자체는 무척 쉬운데요, 사용자가 보내온 변수의 수가 max_input_vars 이상일 경우엔 프로그램을 종료하거나 에러 처리를 하는 루틴이 있어야 하는데, 그 부분이 없어서 문제가 됐던 것.
 
에러 처리 루틴이 없기 때문에, max_input_vars 이상일 경우에도 프로그램은 계속 진행되고, 결국 진행 과정에서 메모리 corruption이 이루어지게 된다. (memory corruption이 어떤 과정으로 이루어지는지는 여러분께서 분석해보시기 바람) 즉, 9 ~ 12줄의 코드는 이를 방지하기 위해 추가한 에러 처리 코드라고 볼 수 있다.
 
사실 이 취약점은 얼마 전에 발생한 “hash collision으로 인한 PHP DoS 공격”을 막기 위해서 추가한 패치 코드 때문에 발생했다. 해당 기법은 Alexander Klink와 Julian Waelde에 의해 “Effective Denial of Service attacks against web application platforms”라는 주제로 2012 Infiltrate 컨퍼런스에서도 발표가 됐었다.
 
max_input_vars를 과도하게 많이 보낼 경우, PHP 내부에서 해쉬 충돌이 일어나게 되고 이러한 현상 때문에 CPU가 99%를 차지하는 등의 DoS가 가능했었다. 그래서 그에 대한 보완 방편으로, php.ini 파일에 max_input_vars 값을 설정할 수 있도록 해두었고, 해당 값 이상의 데이터가 넘어올 경우엔 PHP를 종료하도록 기능을 추가해두었다.
 
그런데 패치를 구현하는 과정에서 에러 처리를 적절히 구현하지 못했기 때문에 이번 버그가 발생한 것이다. php.ini에 max_input_vars 변수 값이 존재하는지 확인해보시기 바란다. 만약 존재한다면 이번에 발견된 버그에 취약하다고 볼 수 있으므로 패치를 적용하시기 바란다.  
 
재미있는 것은, Stefan Esser가 발견하고 리포트를 하긴 했지만, masugata라는 이메일 아이디를 쓰는 사람도 이 버그를 PHP 메일링 리스트에 리포트를 했었다. 그러나 masugata는 이 버그에 대해서 Security의 관점으로 보지 못했거나 혹은 에러 원인에 대해서 자세히 살펴보지 못한 것 같다. 제대로 파악만 했다면, 엄청난 가치를 가진 버그를 발견한 사람이 됐었을지도 모르는데, 아쉬운 생각이 든다.  
 
익스플로잇이 얼마나 reliable할지는 모르겠지만, 아무튼 이 버그는 한동안 보안계에 화제가 될 것으로 예상된다.
[글. Beistlab 이승진]