先拜读这篇文章。
https://www.ambionics.io/blog/iconv-cve-2024-2961-p1
翻译版
https://mp.weixin.qq.com/s/03Bq8iryo22Cme5QR0LqDw
原作者公开exp
https://github.com/ambionics/cnext-exploits
这篇文章讲了什么事呢?
首先是glibc中iconv()函数将一些数据转换成ISO-2022-CN-EXT格式时,会有1-3字节的溢出。这个漏洞存在了24年,所以是一个非常非常通杀的漏洞。但是,由于溢出字节太少,在其他程序上几乎没有成功的案例。然而在这篇文章中,原作者利用php的一些特性,使得它稳定pwn了php几乎所有版本。
linux环境测试这个漏洞
https://github.com/ambionics/cnext-exploits/blob/main/poc.c
可以发现是9个字节,正常来说应该是8个字节。
php跟这个漏洞有关系吗?我们曾经介绍过一个php文件包含,利用filter包含出任意内容的技巧。
https://mp.weixin.qq.com/s/ujxmyvRUaMN_rV7u5xZqtw
其中就大量使用了iconv进行编码转换,所以一个类似
echo file_get_contents($_GET['file']);
的代码,就可以利用
php://filter/convert.iconv.UTF-8.ISO-2022-CN-EXT/resource=
来触发这个漏洞!
当然,这离pwn PHP还差得远,但是既然有完整可控的file_get_contents,那么可以就直接读/proc/self/maps获得libc基地址和libc.so的绝对路径。然后再读libc.so,那么所有函数的真实地址全都能算出来了,劫持__malloc_hook(实际劫持的是custom_heap)就变得容易了很多。
原作者的pwn水平非常之高,还利用了很多技巧来布置他想要堆结构,关于pwn方面的知识我就不献丑了,大家读原文。
最终达到一个file_get_contents就稳定php RCE的地步,具体效果可以看原文章的视频。
想要复现,可以下载exp,只需要布置一个简单的环境即可。
<?php
$file = $_REQUEST['file'];
$data = file_get_contents($file);
echo "File contents: $data";
不过我在复现的时候发现原exp过不了filter检测,这里只需要将三处tf.random.string(50)改短成30即可。
那么仔细想一下这个漏洞可以用在哪些环境中。
1,file_get_contents($_GET['file']);
2,任意文件读取+getimagesize($_GET['file']);或者XXE等
3,绕disable_functions
先说前两种情况,这是即phar反序列化以来第二种RCE的办法!
第一种情况比较少见,但第二种情况还是有可能碰上的。但实战环境中往往传参不会那么单一,又或者需要session。这样原作者的exp由于封装了http请求,所以无法直接拿来打,这里需要修改一下,将生成payload的build_exploit_path()抽离出来。手动下载/proc/self/maps和libc.so,然后生成path去打。
第三种情况,既然漏洞触发是file_get_contents转pwn,那么用来绕绕disable_functions,就是理所当然的。这里可以手动下载目标的/proc/self/maps和libc.so,在自己本地环境生成payload打,也可以直接将exp.py移植成php。效果如下。
原文始发于微信公众号(珂技知识分享):我不允许还有人不知道最新php RCE