패스를 거슬러가서 관리자가 유저에게 보일 생각이 없는 파일이나 디렉터리를 열람하거나 실행시키는 공격
[../]문자열 등을 리퀘스트 패스안에 넣는 방법이 잘 사용된다.
출처: http://www.elancer.co.kr/eTimes/page/eTimes_view.html?str=c2VsdW5vPTEzODg=
************************************************************************************************
| 증상은 달라도 원인은 하나 디렉토리 이동 취약점 여성구 (안철수연구소 모의해킹 컨설턴트) 2006/05/16 |
최근의 보안 화두는 당연 웹 애플리케이션이라고 할수 있다. 보안 관련 최신 뉴스를 봐도 대부분이 취약한 웹 애플리케이션으로 인해 악성 코드가 삽입된 사이트가 발견되었다는 것과 웹을 통한 해킹 사고가 빈번해지고 있다는 것들이다. 방화벽을 비롯하여 다양한 보안 솔루션이 대부분의 공공기관이나 기업에 적용된 상황에서도 왜 이런 보안 사고들이 꾸준히 등장하는 것일까. 그것은 기본적으로 네트워크나 서버의 문제가 아니라 취약하게 구현된 웹 애플리케이션 때문이다.
이번 호에 살펴볼 PHP-Nuke와 phpMyAdmin의 사례도 마찬가지다. PHP-Nuke는 웹 포탈과 온라인 커뮤니티 시스템으로, 웹 기반의 관리, 설문조사, 접근 통계, 사용자 맞춤식 박스, 등록된 사용자를 위한 테마 매니저, 사용자 친화적인 관리 GUI, 글 게시, 코멘트 기능, 검색 엔진 등 매우 다양한 기능을 제공한다. 물론 다국어도 지원해 국내에서도 많이 사용하고 있으며 <화면 1>처럼 PHP-Nuke 웹 사이트(www.phpnuke.org)와 유사한 사이트를 종종 볼 수 있는 것도 이 때문이다.
PHP-Nuke의 디렉토리 이동 취약점 최근 PHP-Nuke과 관련해 발표된 취약점은 상대경로(../)를 이용해 지정된 디렉토리 이상에 존재하는 파일에 접근하는 공격기법인 이른바‘디렉토리 이동(Directory Traversal)’취약점이다. 이것은 sp3x가 지난 10월 19일에 발표한 것으로 PHPNuke 7.8~7.9 + patch 3.1까지 영향을 받는다. 이 취약점은 PHP에서 지원하고 있는 옵션인 magic_quotes_gpc의 활성화 여부에 따라 공격법이 달라지는데 PHP 환경 설정(php.ini)에서 magic_quotes_gpc가 비활성화 되어 있을 경우 문제가 되는 부분은 modules.php라는 다음 부분이다. if (!isset($file) OR $file != $_REQUEST[‘file’]) $file=“index”; if (stripos_clone($file,“..”) OR stripos_clone($mop,“..”)) die(“You are so cool...”); 여기서 stripos_clone() 함수는 변수 $file과 $mop에 디렉토리 이동 공격이 시도되는 것을 탐지하고 방어하기 위한 것이다. PHP5에서는 함수 stripos()를 지원하지만 이를 지원하지 않는 PHP4에서는 함수 strops()를 이용해 다음과 같이 구현하고 있다(함수 strop()는 문자열이 처음 나타나는 위치를 찾는다). if(!function_exists(‘stripos’)) { function stripos_clone($haystack, $needle, $offset=0) { return strpos(strtoupper($haystack), strtoupper($needle), $offset); } } else { // But when this is PHP5, we use the original function function stripos_clone($haystack, $needle, $offset=0) { return stripos($haystack, $needle, $offset=0); } } 이와 같은 구현 부분을 종합해 분석해보면 변수 $file에 악의적인 입력 값인 상대경로에 사용되는 상위경로(..)가 나타날 경우 이를 찾아내고‘You are so cool...’이라는 에러 메시지를 출력함을 알 수 있다. 겉보기엔 전혀 보안 취약점이 존재하지 않는것처럼 보이지만 정상적인 동작 여부를 확인하기 위해 $file 인자에‘index/..’라는 요청을 해본 결과 <화면 2>처럼 구현된 에러 메시지가 출력됨을 알 수 있다.
여기서 우리가 간과한 점이 한 가지 있는데 바로 함수 strpos() 반환 값의 허점이다. 다음 PHP 매뉴얼에 상세하게 설명된 것처럼 함수 strops()는 찾고자 하는 문자열을 찾게 되면 해당 문자열이 시작하는 위치(offset)를 반환하게 된다. int strpos (string haystack, string needle, [int offset]) haystack 문자열에서 needle이 처음 나타나는 수 위치를 반환한다. strrpos()와 달리 이 함수는 needle 인자로 완전한 문자열을 받아서 전체 문자열을 사용한다. needle을 발견하지 못하면 strpos()는 boolean FALSE를 반환한다. 바로 여기서 취약점이 발생하는데 예를 들어‘index/..’와 같은 입력에서는 offset 값으로‘6’을 반환하겠지만‘../../’와 같이 처음부터 상대경로로 시작하는 입력에 대해서는 offset 값으로 ‘0’을 반환하고 이는 거짓(false)을 의미하기 때문에 modules.php의 비교문에서 에러 메시지 대신 정상적인 실행으로 처리되는 것이다. 따라서 공격자가‘../../../../../etc/passwd%00’와 같은 상대경로를 삽입했을 경우 이는 악의적인 입력에 대한 검증을 우회하게 되고 시스템의 주요 파일을 노출시킬 수 있는 것이다. %00은 NULL을 의미하는 것으로 문자열의 끝을 나타내고 뒤에 따라오는 문자열들이 무시된다. 이 취약점을 발견한 사람은 <화면 3>과 같이 Perl로 구성된 간단한 취약점 공격 스크립트를 공개했다. Perl로 구현된 소스코드에 실행 권한을 부여하고 공격 대상과 PHP-Nuke가 설치되어 있는 URL, 임의의 모듈명, 그리고 열람하고자 하는 파일명을 상대경로와 함께 요청하면 <화면 4>와 /etc/passwd와 같은 시스템의 주요 파일을 간단하게 다운받을 수 있다.
한편 PHP에서 지원하는 보안 옵션인 magic_quotes_gpc가 활성화되어 있을 경우에는 모든 phpBB Forum을 포함하고 있지 않은 PHP-Nuke에서는 다음과 같은 취약점이 발생할 수 있다. modules/Forums 디렉토리에 extension.inc 파일이 존재하지 않는다면 변수 $phpEx를 통해서 로컬 서버에 존재하는 임의의 파일을 삽입할 수 있다. http://victim/[nuke_dir]/modules.php?name=Search&file=../Forums/viewtopic&phpE x=../../../../../../etc/passwd phpMyAdmin의 보안 취약점 phpMyAdmin은 여러 개의 MySQL 서버를 하나의 관리 인터페이스로 관리할 수 있도록 도와주는 PHP 애플리케이션이다. Maksymilian Arciemowicz는 지난 10월 10일에 phpMy Admin의 버전 2.6.4-pl1에 대한 보안 취약점을 발표했는데 이는 앞서 설명한 PHP-Nuke와 동일한 디렉토리 이동 취약점이다. 문제가 되는 부분은 phpMyAdmin의 libraries 디렉토리에 존재하는 grab_globals.lib.php로 관련 소스는 다음과 같다. if ( isset( $_POST[‘redirect’] ) && $_POST[‘redirect’] != basename( $_SERVER[‘PHP_SELF’] ) ) { $__redirect = $_POST[‘redirect’]; unset( $_POST[‘redirect’] ); } // end if ( isset( $_POST[‘redirect’] ) ) …(생략) … if ( ! empty( $__redirect ) ) { require(‘./’. $__redirect); exit(); } // end if ( ! empty( $__redirect ) ) 이를 보면 POST 방식으로 전송된 변수 $redirect의 입력 값을 그대로 받아 $__redirect 함수에 저장하고 이를 이용해 시스템에 존재하는 임의의 파일을 삽입하고 있다. 문제는 변수 $redirect에 대한 입력 값을 검증하지 않고 함수 require()를 이용해 시스템 파일을 삽입하기 때문에 상대경로(../)를 이용한 입력 값 조작을 통해서 시스템에 존재하는 어떠한 파일이라도 포함이 될 수 있다는 것이다. 따라서 공격자는 간단한 조작을 통해 /etc/passwd 파일과 같은 시스템의 주요 파일을 그대로 획득할 수 있다.
이 취약점에 대해서도 <화면 6>과 같이 Perl로 구현된 공격코드가 공개됐다. phpMyAdmin 공격코드는 PHP-Nuke의 공격코드와 마찬가지로 공격 대상과 해당 애플리케이션이 존재하는 URL 위치 그리고 공격자가 획득하고자 하는 파일을 상대 경로와 함께 요청하기만 하면 자동적으로 이루어지고 해당 파일을 획득할 수 있도록 되어 있다.
사용자 입력 값을 검증하라 지금까지 PHP-Nuke와 phpMyAdmin에서 발생한 디렉토리 이동 취약점에 대해 살펴보았다. 취약점이 발생하는 부분은 다르지만 발생 원인은 공통적임을 알 수 있다. 즉 사용자로부터 전송돼 오는 입력 값을 적절하게 검증하지 않았기 때문이다. PHP-Nuke의 경우 함수 strpos()를 이용해 공격 징후를 차단하는 과정에서 문자열의 처음에 상대경로가 입력될 수 있다는 것과 함수 strops()의 반환 값에 대한 검증이 충분치 않았기 때문에 발생하는 것이고 phpMyAdmin은 변수 $redirect에 상대경로와 같은 악의적인 요청이 입력될 수 있다는 예상을 하지 못했기 때문이었다.
추가적으로 10월 23일 발표된 PHP-Nuke의 취약점은 rod에 의해서 공격코드가 제작되었으며 <화면 7>과 같이 편리한(?) 인터페이스를 제공하고 있다. 이 취약점은 PHP 환경 설정에서 magic_quotes_gpc가 비활성화되어 있을 때 발생하는 것으로 ‘Your Account’, ‘Downloads’, ‘Web_links’모듈에서 SQL 인젝션을 수행할 수 있다. 취약점을 제공하는 변수는 Your Account 모듈에서는‘username’, Downloads 모듈에서는‘url’, Web_links 모듈에서는‘description’이다. 해당 변수에 다음과 같은 악의적인 SQL 구문을 삽입함으로써 공격자는 웹 디렉토리에 shell.php라는 악성 스크립트를 생성할 수 있고 이를 통해 시스템 명령어를 실행할 수 있는 권한을 획득한다. ‘ UNION SELECT ‘<?error_reporting(0);?>’,0,0,0,0,0,0,0,’<?echo “Hi Master”;ini_set( “ max_execution_time”,0);system($_GET[cmd]);die;?>’,0 INTO OUTFILE ‘../../WWW/PHPNUKE/shell.php’FROM nuke_users/* 이러한 문제점이 발생하는 더 근원적인 이유는 개발자가 사용자로부터 입력되어 오는 값을 한정짓지 않기 때문이다. 사용자로부터 입력될 수 있는 모든 입력 값의 패턴을 규정하고 정해진 패턴에 대한 입력 값만을 허용한다면 이런 취약점은 크게 줄일 수 있을 것이다. 미 국방성의 조사 자료에 의하면 애플리케이션 코드 1000라인에는 평균 15개의 보안 취약점이 존재하고 있다고 한다. 이러한 근원적인 문제점을 해결하기 위한 최선의 대안은, 보안 취약점이 발생하는 원인과 취약점이 발생할 수 있는 부분에 대해 개발자 스스로 사전에 인지하고 이를 막기 위한 내용을 실제 프로그래밍 과정에 반영하는 것이다. 또한 PHP-Nuke와 phpMyAdmin을 비롯하여 공개 애플리케이션을 사용하는 개발자는 항상 자신이 사용하고 있는 애플리케이션의 새로운 소식에 귀를 기울이고 해당 보안 취약점이 나왔을 때 발빠른 조치와 함께 패치를 수행하는 적극성을 가지고 있어야 한다. 원격코드 삽입 취약점의 경우 웜으로 제작돼 전파될 가능성도 있으므로 사전에 피해를 최소화하기 위한 노력을 아끼지 말아야 한다. 실제로 이번 호에 살펴본 PHP-Nuke와 phpMyAdmin의 보안 취약점 이외에 지난번에 다루었던 phpBB가 2005년 10월 31일에도 버전 2.0.17 이하에 대해 사용자 측에서 스크립트를 실행할수 있는 Cross-Site Scripting 취약점과 SQL 인젝션 취약점, 그리고 원격코드 삽입 취약점이 새롭게 발표됐다. 유명한 만큼 이름 값을 하고 있다는 생각이 든다. 현재 가장 최신 버전이 2005년 10월 30일 발표된 버전 2.0.18이므로 사용자들은 최신 버전으로 업데이트하길 바란다.@ * 이 기사는 ZDNet Korea의 제휴매체인 마이크로소프트웨어에 게재된 내용입니다. |












