php原生类-SplFileObject在CTF中的运用
2022-10-29 22:0:6 Author: 漏洞推送(查看原文) 阅读量:42 收藏

今天帮朋友遇到一道CTF题目

源码简化如下:

<?phperror_reporting(0);show_source(__FILE__);
$a = $_GET["a"];$b = $_GET["b"];$c = $_GET["c"];$d = $_GET["d"];$e = $_GET["e"];$f = $_GET["f"];$g = $_GET["g"];
if(preg_match("/Error|ArrayIterator|Exception/i", $a)) { die("hello");}
$class = new $a($b);$str1 = substr($class->$c(),$d,$e);$str2 = substr($class->$c(),$f,$g);$str1($str2);?>

这题以前曾经出现过,主要考点是对php原生类的利用,常规解法就是

$e = new Exception("systemid");echo $e->getMessage();

但是这题if(preg_match("/Error|ArrayIterator|Exception/i", $a)) {通过一个if来拦截了常用的这些原生类,这个就需要我们在这些类以外,再寻找一个符合条件的原生类,需要符合一下条件

1.php原生类

2.存在构造方法,参数为字符串或者数组

3.存在返回值为字符串的无参方法,并且内容可控

根据这个条件找到SplFileObject这个类

SplFileObject

该类可用来读取文件,这个类构造方法如下,只需要传入一个文件名即可

public __construct(    string $filename,    string $mode = "r",    bool $useIncludePath = false,    ?resource $context = null)

还存在一个current无参方法,可返回文件第一行内容

public current(): string|array|false

根据php源码,该类起码支持三种协议data,file,以及http协议

file协议就不考虑了,因为本地文件我们是不可控的。

data协议需要php.ini配置如下:

allow_url_fopen :onallow_url_include:on

要求较高,但是在配置的情况下,可通过如下方法利用

在allow_url_include为off的情况下,我们还可以通过http协议即可,控制返回内容

在内容可控之后就是第二个问题了,如何获得flag?

常规思路就是通过eval来实现一个一句话,例如

$a = "eval";$b = "phpinfo();";
$a($b);

但是你会发现

Fatal error: Uncaught Error: Call to undefined function eval() in /Users/k/Desktop/php/1.php:9

为什么因为php eval是一个语言结构,和echo一样不属于函数,同理就算你通过配置disable_functions也是禁用不了eval函数的。

这个时候自然而然就会想起eval的代替品assert,这是一个实打实的函数,但是不好意思php7中禁止了动态调用assert

Warning: Cannot call assert() with string argument dynamically in /Users/k/Desktop/php/1.php on line 8

尝试直接进行命令执行 sysmtem、exec等等执行了都没有成功。

执行命令没成功,尝试直接进行文件读取,使用show_source("/flag"),盲猜flag位置成功获得flag

扩展

通过这个类想到ctf题目中出现过的SoapClient这个class,这个类一般在sstf场景中利用。如果SoapClient该class被禁用了的话,也可以尝试用SplFileObject此类代替。


文章来源: http://mp.weixin.qq.com/s?__biz=MzU5MTExMjYwMA==&mid=2247485524&idx=1&sn=5c9048d0ba461fd94123bf3869c32ba5&chksm=fe32b8a3c94531b57062031121a7ed00065e4d62d878f683f03f7c2b84a9ef5d5dab0980efe8#rd
如有侵权请联系:admin#unsafe.sh