ghostscript 命令注入漏洞分析

VSole2021-09-24 18:21:50

最近在网上看到一个关于ghostscript软件的一个poc生成脚本,看了下生成的poc感觉应该挺简单的,随手分析下,该漏洞目前在野。

漏洞信息

1、漏洞简述

• 漏洞名称:无

• 漏洞编号:无

• 漏洞类型:命令注入

• 漏洞影响:远程命令执行

• CVSS评分:无

• 利用难度:简单

• 基础权限:不需要

2、组件概述

ghostscript是一款图像浏览工具。ghostscript能够查看以及打印PS、EPS、PDF格式的文件。适用于Unix、Mac OS X、VMS、Windows、OS/2和Mac OS classic等操作系统的使用。

3、漏洞影响

Ghostscript9.50, 基于Ghostscript的三方库和工具。

其他版本不详,未测试。

漏洞复现

1、环境搭建

Ubuntu20.4

2、复现过程

a) 使用提供的poc生成脚本生成poc

python '/home/hua/桌面/IM-RCE-via-GhostScript-9.5.py' 'touch the_poc' '/home/hua/桌面/test.jpg'

b) 安装imagemagick

sudo apt install imagemagick-6.q16

c) 运行convert转换图片

convert test.jpg test.png

漏洞分析

根据流出的poc readme 得知该漏洞并不是直接由convert触发,而是convert调用了GhostScript, GhostScript触发了该漏洞。

先找到convert调用GhostScript的地方,并观察传递的命令行参数。

在linux系统中,调用其他进程的函数无非就system,execX,popen这几个函数,所以可以在libc中对这几个函数下断点。

一段操作后并未发现断点命中,怀疑可能是先fork然后在子进程中调用。果然命中。

根据栈回溯,找到调用fork函数的地方,并修改ip强制将ip指向子进程的空间中,找到了调用gs的地方。

传递的详细命令行参数如下

gs -sstdout=%stderr -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 -sDEVICE=pngalpha -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -r72x72 -g612x792 -dEPSCrop -sOutputFile=/tmp/magick-15565sSaJTfcgWCk7%d -f/tmp/magick-15565gqAGdyB3qGD9 -f/tmp/magick-15565RttrpTjPQ4Qb

其中最关键的参数是/tmp/magick-15565RttrpTjPQ4Qb指向的文件。

可以看到,我们传入的命令已经被写入到了其中。

手动执行上面的命令行测试。

/tmp/magick-15565RttrpTjPQ4Qb 是一个软连接,它指向/proc/self/fd/3, 由于进程不同所以需要将self替换为convert的进程id。

可以肯定该漏洞肯定是由GhostScript触发的。

现在来调试GhostScript,和前面的思路一样,既然是命令注入肯定逃不脱system、execX、popen系列的函数,所以还是在libc中将这些函数下断点等它来即可。

可以看到在popen函数中命中了断点,并且利用’;’来执行命令。

查了一下GhostScript是一个开源的软件,下载了一份源码看下具体的调用逻辑,但由于太过复杂,所以只是简单的分析了下来龙去脉。

这里有一个数据结构,应该是根据%pipe%这个字段来调用该数据结构中的函数指针进行解析。

pipe_fopen函数中调用了open_pipe函数指针。

open_pipe函数指针在pipe_init函数中初始化并赋值为fs_file_open_pipe。

fs_file_open_pipe函数中调用了popen函数,这里就是漏洞的触发点。

很明显,此处是将括号中的字符串当作文件名直接传递给了popen函数来进行执行,所以才导致该漏洞存在。 

另附poc生成脚本(可点击文末阅读原文前往下载附件)。

 

