2022安洵杯web
前言
个人觉得赛题质量蛮好的,只是自己太菜了,花了很长时间都在琢磨第一道web,因为一些细节上的问题导致一直解不出来。赛后就找师傅的wp重新去复现一下,总结自己的问题,在此记录一下,以便日后复习。
badyphp(pop链,原生类打ssrf和文件读取)
打开题目就是源代码:
|
构造pop链思路:
B::__destruct->C::__toString->A::__invoke->C::uwant |
需要绕过wakeup函数,本题目是高版本的php,常规绕过不管用。细看这个代码:
$this->b = $this->k; |
我们让$b去指向A类中$a的地址,就可以覆盖掉$a本来的变量了。打一下payload去触发phpinfo();
师傅的wp使用fast destruct来绕过的,都行。
原链⼦:O:1:"B":3:{s:1:"a";O:1:"C":2:{s:1:"a";N;s:1:"c";O:1:"A":2:
{s:1:"a";i:0;s:1:"b";O:1:"C":2:
{s:1:"a";s:7:"phpinfo";s:1:"c";N;}}}s:1:"b";N;s:1:"k";N;}
经Fast Destruct过后的:O:1:"B":3:{s:1:"a";O:1:"C":2:
{s:1:"a";N;s:1:"c";O:1:"A":2:{s:1:"a";i:0;s:1:"b";O:1:"C":2:
{s:1:"a";s:7:"phpinfo";s:1:"c";N;}}}}}s:1:"b";N;s:1:"k";N;}
题目中还提示让我们访问flag.php,flag文件的php代码为
|
REMOTE_ADDR是无法伪造的,所以利用SoapClient类来打ssrf进去。另外可以new对象,我们可以利用原生类来读取flag。说起来很容易,但是怎么操作呢?
在主页面的php代码中我们是可以传session的,另外还有ini_set函数,我们可以控制修改php_ini的参数配置,没错,这里存在session反序列化漏洞。编写攻击ssrf的poc:
|
开始我们是不知道flag的文件名的,所以这一步之前,我们需要利用原生类加glob协议把flag文件名给找出来。更改处理器配置为php_serialize,并且将payload传入session中。
传进去之后它是储存在session中,然后我们再传一次,把SoapClient写进session中,为什么要这么做?我们将打ssrf的原生类写进session里了,能够满足反序列化的条件,但是我们还需要去触发SoapClient类里的__call方法才能真正达到效果。主页面php代码有回调函数:
call_user_func(array(reset($_SESSION), $this->a)); |
这个函数,若第一个参数是数组的话,数组的第一个键值会作为类名,剩下的键值作为方法名,来调用这些函数。两者我们都可控,需要利用这个点来触发__call方法。另外我们呢需要将处理器改为php。
那么接下来就利用我们构造的pop链来触发call方法了。exp为
|
本地访问flag.php时的PHPSESSID是我们自己设置的,触发call方法后原生类读取flag的内容储存在session中,但是我们需要修改PHPSESSID为自己设置的才能得到flag。
EZ_JS(hash扩展攻击)
打开题目是一个登录框,随便输入些什么登进去。在页面源码有注释,是JSFuck编码,放在游览器解码一下。
这个提示我真不懂是什么意思,看大师傅的wp根据js大写特性绕过,输入admın。同样的,在登录框界面也有注释,
哈希扩展攻击,没怎么了解过,先学会用工具,在这留个坑以后再学。在做题的时候,我对这个注释的理解还是有些偏差,用工具解出hash和密码,hash要添加在cookie里。注意要把\x修改为%
抓登录包,添加admin密码,修改cookie得到文件
访问这个文件直接得出flag了。why?看师傅的wp不是还有原型链污染嘛。
ezupload(file_get_contents与原生类)
是一个上传表单,可以上传php文件,试着上传一句话木马,发现不成功。我们上传phpinfo,可以上传,发现许多函数都被禁用了。
于是我就想怎么开始绕disable_functions了,然而却没什么思路。看了大师傅的wp,发现其实函数禁用的并不全。还有file_get_contents函数可以用,但是上传对上传包的内容有限制,进行字符串拼接绕过,当然也可以用十六进制绕过。
可以看到/etc/passwd的内容。
那么我们如何利用file_get_contents把flag给读出来。看了师傅的wp才知道还可以配合原生类来找到flag文件并且读取。真的强,我是想不到的。那么传入文件。
<?php echo ('fil'.'e_get_contents')(("/".(new DirectoryIterator("glob:///f?????????????"))));?> |
因为flag大都在根目录下,配合DirectoryIterator原生类并且利用glob协议找到flag文件名。本来想匹配f的,被过滤了。那就只能用?通配符一个个的匹配,最终在匹配13个问号得出flag。
结语
慢慢学习,慢慢积累。又是崇拜大师傅的一天~