CTF web sd培训 morning
web培训文档:(主要讲了popchain)
一、php反序列化漏洞以及popchain构造
popchain(称为):
函数的调用过程。
php语言:
1.$this->:你只要知道那是一个用来表示类内部的属性和方法的代号就好了!
2.对象 属性算对象么???我知道对象是一个类的实例化,那属性也是属性类的一个实例化 所以也是一个对象?
EXP:全称 ‘ Exploit ‘,
中文 ‘ 利用 ‘,指利用系统漏洞进行攻击的动作
RCE漏洞,可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统。
序列化与非序列化:
序列化 (serialize)是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。在PHP应用中,序列化和反序列化一般用做缓存,比如session缓存,cookie等
(人话:)
1.在php中有一个让对象睡觉的方法,叫searialize(),它会将对象的各属性序列化以方便保存起来,而unsearialize()方法是将保存的序列化的数据解开变成对象。也叫唤醒(猜测:类应该就是保存的序列化数据,当new一个对象时,unsearialize()被调用)
魔术函数:PHP中把以两个下划线__开头的方法称为魔术方法
__construct(),类的构造函数
__destruct(),类的析构函数
__call(),在对象中调用一个不可访问方法时调用
__callStatic(),用静态方式中调用一个不可访问方法时调用
__get(),获得一个类的成员变量时调用
__set(),设置一个类的成员变量时调用
__isset(),当对不可访问属性调用isset()或empty()时调用
__unset(),当对不可访问属性调用unset()时被调用。
__sleep(),执行serialize()时,先会调用这个函数
__wakeup(),执行unserialize()时,先会调用这个函数
__toString(),类被当成字符串时的回应方法
__invoke(),把对象当方法用的时候。此方法会被调用
__set_state(),调用var_export()导出类时,此静态方法会被调用。
__clone(),当对象复制完成时调用
__autoload(),尝试加载未定义的类
__debugInfo(),打印所需调试信息
1.PHP中__construct(),类的构造函数详解-php教程-PHP中文网
2.PHP中__destruct(),类的析构函数详解-php教程-PHP中文网
理解序列化的例题:
1 | class test |
实际调用语句:
序列化方法的返回是字符串
第一个测试:
1 | $test = new test;\\ |
运行结果:
ttt called! array(1) { [0]=> string(8) “arrgssss” } O:4:”test”:2:{s:10:”testflag”;s:9:”flag{233}”;s:1:”a”;s:3:”aaa”;} __destruct called!
第二个测试:
1 | $test = new test; |
运行结果:
O:4:”test”:2:{s:10:”testflag”;s:9:”flag{233}”;s:1:”a”;s:3:”aaa”;} //
__wakeup called! __destruct called! //unser效果 可能在程序运行释放 没错 php内存问题请查看总结PHP内存释放以及垃圾回收_php技巧_脚本之家 (jb51.net)
__destruct called!//是ser效果
第三个测试
1 | $test = new test; |
运行结果:
__toString called! __
destruct called!
第四个测试:
1 | $test = new test; |
运行结果:
ttt called! array(1) { [0]=> string(8) “arrgssss” } __destruct called!
popchain的构造:
php反序列化漏洞:
根本原因也是程序员写出来的。
通过写exp 触发方法,从而进行操作
PHP反序列化漏洞也叫PHP对象注入,漏洞的形成的根本原因是程序没有对用户输入的反序列化字符串进行检测,导致反序列化过程可以被恶意控制,进而造成代码执行、getshell等一系列不可控的后果。反序列化漏洞并不是PHP特有,也存在于Java、Python等语言之中,但其原理基本相通。
在魔术方法里面有system()或者eval()函数,里面的参数我们都是可控的
理解反序列化漏洞例题:
(29条消息) 漏洞复现篇——PHP反序列化漏洞_爱国小白帽-CSDN博客_php 反序列化漏洞
phpunlink函数:PHP unlink() 函数 (w3school.com.cn)
题目一:(1.php)
1.在反序列化popchain过程中,construct方法可以忽略。
代码分析:
1 | class Modifier { |
php语言@:
[PHP中的@符号有什么用-php教程-PHP中文网](https://www.php.cn/php-weizijiaocheng-414633.html#:~:text=at符号(%40)在PHP中用作错误控制操作符。 当表达式附加%40符号时,将忽略该表达式可能生成的错误消息。,如果启用了track_errors功能,则表达式生成的错误消息将保存在变量%24 php_errormsg中。)
思路分析:
1.从代码观察可以看出,没有可以直接利用的方法,
1 | public function __get($key){ |
看起来好像可以利用 但是$function();里面没有参数。
2.要做的是通过unserialize方法调用到比较危险的include($value)
结果:
所构造的pop链:
1 | // Show.__wakeup -> Show.toString -> Test.__get -> Modifier.__invoke |
1>首先先new一个show的对象,然后在反序列化的过程中会调用__wakeup这个方法.
2>
1 | public function __wakeup(){ |
这里在进行”/gopher|http|file|ftp|https|dict|../i”过滤之前,就已经将$this->source当作一个字符串来进行访问。
3>经验:
1 | public function __toString(){ |
1 | public function __get($key){ |
这里的get会对source进行一个获取,
而走到__get就会利用到这个点$function()。然后再走到invoke()
然后invoke()又会转到:
1 | protected $var;//可控的 |
然后就可以进行一个任意文件包含。
php的include()函数:PHP Include 文件 (w3school.com.cn)
编写的exp:(可以利用debug来)
popchain:
1 | // Show.__wakeup -> Show.toString -> Test.__get -> Modifier.__invoke |
1 | $a = new Show('flag.php'); // 初始化参数随便 |
DEBUG:
1 | class Modifier { |
php的数据类型: 对象 定义就是 public $var