函数调用imagemagick漏洞
本作品采用《CC 协议》,转载必须注明作者和本文链接
概述在windows系统上,涉及到内核对象的功能函数,都需要从应用层权限转换到内核层权限,然后再执行想要的内核函数,最终将函数结果返回给应用层。本文就是用OpenProcess函数来观察函数从应用层到内核层的整体调用流程。OpenProcess函数,根据指定的进程ID,返回进程句柄。NTSTATUS Status; //保存函数执行状态。OBJECT_ATTRIBUTES Obja; //待打开对象的对象属性。HANDLE Handle; //存储打开的句柄。CLIENT_ID ClientId; //进程、线程ID. dwDesiredAccess, //预打开进程并获取对应的权限。ObjectNamePresent = ARGUMENT_PRESENT ; //判断对象名称是否为空
关于堆栈ShellCode操作:基础理论002-利用fs寄存器寻找当前程序dll的入口:从动态运行的程序中定位所需dll003-寻找大兵LoadLibraryA:从定位到的dll中寻找所需函数地址004-被截断的shellCode:加解密,解决shellCode的零字截断问题
反射式DLL注入实现
2022-05-13 15:59:21
反射式dll注入与常规dll注入类似,而不同的地方在于反射式dll注入技术自己实现了一个reflective loader()函数来代替LoadLibaryA()函数去加载dll,示意图如下图所示。蓝色的线表示与用常规dll注入相同的步骤,红框中的是reflective loader()函数行为,也是下面重点描述的地方。
漏洞发生的位置是在驱动文件Win32k.sys中的xxxHandleMenuMessage函数,产生的原因是没有对该函数中调用的xxxMNFindWindowFromPoint函数的返回值进行合法性验证,直接将其作为参数传递给后面的xxxSendMessage函数调用,从而造成了提权漏洞
Win32k组件最初的设计和编写是完全建立的用户层上的,但是微软在 Windows NT 4.0 的改变中将 Win32k.sys 作为改变的一部分而引入,用以提升图形绘制性能并减少 Windows 应用程序的内存需求。窗口管理器(User)和图形设备接口(GDI)在极大程度上被移出客户端/服务端运行时子系统(CSRSS)并被落实在它自身的一个内核模块中。
结构&拷贝与引用
2023-05-10 11:27:04
结构&拷贝与引用开始之前,我们约定数据块也叫插槽,也就是storage。storage是永久存储在区块链上的地方。Stack 的最大深度为 1024 个元素,支持 256 位的字长。结构当定义局部变量时,它存储在内存中,然后压入堆栈以执行。1024栈深简介EVM不是寄存器机而是堆栈机,所以所有的计算都在称为堆栈的数据区域上进行。1024 是一个非常保守的值,以尽可能安全EVM 的设计方式往往会使更大的堆栈变得无用。EVM 只能访问堆栈中前16个slot。
可是当我们开启了smap保护之后,内核态就没有办法访问用户态的数据,此时当我们再hijack tty_operation到我们的用户态时,我们的kernel就会panic,更别说劫持执行流到用户态上执行rop了。当我们调用msgsnd时,在linux内核中会调用do_msgsnd。
本篇针对该JS中的字符串混淆进行还原。字符串是如何混淆的解密方式想要对字符串反混淆就要先分析该样本是如何对字符串进行混淆的。而处于全局作用域的_0x1f1a68实际上也是对另一个函数的调用。
当线程从等待状态苏醒后,会自动检测自己得APC队列中是否存在APC过程。所以只需要将目标进程的线程的APC队列里面添加APC过程,当然为了提高命中率可以向进程的所有线程中添加APC过程。然后促使线程从休眠中恢复就可以实现APC注入。往线程APC队列添加APC,系统会产生一个软中断。第二个参数表示插入APC的线程句柄,要求线程句柄必须包含THREAD_SET_CONTEXT访问权限。第三个参数表示传递给执行函数的参数。如果直接传入shellcode不设置第三个函数,可以直接执行shellcode。
01高门槛,勿入在Cisco平台上有一个很有用的Traceback log功能,实时记录当前Code运行到特
VSole
网络安全专家