웹 해킹 & 시큐어 코딩

웹 해킹 & 시큐어 코딩 (25)

홍시뗄레 2025. 2. 6. 17:03

파일 다운로드 취약점이란 무엇인가?

정상적인 파일이 아닌 비정상적인 파일을 다운로드받는 취약점. 

공격 대상은 파일 다운로드 기능. 

정상적인 파일과 비정상적인 파일 기준은 무엇일까?

사용자는 정상적으로 파일을 다운로드 받는다. 기준은 파일 다운로드 기능에 제한되어 있는 곳에서 다운로드를 실행하느냐, 아니면 벗어나느냐에 따라 구분된다.

기존에 다운로드 기능은 특정 경로를 지정해둔다. 예를 들어, /web/root/A/upload/

이렇게 사용자가 업로드하는 경로가 있고, 여기서 다운로드받을 수 있게 지정된 경로를 통해 받을 것이다.

 

그러나 공격자는 이 경로를 변조한다. 

전체 경로를 사용자로부터 입력받는다면 쉽게 경로를 바꿀 수 있다. 

일부 경로만 받는 경우도 있지만, 공격자가 경로 이동 문자를 삽입하면, 경로 이동을 통해서 소스코드나 서버 설정 파일 등을 받을 수 있게 된다.

 

결국, 파일 다운로드 기능에 대해 비정상적인 파일을 받는 취약점인데, 경로 이동 문자를 삽입해서 지정된 경로를 벗어난 파일을 다운로드 받는 취약점이다. 기준은 지정된 경로냐 아니냐에 따라 구분된다.

공격 원리 분석

사용자로부터 파일명을 입력받는다. 이때 공격자는 경로 이동 문자가 삽입된, 서버의 특정 설정 파일을 다운로드 시도한다. /etc 경로가 리눅스나 유닉스의 최상위이다. 

client 관점에서는 경로가 어떻게 구성되어 있는지 모르기 때문에 무작정 될 때까지 경로 이동 문자를 계속해서 넣는다. 

 

../가 입력되므로써 상위로 올라탄다. 

이렇게 만들어진 경로의 파일이 유출된다. 

결국 공격자에게 passwd 파일이 보내질 수도 있다. 

공격 방법

case 1: 단순히 파일명만 받는 경우.

소규모 웹서비스일 경우가 많다. 리눅스나 유닉스일 경우엔 etc다. 윈도우 기반은 최상위가 없다. 

윈도우는 파티션을 분리하기 때문에 디폴트값이 없다. (전체 경로를 받는 경우 제외)

이렇게 지정 경로를 벗어날 수 있다.

 

case 2: 일부 경로와 파일명을 입력받는 경우.

중규모 이상 대규모 웹사이트. 파일 다운로드 경로를 분리해놨다는 의미. 

1에서는 /upload/ 여기다가 파일을 놨다면, 2는 /upload/notice/ 이런식으로 upload 경로 안에 분리를 해준 경우이다. 규모가 커서 관리를 편리하게 하기 위해 경로를 세분화한 것이다.

공격 방법은 두 가지이다. 경로 삽입 문자를 넣거나, 파일명에 넣는 방법도 있다.

path와 filename 둘다 대응해야 된다.

 

case 3: 전체 경로를 받는 것

공격자에게 큰 힌트가 된다. 

일부 경로만 공개되는 것이 가장 바람직하다.

공격자는 전체 경로에 etc로만 바꾸면 된다. 굉장히 취약함.

 

* 운영체제별 경로 구분 기호

unix, linux: /

windows: \ (역 슬래시), / 둘다 사용 가능

 

간혹 진단할 때 윈도우에서 역 슬래시를 대응하지 않으면 취약하다.

[실습7-1] 파일 다운로드 취약점 공격 실습

파일 업로드에 앞서 게시글 하나를 작성해줄 건데, 아무 파일이나 클릭해서 올려주겠다. 나같은 경우엔 텍스트 파일을 하나 업로드해줄 것이다. 

참고) 파일 크기가 너무 크면 업로드가 안 되므로 정말 작은 파일을 업로드해주자. 나는 hi.txt에 hi 하나만 입력하고 저장했다.

이렇게 올라갔고, 파일을 다운로드 받기 위해 클릭하면서 버프스위트로 페이로드를 한번 보자.

