모의해킹 스터디 복습

모의해킹 스터디 15주차(1): 이미지 웹쉘의 실체

whydontyoushovel 2025. 2. 11. 04:51

목차

  • 웹쉘과 이미지 웹쉘
  • 이미지 웹쉘이 가능한 상황

        1) 확장자 검증 미흡

        2) Null Byte Injection

        3) .htaccess 설정 파일

        4) File Include 취약점

  • 정리

 

 

 File Upload 

공격자가 원하는 임의의 파일을 서버에 업로드할 수 있는 공격

웹쉘은 대표적인 File Upload 공격 시나리오 중 하나

 

 

   웹쉘  & 이미지 웹쉘       

1) 웹쉘

  • 인터넷 상에서 OS 명령을 내릴 수 있게 하는 파일
  • OS 실행 코드를 파일에 포함시켜 대상 서버에 업로드한 후 해당 파일을 웹으로 요청
  • 서버는 요청한 파일의 서버측 스크립트를 모두 실행시킨 뒤 결과를 클라이언트에게 반환

실행 예시

 

2) 이미지 웹쉘

  • 확장자가 .jpg나 .png, .php.jpg 등의 이미지 파일인데 내부의 웹쉘 코드가 실행되는 경우 이미지 웹쉘이라고 함

 

▷문제

  • 웹쉘 공격은 확장자가 서버측 실행코드(php 등)여야 서버에서 WAS로 코드를 넘겨 실행시킬 수 있음
  • .jpg나 .php.jpg 등의 확장자는 절대 실행 안되는 게 맞음
  • 근데 이미지 웹쉘이 실행된다는 글이 자주 목격됨 (특히 이중확장자)

 

▷목표

  • 이미지 웹쉘이 실행되는 경우를 살펴보고 이게 어째서 실행이 되었으며 이것이 왜 이미지 웹쉘이라고 할 수 없는지 생각해보기

 

 

 

   이미지 웹쉘이 실행되는 케이스       

▷ webshell.jpg.php 된당께요

업로드 파일에 대한 확장자 검증이 미흡한 경우

  • 예시 코드
<?php
function double_extPass($filename) {
    $name = explode('.',$filename);
    $ext = $name[1];

    if($ext == "png") {
        return true;
    } else {
        echo "<script>alert('png 형식만 지원됩니다.');</script>";
        exit;
    }
}

$explode = double_extPass($_FILES['image']['name']); //.png.php 테스트

if (isset($_FILES['image']) && $_FILES['image']['error'] === 0 && $explode) {
    $img_name = basename($_FILES['image']['name']);
    $file_path = "img/";
    $targetPath = $file_path . $img_name;
    // 서버에 파일 저장 + DB에 경로 저장
} else {
    // 돌아가
}
?>
  • example.png.php 파일을 업로드할 경우 " . "을 기준으로 문자열 분리 후 배열로 저장
  • 분리된 문자열 중 [1]번째 요소가 "png"이면 true 반환
  • 업로드한 파일이 있고 에러가 없으며, [1]번째 문자열이 "png"일 경우 img/example.png.php라는 경로에 파일 저장

 

★ 내 서버에서 실습해보기

.png.php 확장자를 가진 웹쉘 파일을 업로드

 

정상 업로드됨

업로드한 게시물로 리다이렉션

 

파일을 실행시키기 위해 이미지 아이콘을 우클릭한 뒤 새 탭에서 파일 요청

새로 연 탭에서 cmd 명령어를 입력하고 실행 결과를 확인

 

서버의 파일 저장 경로에도 정상적으로 저장됐음을 확인함

 

  • 확장자를 하나만 썼을 거란 생각으로 앞에서부터 검증하고 파일 이름 전체를 저장
  • 이 경우 .jpg.php 등의 확장자는 서버에 저장될 수 있음
  • 악성코드를 유포할 때 이와 비슷한 케이스가 이용되기도 함. 운영체제 내 기본 확장자를 숨기는 옵션이 설정되었을 경우 example.pdf.exe 파일도 example.pdf로 표시되어 악성 프로그램을 실행시킬 수 있음.  

 

 

▷ webshell.php%00.jpg는 된당께요

Null Byte Injection 취약점

  • 예시 코드
