File Upload Vulnerability [6]
DATE : 2023/9/21
Last updated
DATE : 2023/9/21
Last updated
이전 LAB에서는 blacklist로 특정 파일 확장자를 차단하고 있었다.
또한 blacklist를 피해 서버에 파일을 업로드 하더라도 그 파일을 실행할 대상으로 인식 시키기 위해
.htaccess 파일을 작성해줄 필요가 있었다.
이번에 풀어볼 LAB에서도 Blacklist가 적용된다고 하는 데
업로드할 수 있는 파일 확장자가 좀 더 제한적인 느낌이다...!
이번 LAB은 어떻게 해결할 수 있을 지 바-로 들어 가보자.
앞에서 살펴봤던 것처럼 LAB에 들어가 wiener:peter 계정으로 로그인해준다.
로그인 후 제공되는 avatar form에 업로드 하고 싶은 file을 넣어 Upload 하면
오직 JPG & PNG file만 업로드할 수 있다고 한다.
그렇다면 우리가 업로드 하고 싶은 PHP file은 업로드를 할 수 없다..!
그렇다면 우리가 올리는 파일은 PHP인데 이를 JPG or PNG로 인식하도록 만들어야 한다.
일단 제일 단순하게 파일 확장자를 이어 붙여보자.
원래 filename에 확장자 하나를 더 붙여서 보내봤다.
response를 확인해보면 정상적으로 업로드 된 걸 확인할 수 있다.
(.png로 실행해도 동일한 결과가 나온다.)
그렇다면 다음 문제는 blacklist를 회피해 올린 파일이 서버에서 실행되도록 만드는 것이다.
jpg 상태로 서버에 올려지면 이 파일을 실행시킬 대상으로 인식하지 않는다.
따라서 업로드할 때는 jpg를 보고 blacklist를 회피하고 이후에는 이 확장자가 인식되면 안된다.
이를 실행할 수 있는 간단한 방법은
.jpg 앞에 세미콜론을 붙이거나 null byte를 붙이면 된다.
파일 확장자를 검사할 때는 맨 뒤에 있는 jpg를 보고 이미지 파일이라 판단해 blacklist를 우회하고
파일을 실행할 때는 파일 이름을 세미콜론 or Null byte 전까지만 인식하게 된다.
따라서 파일을 업로드 하고 나면 세미콜론 or Null Byte 뒤에 붙은 jpg or png 확장자는 무시되고
php까지만 인식한 서버는 이 파일을 실행하게 되는 것이다.
filename을 "webshell.php%00.png"로 조작해 packet을 보내면
성공적으로 파일을 업로드할 수 있고
URL 바에 /files/avatars/webshell.php를 입력해 실행도 시킬 수 있다.
secret file에서 찾은 flag를 제출해주면 끝!
위의 과정은 %00(null byte)가 아닌 세미콜론으로 해도 똑같은 결과를 얻을 수 있다.
이번 LAB에서는 파일 업로드를 통과할 수 있는 특정 확장자로 인식되기 위한 우회 방법을 살펴보았다.
만약 filename 안에 포함된 확장자가 몇 개인지 확인하거나
확장자와 content-type 또는 확장자와 파일 내용 등을 같이 검사하는 과정을 거쳤다면
단순히 확장자 하나를 이어 붙이는 걸로는 우회할 수 없었을 것이다.
그렇다 보니 defense in depth!!
한 가지 방법으로 공격을 막는 것 보다는 발생할 수 있는 여러 경우에 맞설 수 있는
하지만 서버에 올라간 뒤에 PHP file로 실행될 수 있도록 해야 한다..
즉, php.jpg 형태로 파일을 업로드 하면 PHP 확장자를 차단하는 blacklist를 우회할 수 있다는 것!
검증 체제를 구현할 필요가 있다!!