그러냐

파일 업로드/다운로드 취약점 - 업로드 본문

php 시큐어코딩

파일 업로드/다운로드 취약점 - 업로드

관절분리 2023. 2. 17. 17:34
반응형
더보기
닫기

- webhard.php

<?php
    session_start();
    if($_SESSION['loginID'] == "")
    {
        echo "<script>alert('로그인 후 사용하실 수 있습니다.'); location.href='/'; </script>";
        exit;
    }

?>

<html>
    <head>
        <title>웹하드</title>
    </head>

    <body>
        <pre>
            <form method="POST" action="search_file.php">
                검색어 : <input type="text" name="keyword">
                <input type="submit" value="검색"> <input type="reset" value="취소">
            </form>

            <form method="POST" action="up_file.php" enctype="multipart/form-data">
                <input type="file" name="upfile">
                <input type="submit" value="업로드"> <input type="reset" value="취소">
            </form>
        </pre>
    </body>

</html>

 

 

- 웹 서버 테이블

mysql> create table file_tb(
    -> no int auto_increment primary key,
    -> name varchar(255) not null,
    -> user varchar(20) not null,
    -> size varchar(20) not null,
    -> reg_date datetime
    -> );
Query OK, 0 rows affected (0.01 sec)

 

 

- 웹서버 업로드 디렉토리 권한

> chmod 777 upload

 

 

- up_file.php

<?php

    echo $name = $_FILES['upfile']['name'];
    echo $tmp_name = $_FILES['upfile']['tmp_name'];
    echo $size = $_FILES['upfile']['size'];

    $conn = mysql_connect("localhost", "root", "P@ssw0rd");
    if(!$conn){
        echo "DBMS Connect Fail!";
        exit;
    }

    mysql_select_db("webhacktest");

    session_start();
    $sql = "insert into file_tb set name='$name', user='$_SESSION[loginID]', size='$size', reg_date=now()";

    $result = mysql_query($sql);

    if($result)
    {
       $move_result = move_uploaded_file($tmp_name,"./upload/$name");

       if($move_result)
       {
           echo "파일 업로드 성공";
       }
       else
       {
            echo "파일 업로드 실패(이동)";
       }
    }
    else
    {
        echo "파일 업로드 실패";
    }
    mysql_close();
?>

 

 

- 임의의 파일 업로드

 

 

 

 

 

- 검색 구현

> search_file.php

<?php

    $keyword = $_POST['keyword'];
    $conn = mysql_connect("localhost","root","P@ssw0rd");
    if(!$conn)
    {
        echo "DBMS Connect Fail";
        exit;
    }

    mysql_select_db("webhacktest");
    $sql = "select * from file_tb where name like '%$keyword%'";
    $return = mysql_query($sql);

?>


<html>
    <head>
        <title> 검색 결과</title>
    </head>


    <body>
        
            <?php
            while($result = mysql_fetch_array($return))
            {
            ?>
           
            번호 : <?= $result['no']; ?> <br>
            파일이름 : <a href="down_file.php?name=<?= $result['name'];?>"><?= $result['name']; ?> </a> <br>
            파일크기 : <?= $result['size']; ?><br>
            등록자 : <?= $result['user']; ?><br>
            등록일시 : <?= $result['reg_date']; ?><br><br>
        
            <?php
            }
            ?>
        
    </body>

</html>

 

 

- 파일 내려받기

> down_file.php

<?php
    // 다운로드 할 파일명을 변수에 저장
    $name = $_GET['name'];


    // 응답 메시지에 헤더를 추가하는 함수
    Header("Content-Type: application/octet-stream"); // 바이트 단위로 전달
    Header("Content-Disposition: attachment; filename=$name"); // filename 항목이 클라이언트 측에 저장될 파일 이름
    Header("Content-Transfer-Encoding: binary");  // 전달하는 파일의 형식은 바이너리 형식(원본 그대로)으로 전달
    Header("Content-Length: ".filesize("./upload/$name")); // content-length헤더는 저장 될 파일의 크기(filesize 함수)


    // 클라이언트에게 전달 할 파일을 오픈함, 바이너리 모드, 읽기 전용
    $fd = fopen("./upload/$name", "rb"); // rb = r 읽기모드 , b 바이너리모드

    // 오픈된 파일을 읽고 응답 메시지에 출력한다
    echo fread($fd, filesize("./upload/$name"));

?>

 

 

 

File Upload

• File Upload 취약점

- 웹 서버가 제공하는 파일 업로드 기능을 이용하여 악성 스크립트를 업로드 하는 공격

- 서버에서 실행될 수 있는 파일을 업로드 하여 공격자가 원하는 기능을 동작하게 함