<?php
function null_test($filename) {
    $name = explode('.',$filename);
    $ext = end($name);

    if($ext == "png") {
        return true;
    } else {
        echo "<script>alert('" . $ext . ": 이 형식은 안됨.');</script>";
        exit;       
    }
}

$null_test = null_test($_FILES['image']['name']);

if (isset($_FILES['image']) && $_FILES['image']['error'] === 0 && $null_test) {
     $img_name = basename($_FILES['image']['name']);
     $file_path = "img/";
     $targetPath = $file_path . $img_name;
     //서버에 파일 저장
     //DB에 경로 저장
} else {
    //돌아가
}
?>
  • example.php%00.png 같은 파일명에서 " . " 을 기준으로 문자열 분리
  • 분리한 뒤 얻은 배열의 가장 마지막 값(png)을 변수에 저장
  • 이 값이 png일 경우 true 반환
  • 업로드한 파일이 있고 에러가 없으며, 파일명 마지막에 쓰인 확장자가 png일 경우 "img/example.php%00.png"라는 경로에 파일 저장
  • 이때 서버에는 %00 이후 문자열이 잘린 채 example.php만 저장됨

 

★ 내 서버에서 실습해보기

이름에 널 바이트가 삽입된 파일과 함께 게시글 작성

 

정상 업로드 되었다는 알림 확인

 

리다이렉션 된 페이지에서 파일을 새 탭으로 엶

 

안됨

 

널 바이트를 생략한 뒤 요청해도 안됨

서버를 확인해보니 webshell.php%00.png 로 널 바이트 이후 문자열이 포함된 채 저장됨
널 바이트 인젝션 공격에 실패했다는 뜻.
널 바이트 인젝션은 php 5.3.3 이하 버전 및 windows 서버 (IIS) 특정 버전에서 볼 수 있는 취약점이라고 함
  • $_FILES로 이름을 받을 때도, move_uploaded_file로 경로를 지정할 때도 널 바이트 이후는 잘리지 않았다는 뜻

echo phpversion(); 으로 php 버전을 확인해본 결과.
왜 404가 뜰까 고민해봤는데 이미지 확장자인데 내용이 이미지가 아니라서는 아닌 것 같음.
.png로 업로드했을 땐 실행만 안될뿐 이미지 아이콘이 뜨긴 했기 때문에.
아파치 서버가 .php%00.png 파일 요청 시 %00을 처리하지 못하는 것 아닐까...생각..

 

  • 웹 애플리케이션(백엔드)가 png를 검증한 뒤 이미지 파일로 생각하여 통과시킬 때
  • 운영체제 버전에 따라 %00 이하의 문자열은 탈락시키고 저장해서 webshell.php로 저장될 가능성이 있음

 

 

▷ webshell.php.jpg 진짜 된당께요

.htaccess 설정 파일 덮어쓰기

  • 디렉토리별로 규칙을 직접 지정하여 이미지 확장자도 php처럼 동작하게 할 수 있음
AddType application/x-httpd-php .png

 

 

★ 내 서버에서 실습해보기

php 파일을 포함한 게시글을 작성

php 형식은 안된다는 alert 확인

 

버프 스위트의 인터셉트를 활성

 

다시 게시글을 작성하여 업로드

파일명을 ".htaccess"로,
파일 내용을 "Addtype application/x-httpd-php .hellyeah"로 변경한 뒤
요청 전송

 

파일 업로드 성공

.htaccess가 저장된 경로를 확인하기 위해 새 탭으로 파일을 요청

해당 설정 파일이 업로드되었으나 접근 권한이 없어서 403 코드가 뜸
어쨌든 img 디렉토리의 파일 중 .hellyeah 확장자를 가진 파일은 php처럼 실행시킬 것

 

ls -al 명령어 실행 결과
img 디렉토리에 설정 파일이 저장된 것을 확인할 수 있음

웹쉘을 올리기 위해 다시 인터셉트를 켬

확장자를 변경시킬 파일과 함께 게시글을 작성

 

인터셉트한 요청 데이터에서 파밀명의 확장자를 .hellyeah로 변경한 뒤 전송

파일이 서버에 업로드됨

웹쉘 파일을 실행시키기 위해 새 탭에서 파일 요청

cmd 명령어를 GET 방식으로 전달한 결과
서버가 명령어를 실행했음을 알 수 있음

 

