[Web] Inject Malicious Code to PHP-GD Image
: 취약점 진단을 수행하다도면, 악성스크립트 업로드 시 확장자 변조까지는 가능하지만 악성 스크립트의 내용이 제거되어 exploit이 불가능한 경우가 있습니다. 이러한 경우, PHP-GD lib 함수를 통해 이미지가 재생성될 가능성이 존재하게 됩니다. 개발자분들은 FIleUpload 취약점을 대응하기 위해 PHP 환경에서는 PHP-GD lib 내 getimagesize() 및 imagecreatefromgif() 함수를 사용하기도 합니다. 해당 게시글에서는 이를 우회하는 방법에 대해 기술할 것입니다.
01___What is PHP-GD ?
: PHP-GD는 PHP의 라이브러리 중 하나로, GIF , PNG , JPEG , WBMP 및 XPM을포함하여 다양한 이미지 형식으로 이미지 파일을 재생성하고, EXIF 헤더값에 저장된 메타데이터를 읽을 수 있습니다.
해당 라이브러리는 파일 업로드 취약점을 방어하기위해서 종종 사용되기도 합니다.
(이미지 재생성을 통한 악성 스크립트와 같은 불필요한 파일내용 제거)
02___Example PHP-GD lib
대표적으로 사용되는 함수로는 imagecreatefromgif(), imagecreatefromjpeg() 입니다.
EXIF 메타 데이터에 악성 스크립트 삽입 후 파일 업로드 시 imagecreatefromjpeg(), imagecreatefromgif()를 사용하게되면 이미지 재생성 시 EXIF 메타 데이터 영역에 삽입되었던 악성 스크립트가 제거됨을 확인할 수 있습니다.
이를 우회하기 위해서 가장 먼저 생각해볼 수 있는 건, EXIF 메타 데이터 영역이 아닌 이미지 데이터 영역 자체나 그 외의 영역에 악성 스크립트를 삽입해 볼 수 있다는 것입니다.
03___How to Bypass PHP-GD lib
https://secgeek.net/bookfresh-vulnerability/
Case 1) imagecreatefromgif() bypass
imagecreatefromgif() 함수가 적용되어 있을 경우라고 가정해봅시다.
이를 우회하기 위해서는 php-gd를 직접 사용하여 변환하기 전 gif 이미지와 변환 후 gif 이미지의 내용을 비교하여 내용이 변하지 않은 유사한 부분을 찾아 RCE를 삽입하면 될 것입니다.
코딩을 하여 두 파일 내용 내 유사한 부분인 "3b45d00ceade0c1a3f0e18aff1" 찾을 수 있었고, 이 곳에 간단한 스크립트 작성( "<? phpinfo() ?>" )을 시도합니다.
PHP 코드가 성공적으로 실행되었음을 확인할 수 있습니다.
More detail) imagecreatefromgif() bypass
php-gd lib을 조금 더 살펴보면서 이미지에 페이로드를 몇 바이트 넣을 수 있는지 테스트해봅시다.
.jpg 이미지에는 최대 13바이트 페이로드를 삽입할 수 있었지만, .gif 이미지에는 더 많은 바이트를 삽입할 수 있습니다.
주입될 수 있는 GIF이미지는 널 바이트 블록이 있는 GIF 이미지이다.
Netscape Looping Application Extension이 있는 GIF 이미지에는 널 바이트 블록이 있다.
Netscape Looping Application Extension은 가장 널리 사용되는 Application Extension Block으로, 브라우저 나 다른 GIF 뷰어가 애니메이션 GIF 파일 전체를 반복하도록합니다.
Netscape Looping Application Extension https://media2.giphy.com/media/6NjZoOdEbXs1W/source.gif 가있는 예제 GIF 이미지입니다.
php-gd로 GIF 이미지를 재생성하면 NULL 바이트 블록이 제거되지 않음을 확인할 수 있습니다.
해당 널 바이트에 페이로드 삽입 시 결과는 아래와 같습니다.
대상 앱에 RCE 페이로드 삽입 시 임의의 명령어를 실행시킬 수 있습니다.
아래의 영상은 해당 취약점의 데모영상입니다.
exploit을 편하게 진행하기 위한 도구들이 있습니다.
1) imagecreatefromgif() 우회를 위한 인젝터
https://gist.github.com/asdqwe3124/e63eba35dc8e6976af97f1a9348b277b
2) imagecreatefromjpeg() 우회를 위한 인젝터
https://github.com/dlegs/php-jpeg-injector
how to use.
python gd-jpeg.py [JPEG] [PAYLOAD] [OUTPUT] |
e.g. python gd-jpeg.py cat.jpeg infected_cat.jpeg
example.
1. php gd lib을 사용하여 이미지 재생성
$ PHP gd.php image.jpg image-gd.jpg
2. dlegs 도구를 사용하여 페이로드를 .jpg 이미지에 삽입
$ python gd-jpeg.py image-gd.jpg '<? php phpinfo ()?>'image-gd-poc.jpg
3. 주입 된 페이로드가 작동하는지 확인하기위해 php-gd로 image-gd-poc.jpg 재생성
$ PHP gd.php image-gd-poc.jpg image-gd-poc-1.jpg
4. vbindiff를 이용해 image-gd-poc.jpg / image-gd-poc-1.jpg비교
$ vbindiff image-gd-poc.jpg 이미지 gd-poc-1.jpg
** 주의사항
대상 앱이 기본 품질 (기본값 -1)로 이미지를 다시 만드는 경우에만 작동합니다. 그러나 대상 앱에서 이미지를 품질 90으로 변환한다면 이미지에 삽입 된 페이로드가 제거됩니다.
how it works.
Reference.
https://jb-skin-131.tistory.com/31
https://github.com/fakhrizulkifli/Defeating-PHP-GD-imagecreatefromjpeg
https://secgeek.net/bookfresh-vulnerability/
https://github.com/dlegs/php-jpeg-injector
http://www.vurdalakov.net/misc/gif/netscape-looping-application-extension
https://extbrain.tistory.com/21
[WEB] Bypass XSS(Quotation&apstrophe filtering) with JS Regular expression (0) | 2020.05.29 |
---|---|
[Web/Mobile] 코로나19관련 화상회의 시 보안 고려사항(금융보안원 기준) (0) | 2020.04.12 |
[Web] XSS WAF&character limitation bypass (0) | 2020.04.07 |
[Proxy] Ultrasurf Setting (0) | 2020.03.26 |
[보안이슈] OAuth Misconfiguration(4) : 취약점 사례(Convert Redirect) (0) | 2020.03.10 |