우선 repeater로 보내봤다.

먼저 경로 이동이 가능한지 확인해보기 위해서 내가 올린 파일 앞에 /, \를 입력했을 때 어떤 결과가 나오는지 확인해보자.

둘 다 가능하다. 결국 윈도우 기반이란 것을 확인할 수 있다.

이번엔 ./를 넣어보자. 

./를 입력했을 때는 파일 다운로드가 되지만

../를 입력하면 다운로드되지 않는다. (hi가 있는지 없는지 확인해주면 된다.)

 

여기는 소규모 웹사이트기 때문에 업로드 경로가 하나밖에 없을 것이다. ../를 하면 상위 경로로 올라가게 된다. 그래서 파일을 찾을 수 없어서 다운로드가 불가능할 것이다.

그 위에가 웹 디렉터리라고 생각하고, ../index.php라고 입력해보자.

이렇게 했더니 index.php를 다운로드 받을 수 있게 되었다. 파일 다운로드 취약점을 통해서 서버사이드스크립트로 작성된 코드를 볼 수 있게 되었다.

다른 파일들도 받아볼 수 있을 것이다. (common.php로 연습해보면 나온다.)

소스코드 다운로드 외에도 서버 내 여러 설정 파일을 다운로드 받을 수 있고, 이는 매우 위험하다. 

 

[실습7-2] 개발자분들이 자주 실수하는 잘못된 대응 방안 적용

download.php에서 ../와 ..\에 대한 치환 처리를 해준다. 그럼 저장해주고, 경로 이동이 되는지 확인해보자.

다시 다운로드를 받는 페이로드를 리피터로 보내서 확인해보자. ../를 앞에다 붙였는데도 불구하고 파일이 다운로드되어 실행된 것이 나타난다. 치환하면서 제거했기 때문에 ../가 없어지고, 그냥 hi.txt를 다운로드되는 방식으로 작동되고 있다.

근데 만약 ../가 제거된다면, 다른 방식으로 다운로드받을 수 있지 않을까?

....//를 붙이면 우회가 가능하다.

이렇게 우회가 가능해지기 때문에 ../를 치환하는 것은 안전한 시큐어 코딩이 아니다.

근데 이건 아무리 제거하려고 해도 어떻게든 우회가 된다.

그리고 윈도우 환경에서 /만 제거한다고 해도, \가 남아있기 때문에 안전하지 않은 시큐어 코딩을 할 수도 있다.

[실습7-3] 재미로 보는 실무 사례 분석

파일 이름 중간에 /를 넣어서 치환하는지 확인할 수 있다.

예: 

webshell.jsp를 다운로드받고자 할 때

w/ebshell.jsp를 넣어서 다운로드가 되는지 확인하는 것이다.

무엇을 제거하는지 하나씩 리피터를 통해 확인해보면 경로 이동이 가능한지 볼 수 있다.

대응 방안

간접적 다운로드 방식은 key 값. 기존 3가지 케이스는 어플리케이션 단에서 직접 파일 시스템으로 접근했다면, 네 번째 케이스는 db에 질의를 한다. 효율은 더 떨어지지만 보안적으로 더 안전하다.

 

전체 경로 + 파일명

예전에는 많았지만 요새는 다 대체되고 있다. 보안상 좋지 않은 설계이다.

 

일부 경로 + 파일명

오늘날 웹에서 가장 많이 사용된다. 경로와 파라미터에 대한 올바른 검증 로직이 필요하다. 역슬러시 문자를 치환, 제거하거나 문자들이 존재할시 경고창을 출력하고 어플리케이션을 종료하는 방법이 있다. 우회하는 것을 방지할 수 있다.

 

파일명

파라미터에 대해 슬러시나 ..에 대해 위와 같이 점검을 하면 된다.

 

키(Key) 값

sql injection에 취약할 수도 있다. 키값을 입력받는다면 preparedStatement를 이용하여 안전하게 코딩해야 한다. 

 

[실습7-4] 취약 환경 시큐어 코딩 적용 실습

이제 실습을 해보자.

이렇게 슬러시가 하나만 들어가도 오류가 떠서 다운로드가 되지 않는 것을 확인할 수 있다. 

점도 확인해보면 오류가 나타나고, 오로지 hi.txt만 입력해야 다운로드가 가능해진다.