背景
近期,F5 官方爆出BIG-IP 中存在一个高危格式化字符串漏洞 (CVE-2023-22374),可导致认证攻击者触发拒绝服务条件并可能执行任意代码。由于该高危漏洞是格式化字符串漏洞,且相比于其它漏洞平时不常见到,本小节便对该漏洞进行简单分析。
受CVE-2023-22374影响的版本有:
BIG-IP:17.0.0
BIG-IP:16.1.2.2 - 16.1.3
BIG-IP:15.1.5.1 - 15.1.8
BIG-IP:14.1.4.6 - 14.1.5
BIG-IP:13.1.5
漏洞原理
从CVE发布的信息中,我们可以得知该漏洞是格式化字符串漏洞。格式化字符串漏洞是C语言标准库中的格式化输出函数的内在漏洞(如:printf,fprintf,sprintf,snprintf等函数),格式化输出函数格式是根据传入格式化字符串参数进行解析的,当开发者不留意格式化输出函数的参数控制,导致格式化输出函数执行时解析错误的参数形成漏洞。简单来说格式化字符串漏洞造成的原因就是格式字符串函数要求的参数和提供的参数不匹配。化字符串漏洞攻击可造成程序崩溃、程序信息数据窃取、程序内存修改、获取执行权限等等。
以一个简单程序为例。下图中,假设程序开发者定义了变量a,b,c。程序开发者在使用printf进行格式化输出时,不小心丢掉了参数c,但是格式化输出函数printf并不会检测开发者是否丢掉了参数,并且按照程序执行逻辑进行正常解析,就导致了printf函数将栈上的其他数据给泄露了出来(32位程序的参数存放在栈中。当传入参数有误时,printf会误认为将其他数据作为格式化参数进行输出)。
上图中只是一个简单的示例,大多数开发者都会察觉到,但是实例中出现的漏洞,并不会像上面那么明显。当开发者将用户输入数据存储至申请的变量时,以为用户会用字符串进行输入,但是攻击者输入带有特殊含义字符串进行输入时,此时的函数变成了printf("aaaa.%x.%x.%x.%x.%x."),后面程序执行时就像上面的例子效果一样(printf误认为后面有5个格式化参数),导致了printf函数将栈上的其他数据泄露了出来。
注意:由于保存字符串的变量在栈空间中,攻击者可以输入"xxxxyyyy%Nc%N$n.%Nc%N$n.."(N为整数,N$:获取格式化字符串中的指定参数)进行地址写入获取执行权限,或输入"%s.%s.%s.%s.%s..."(printf函数中,%s期望赋予一个存储地址,并打印输出在此地址中存储的数据。栈空间中有许多非存储地址,当使用%s进行访问时,由于是非法地址,程序直接崩溃)使程序崩溃。
%后面可加参数部分解释为:
d/i,有符号整数
u,无符号整数
x/X,16 进制 unsigned int 。x 使用小写字母;X 使用大写字母.
s,输出以null 结尾字符串直到精度规定的上限;如果没有指定精度,则输出所有字节。
c,把 int 参数转为 unsigned char 型输出
p, void * 型,输出对应变量的值。printf("%p",a) 用地址的格式打印变量 a 的值,printf("%p", &a) 打印变量 a 所在的地址。
n,不输出字符,但是把已经成功输出的字符个数写入对应的整型指针参数所指的变量。
知道了格式化字符串漏洞的原理后,我们便可以对CVE-2023-22374进行简单分析。
漏洞分析
本小节中,在靶场环境中调用本小节使用的漏洞环境:BIG-IP 15.1.5.1。
在为BIG-IP靶标设置好IP地址后,BIG-IP会自动分配出相同的mgmt IP地址。
CVE信息中表明在bip-ip受影响的版本中,格式化字符串漏洞出现在iControl SOAP服务中,并且该漏洞可以将iControl SOAP CGI服务崩溃或可能远程代码执行。在前面的小节分析CVE-2022-41622时,我们已经分析了此程序(当时并未详细说明)。我们可以在F5官方网站中查看iControl SOAP的说明,如下图所示,iControl SOAP 是一个开放的 API,使用 SOAP/XML 格式的信息进行通信。当用户通过WSDL来访问"/iControl/iControlPortal.cgi"路径的cgi服务后,我们可以通过查看/var/log/ltm中的日志信息来查看用户启动的 SOAP API 调用记录。由此可知当我们对iControlPortal.cgi进行攻击时,可以在"/var/log/ltm"文件中观察到执行结果。
CVE-2023-22374漏洞产生的位置位于“_vsyslog_chk”函数中,当传入的第二个参数a2为-1时,程序进入vfprintf函数的执行流程。在函数处理时,a3参数可由用户控制,且没有进行字符串过滤,导致用户可输入带有特殊含义字符串从而被vfprintf函数格式化输出。
对"_syslog_chk"函数按"x"交叉引用,可以查看到在syslog函数中调用了"_syslog_chk"函数。并且"_syslog_chk"函数的参数a2为-1,a3参数由syslog的a2参数传入。
syslog函数由“/usr/local/www/iControl/iControlPortal.cgi"程序的"PortalDispatch::HandleWSDLRequest"函数被调用。
在下面的动态调试中,我们将观察到从用户输入带有特殊含义字符串到漏洞触发详细的流程。
调试过程如下,首先需要将要调试的“/usr/local/www/iControl/iControlPortal.cgi"程序和其所需的lib库拷贝到本地。这里可以使用“ldd 程序名”查看程序所需动态库,下图中,"/lib"目录软连接到了"/usr/lib"目录,所以改程序所有的动态库都位于"/usr/lib"目录下。
使用scp命令将“/usr/local/www/iControl/iControlPortal.cgi"和"/usr/lib/*"文件拷贝到本地,并在big ip中传入gdbserver对iControlPortal.cgi进程进行attach。
使用gdb对iControlPortal.cgi程序进行远程调试,在PortalDispatch::HandleWSDLRequest函数处断点,并设置好lib库目录后,使用"target remote ip:port"进行连接调试。程序自动断下来后,输入c运行,随后发送poc。
程序断在了我们的断点处,随后接着往下调试。下图中程序获取QUERY_STRING环境变量参数的值,这里eax即获取到的值,可以看到我们传入的poc。
使用hex命令查看地址里面对应的内容。
随后获取"CONTENT_LENGTH"和"SCRIPT_NAME"环境变量的值。
程序进入循环,程序使用strchr搜索QUERY_STRING环境变量参数的值中第一次出现"."符号的位置,并判断"."后面的字符是否存在大于"0x2f",随后结束循环。
紧接着,程序将“query: WSDL=ASM.LoggingProfile:%x:%x:%x:%x:%x:%x:%x:%x:%x::%x:%x:%x%x:”作为第二个参数传入syslog函数。
随后在syslog函数里面调用了"__syslog_chk"函数,“query: WSDL=ASM.LoggingProfile:%x:%x:%x:%x:%x:%x:%x:%x:%x::%x:%x:%x%x:”字符串作为第三个参数传入。
在"__syslog_chk"函数中,使用vfprintf将格式化字符串的结果输入到open_memstream函数申请的内存流(内存流可根据需求自动增长)中。这里vfprintf在格式化字符串时产生了漏洞。
随后,程序调用send函数将日志输出到/var/log/ltm文件中。此条汇编执行完成后,我们可在“/var/log/ltm”文件观看到本地poc攻击结果。
几乎所有的wsdl都可以触发该漏洞,下图为LocalLB.VirtualServer poc攻击后,漏洞触发处的参数情况。
同理,所有的wsdl被攻击后的日志信息也会send到/var/log/ltm文件中。
漏洞复现
根据调试可知该漏洞为堆上的格式化字符串漏洞,堆中格式化字符串漏洞的利用步骤一般都是先泄露地址信息,包括ELF的地址和libc的地址。由于是堆上的格式化字符串漏洞,参数不在栈上,所以无法根据参数进行任意地址写入。这时就需要查找栈上的数据分布情况,理想的状况下需要三个指针p1、p2、p3,形成p1指向p2、p2指向p3(p3为返回地址位置)的情况,这时我们可以先利用p1修改p2的最低字节,可以使p2指向p3指针8字节中的任意1字节并修改它,这样可以逐字节地修改p3成为one_gadget的地址就可以获得shell。在CVE-2023-22374的远程代码执行漏洞利用方面,攻击者无法看到日志文件中的泄露信息也就无法泄露程序的地址信息,调试过程中栈上的空间分布并没有出现理想中的结果(即p3为_vsyslog_chk函数的返回地址或PortalDispatch::HandleWSDLRequest函数的返回地址),并且如果想要多次写入,由于aslr的存在重新写入时地址会改变,所以想要获取远程代码执行权限还是比较困难的(不排除大佬有其他方式或程序出现的特殊状况)。
而在拒绝服务攻击方面,格式化字符串漏洞利用较为简单,只需要将poc改为"%s%s%s%s%s%s%s%s"就可以使得程序崩溃。
总结
在这一小节中,我们学习格式化字符串漏洞,以及简单分析了格式化字符串漏洞产生的过程。同时,我们了解了发生在堆上的格式化字符串漏洞的简答分析流程,虽然CVE-2023-22374漏洞在实际利用情况比较鸡肋,但是对我们研究学习非常有帮助。