- 적절한 검증 없이 파일 업로드 기능을 제공할 때 발생하는 취약점 → 확장자 검증 필요

 

• 피해 범위

- 악성 스크립트를 이용한 시스템 명령 실행, 시스템 구조 파악

 WEB Shell을 이용하여 공격 함

- 간단한 Backdoor를 업로드 한 뒤 이를 이용하여 공격을 시도 함

 

• 공격 조건

- 파일 업로드가 가능해야 함

- 파일이 업로드된 디렉터리의 경로를 알아야 함

- 파일이 업로드된 디렉터리의 실행 권한이 있어야 함

 

 

 

 

 

 

File Upload - 취약점

조건1) 파일 업로드 할 수 있는 기능이 제공이 되어야함.

조건2) 파일 업로드 되는 경로를 알아야함(부적절한 구성으로 인한 노출, 오픈소스 제작된 페이지)

조건3) 업로드 된 디렉토리에 실행 권한이 있어야함.

 

취약점) 웹쉘을 실행 할 수 있다.

--> 웹쉘 : 웹 서비스를 이용하여 서버측의 명령을 실행할 수 있는 악의적인 목적의 스크립트 파일

 

취약점 원인) APM(Apache+Php+Mysql)

> php : 서버측에서 동적인 처리를 위해 사용하는 언어

, php, apache와 mysql이 데이터를 주고 받을 수 있도록 만들어준다.

> php의 함수를 이용하면 리눅스 시스템 명령(쉘 명령) 실행할 수 있게 된다.

 

 

File Upload - 취약점 공격 실습

 

1. guest로 파일(test.txt) 업로드

 

 

2. 웹서버에서 업로드 된 파일 실행

 

 

 

 

3. webshelltest.php

> system() 함수 사용

<?php echo system('ls'); ?>

 

4. 결과

 

 

 

File Upload - 취약점 공격 실습 : cmd

 

 

<?php echo system($_GET['cmd']); ?>

 

> 반응 없음

 

 

 

 

 

 

 

File Upload - 취약점 공격 실습 : c99shell

> GUI 방식, 다양한 작업 수행 가능

 

 

 

 

1. 서버의 코드도 쉽게 확인 가능

> localhost.. database 이름..

 

 

2. 웹서버의 mysql 정보 획득 가능

 

 

 

 

File Upload - 웹쉘 업로드 취약점 보안

 

1. php 문자열 필터링

> /i 대소문자 관계없이 필터링

    echo $name = $_FILES['upfile']['name'];
    echo $tmp_name = $_FILES['upfile']['tmp_name'];
    echo $size = $_FILES['upfile']['size'];

    if(preg_match("/.php/i",$name))
    {
        echo "php 파일은 업로드 하실 수 없습니다.";
        exit;
    }

 

 

 

2. .php 업로드 결과

 

 

 

 

 

File Upload - 웹쉘 업로드 취약점 보안 : 우회 방법(.htaccess)

 

.htaccess

: 분산 설정 파일

 

* httpd

----------------------------

A : 공식 홈페이지

B : 쇼핑몰 홈페이지

----------------------------

 

> /etc/httpd/conf/httpd.conf 수정하면 A,B 둘다 설정값이 적용 된다.

 

> 어느 한쪽만 따로 설정하고 싶은경우 htaccess가 사용된다.

: 디렉토리 별로 설정값이 달리 적용된다.

 

 

 

문제점

 

1. 공격자는 c99shell.php 파일을 업로드 하려고 한다.

 

> .php 파일은 필터링되어 있으므로 업로드할 수 없다.

 

 

 

2. c99shell2.txt로 확장자를 변경하여 업로드한다.

 

 

> 업로드는 되었지만 txt로 처리되므로 의미가 없다.

 

 

 

 

우회 방법

> 현재 php는 업로드할 수 없지만, txt는 업로드 할 수 있고 처리될 수 있다.

 

조건1) 아파치 웹서버 설정에서 허용이 되어있어야한다.

[root@localhost upload]# vim /etc/httpd/conf/httpd.conf

 

 

 

 

 

1. .htaccess 생성

AddType application/x-httpd-php .txt

> .txt 파일을 php파일로 실행되게함

 

 

 

2. .htaccess를 먼저 업로드

 

 

 

3. c99shell2.txt 업로드

 

 

 

 

 

보안

 

1. htaccess도 필터링한다.

    if(preg_match("/.php|.htaccess/i",$name))
    {
        echo "php,htaccess 파일은 업로드 하실 수 없습니다.";
        exit;
    }

 

 

 

 

 

출처 : https://girrr.tistory.com/99

반응형