php中异常原生类的应用
# 前言
php中原生类经常会带来一些意想不到的用法,想不出来怎么构造 pop 链或者没路可走的时候可以来看一看
一切的前提是开启报错的情况下
原理是利用了异常类的 __toString
# Error与Exception类的介绍
# Error 类
Error 是所有PHP内部错误类的基类,该类是在PHP 7.0.0 中开始引入的。
类摘要:
Error implements Throwable {
/* 属性 */
protected string $message ;
protected int $code ;
protected string $file ;
protected int $line ;
/* 方法 */
public __construct ( string $message = "" , int $code = 0 , Throwable $previous = null )
final public getMessage ( ) : string
final public getPrevious ( ) : Throwable
final public getCode ( ) : mixed
final public getFile ( ) : string
final public getLine ( ) : int
final public getTrace ( ) : array
final public getTraceAsString ( ) : string
public __toString ( ) : string
final private __clone ( ) : void
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
类属性:
- message:错误消息内容
- code:错误代码
- file:抛出错误的文件名
- line:抛出错误在该文件中的行数
类方法:
Error::__construct
(opens new window) — 初始化 error 对象Error::getMessage
(opens new window) — 获取错误信息Error::getPrevious
(opens new window) — 返回先前的 ThrowableError::getCode
(opens new window) — 获取错误代码Error::getFile
(opens new window) — 获取错误发生时的文件Error::getLine
(opens new window) — 获取错误发生时的行号Error::getTrace
(opens new window) — 获取调用栈(stack trace)Error::getTraceAsString
(opens new window) — 获取字符串形式的调用栈(stack trace)Error::__toString
(opens new window) — error 的字符串表达Error::__clone
(opens new window) — 克隆 error
# Exception 类
Exception 是所有异常的基类,该类是在PHP 5.0.0 中开始引入的。
类摘要:
Exception {
/* 属性 */
protected string $message ;
protected int $code ;
protected string $file ;
protected int $line ;
/* 方法 */
public __construct ( string $message = "" , int $code = 0 , Throwable $previous = null )
final public getMessage ( ) : string
final public getPrevious ( ) : Throwable
final public getCode ( ) : mixed
final public getFile ( ) : string
final public getLine ( ) : int
final public getTrace ( ) : array
final public getTraceAsString ( ) : string
public __toString ( ) : string
final private __clone ( ) : void
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
类属性:
- message:异常消息内容
- code:异常代码
- file:抛出异常的文件名
- line:抛出异常在该文件中的行号
类方法:
Exception::__construct
(opens new window) — 异常构造函数Exception::getMessage
(opens new window) — 获取异常消息内容Exception::getPrevious
(opens new window) — 返回异常链中的前一个异常Exception::getCode
(opens new window) — 获取异常代码Exception::getFile
(opens new window) — 创建异常时的程序文件名称Exception::getLine
(opens new window) — 获取创建的异常所在文件中的行号Exception::getTrace
(opens new window) — 获取异常追踪信息Exception::getTraceAsString
(opens new window) — 获取字符串类型的异常追踪信息Exception::__toString
(opens new window) — 将异常对象转换为字符串Exception::__clone
(opens new window) — 异常克隆
# 绕过 hash 比较
2021蓝帽杯 jack and rose
class 这是一个class{
function 假装是个函数(){
if( ($this->var1 != $this->var2) && (md5($this->var1) === md5($this->var2)) && (sha1($this->var1)=== sha1($this->var2)) ){
eval($this->var1);
}
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
如题,平常如果遇到单纯的 md5 比较或者 sha1 用数组什么的绕就绕过去了,但是这种的在类中同时比较应该怎么办在比赛的时候卡了我很久
在这里,由于调用了md5和sha1函数,他们可以对一个类进行hash,并且会触发这个类的 __toString
方法。
eval
函数传入一个类对象时,也会触发这个类里的__toString
方法。
注意:这里的错误信息中是会包含行数的,所以需要这俩new在同一行才ok
# 进行 XSS
测试代码:
<?php
$a = unserialize($_GET['xss']);
echo $a;
1
2
3
2
3
POC:
<?php
$a = new Error("<script>alert('xss')</script>");
echo urlencode(serialize($a););
1
2
3
2
3
后续待补全...
上次更新: 2021/07/22, 19:41:50