설정 파일을 다시 업로드하여 png 파일이 php처럼 실행되게 할 수 있음

대신 설정 파일을 또 업로드할 경우 원래 있던 설정 파일의 내용을 덮어쓰기 때문에
이전에 설정한 hellyeah 확장자는 더이상 실행되지 않음
(덮어쓰기 때문에 서버에 저장된 .htaccess 파일 수는 여전히 1개임)
  • 파일 업로드 취약점이 있다면 .htaccess 파일을 업로드하여 파일 저장 경로의 설정을 변경할 수 있음
  • 이때 어떤 확장자든 php처럼 서버가 코드를 실행시키게 설정할 수 있기 때문에 jpg 등의 확장자도 웹쉘이 됨
  • 이런 이유로 .php.jpg 같은 이중확장자도 실행시킬 수 있음

 

 

 

▷ webshell.jpg 이거 진짜 됨. 내가 봤음.

File Include 취약점

  • include 기능: 다른 파일을 그대로 포함시켜 무조건 실행함
  • include 함수 안에 들어가는 파일을 GET 파라미터로 받을 경우 png 확장자인 웹쉘을 실행시킬 수 있음
  • 예시 코드
<?php
    if(isset($_GET['page'])){
        include($_GET['page']);
    }
?>
  • page 파라미터가 있으면 그 파일을 현재 파일에 포함시킴
  • php 코드 내부에 있으므로 무조건 실행됨

 

★ 내 서버에서 실습해보기

인클루드 취약점을 만들어 둔 게시글 읽기 페이지에 접근

 

테스트 삼아 로그인 페이지 요청
css는 개박살났지만 login.php를 포함시키고 있는 것을 확인

 

파일 인클루드 취약점을 이용해 이미지 웹쉘을 실행시키기 위해
png 확장자를 가진 웹쉘 파일 업로드

파일이 서버에 업로드됨

 

리다이렉션된 페이지에서 파일을 우클릭하여 새 탭으로 엶

 

이미지 파일이라 실행되지 않음

 

파일 인클루드 취약점이 있는 페이지에서
이미지 웹쉘을 요청했으나 아무 변화가 없음
당연함. cmd 파라미터를 전달하지 않았음

 

웹쉘의 파라미터인 cmd명령어를 포함하여 전송한 결과
웹쉘 코드가 실행되고 있음을 확인
웹쉘 파일을 새 탭으로 열 때와 달리 현재는 게시글 읽기 페이지에서 실행되고 있기 때문에 
ls 명령어 결과 img 상위 디렉토리의 파일 목록이 출력되고 있음

 

명령이 실행되는 현재 위치

 

  • 파일 인클루드 취약점이 있는 페이지에서 png 등의 이미지 확장자를 가진 웹쉘 코드가 실행될 수 있음

로그파일 읽기 권한 문제

 

 

 

 

 

 

   정리       

 

1) 확장자 검증 미흡

원인 개발 시 업로드 파일 확장자를 앞에서부터 검사함
결과 .jpg.php 등의 이중확장자를 이미지 파일로 착각하고 서버에 저장
이미지 웹쉘이
아닌 이유
이미지 파일이 아니라 걍 php 파일임

 

2) Null Byte Injection

원인 서버측 개발 환경 상의 취약점
결과 .php%00.jpg 로 업로드 시도할 경우 뒤에서부터 확장자를 검사해도 서버에는 %00 이후 문자열을 제외한 채 저장
이미지 웹쉘이
아닌 이유
얘도 걍 php 파일임

 

3) .htaccess 설정 파일 덮어쓰기

원인 .htaccess 파일이 서버에 업로드됨
결과 실행되지 않는 확장자를 php처럼 실행되게 함
이미지 웹쉘이
아닌 이유
굳이 이미지 확장자일 필요도 없음

 

4) File Include 취약점

원인 사용자가 include 함수에 포함될 파일을 지정할 수 있으며 파일에 포함된 코드는 무조건 실행시킴
결과 .jpg 같은 이미지 확장자를 가진 웹쉘 파일을 포함시켜 코드를 실행시킬 수 있음
이미지 웹쉘이
아닌 이유
이미지 웹쉘이긴 하지만 파일 업로드 취약점 이외의 별개의 취약점이 필요함