BUUCTF靶场练习——第六周

[极客大挑战 2019]PHP

打开靶机,根据提示猜测本题应该是考察备份文件泄露的知识

题目经常需要进行代码审计,但是网站源码通常不会直接给,需要自己发现,实践中往往是开发者的疏忽而忘记删除备份文件,从而导致服务器中残留源码,而备份文件便是常见的源码泄露方式

在这里插入图片描述

常见的备份文件后缀名(备份文件基本上都是压缩包)

.rar
.zip
.7z
.tar.gz
.bak  --  对于bak类的备份文件,可以直接输入文件名称+.bak访问,如index.php.bak
.txt
.old
.temp
_index.html
.swp
.sql
.tgz
.tar

常见的备份文件名(不包含后缀)

web
website
backup
www
wwwroot
temp
db
data
code
test
admin
user
sql

常见的备份文件所在目录

/  --  根目录
/admin
/data
/default
/index
/login
/manage
/cmseditor
/db
/bbs
/phpadmin

用御剑可以扫出备份文件www.zip

在这里插入图片描述

访问之后可以下载网站的源代码

在这里插入图片描述

对源代码进行代码审计,修改源代码,将class.php文件中的usernamepassword进行修改,使其满足后面打印flag的条件判断语句,再将源代码文件夹复制到phpstudy的WWW目录下,开启phpstudy服务把代码跑起来,触发flag的输出

在这里插入图片描述

但是遇到问题403访问不了

在这里插入图片描述

在phpstudy管理网站——修改——高级配置——开启目录索引,进而可以顺利访问localhost(会显示phpstudy的WWW目录下的所有目录),进入www目录

在这里插入图片描述

但是发现访问class.php也还是没办法得到flag,此处还用到了burp抓取本地包,需要在浏览器访问about:config,修改network.proxy.allow_hijacking_localhosttrue

在这里插入图片描述

是代码审计的不够好吗,查看到index.php中有反序列化函数,或许涉及到反序列化知识,百度查看一下php反序列化的知识,发现class.php中的几个函数都是反序列化中常见的魔术方法

__wakeup()  --  执行unserialize()时,会先调用这个函数
__sleep()  --  执行serialize()时,会先调用这个函数
__construct  --  当一个对象创建时被调用
__destruct()  --  对象被销毁时触发
__call()  --  在对象上下文中调用不可访问的方法时触发
__callStatic()  --  在静态上下文中调用不可访问的方法时触发
__get()  --  用于从不可访问的属性读取数据或者不存在这个键都会调用此方法
__set()  --  用于将数据写入不可访问的属性
__isset()  --  在不可访问的属性上调用isset()或empty()触发
__unset()  --  在不可访问的属性上使用unset()时触发
__toString()  --  把类当作字符串使用时触发
__invoke()  --  当尝试将对象调用为函数时触发

序列化是将变量或对象转换成字符串的过程,用于在存储或传递PHP的值的过程中,同时不丢失其类型和结构;而反序列化就是将字符串转换成变量或对象的过程;通过序列化与反序列化我们可以很方便的在PHP中进行对象的传递,本质上反序列化是没有危害的,但是如果用户对数据可控那就可以利用反序列化构造payload进行攻击

魔术方法是一种特殊方法,当对对象执行某些操作时会覆盖PHP的默认操作

发现该题与[SWPUCTF 2021 新生赛]ez_unserialize题目类似,根据该题目的解答,需要先编写一个序列化Name类的php代码,并通过php进行解析执行,这里编写php代码如下

<?php
<?php
class Name{
    private $username = 'admin';
    private $password = '100';

    public function __construct($username,$password){
        $this->username = $username;
        $this->password = $password;
    }
}
$a=new Name();
echo serialize($a);
?>

将该代码保存到phpstudy的根目录下进行访问,可以在浏览器得到序列化后的数据为:O:4:"Name":2:{s:14:"Nameusername";N;s:14:"Namepassword";N;}

在这里插入图片描述

将该数据作为index.php中的select参数值进行传递,可以发现页面打印了flag.php中的flag的值,为啥不是flag?

在这里插入图片描述

目前存在疑问的点:

  1. 将序列化数据作为参数传递为什么得不到flag
  2. 不太懂参数传递进去之后的处理过程,为啥传递参数就会输出,此时修改class.php中对于private类型的$username$password变量,会根据if判断打印出相关信息;而不传递参数时,不管class.php中private类型的$username$password变量设置什么,下方的if都不会输出东西

看下大佬的wp,学习一下

发现本题有多个知识点

  1. php反序列化的魔术方法什么时候会执行,如前面所介绍
  2. __destruct()方法执行会先执行__wakeup()方法,需要绕过__wakeup()方法,利用cve漏洞:当成员属性数目大于实际数目时可绕过__wakeup()方法
  3. 可以通过php脚本生成序列化数据,也可以通过序列化的语法规则手动构造一个序列化数据

序列化语法规则:对象类型:长度:“类名”:类中变量的个数:{类型:长度:“值”;类型:长度:“值”;…}

在这里插入图片描述

  1. private声明的字段为私有字段,只在所声明的类中可见,在该类的子类和该类的对象实例中均不可见,因此私有字段的字段名在序列化时,类名和字段名前面都会加上\0%00的前缀,字符串长度也包括所加前缀的长度

综上,手动构造出来的序列化数据为O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;},使用以下php代码同样可以得到序列化数据,但是需要将口字修改成%00,即在类名和字段名前都加上%00

<?php
class Name{
    private $username = 'admin';
    private $password = '100';

    public function __construct($username,$password){
        $this->username = $username;
        $this->password = $password;
    }
}
$a=new Name('admin', '100');
echo serialize($a);
?>

将生成的序列化数据作为index.php文件的select参数传入,得到flag{797b6f05-8c8c-4973-9456-0519f049fa03}

在这里插入图片描述

总结:

针对前面两个疑问,首先前面产生序列化数据的php代码并不正确,其次也没有在类名和字段名前加%00,后面尝试以上的修正之后,发现还是没办法给出真实的flag,应该是Syc函数的问题,可能会调用系统本地的资源从而打印出flag的真实的值,而将源代码在本地进行部署,我们没有那样的环境,因此无法打印出flag的真实的值

针对第二个问题,即使修改了源代码中__construct()函数中$usernmae$password的值,也没办法打印flag的,因为__construct()函数是当一个对象创建时才会被调用,而源代码中并没有serialize函数,因此是不会调用__construct()函数的,这也是为什么需要自己编写php生成序列化数据代码或者自己手动构建序列化数据的原因

  1. 学习了php反序列化的原理并了解了魔术方法的调用条件以及序列化数据的语法构建规则
  2. 不能将源代码放在本地搭建环境再通过修改源代码的形式拿flag,因为本地可能不存在某些远程才有的资源
  3. 学习了phpstudy访问网站403的解决方案,需要开启目录索引功能
  4. 学习了burp如何抓取本地包,需要修改about:confignetwork.proxy.allow_hijacking_localhosttrue
  5. 了解了__wakeup()函数的绕过方式以及private声明的字段在生成序列化数据时需要添加%00
  6. 了解了ctf的web解题的两个固定姿势:查看网页源代码和进行代码审计(备份文件泄露源码)

[ACTF2020 新生赛]BackupFile

从题目名称可以猜测应该是一道和备份文件泄露相关的题目,打开靶机提示尝试找到源文件,从上题可知常见的备份文件名及其后缀,这里使用了先知社区提供的一款扫描器,该扫描器的扫描更倾向于ctf中的扫描,即更倾向于扫描一些备份文件,此外可以设置包含比赛名称相关的关键字,项目地址在这里,但是工具很老了,且好像没有维护了,不过用来简单扫描还是可以的

在ctf-scan目录下打开cmd,执行python ctf-wscan.py http://1d8e8f5c-041f-4308-99d1-6708dab16bf1.node4.buuoj.cn:81开启扫描,扫描结果如下

在这里插入图片描述

发现存在index.php.bak文件,访问可以下载得到网站的源代码如下

<?php
include_once "flag.php";

if(isset($_GET['key'])) {
    $key = $_GET['key'];
    if(!is_numeric($key)) {
        exit("Just num!");
    }
    $key = intval($key);
    $str = "123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3";
    if($key == $str) {
        echo $flag;
    }
}
else {
    echo "Try to find out source file!";
}

进行代码审计,可以发现其包含了flag.php文件,并且在第三个if中若满足条件则会打印flag,要满足条件需要

  1. 设置key参数
  2. key参数需要为数字
  3. key参数值要能和$str字符串进行弱比较为true

php类型比较

  1. ==:弱类型比较,只比较值,不比较类型,即会将两种字符类型转换成相同再进行比较
    关于类型转换,当一个字符串被当作一个数值来取值时,若该字符串没有包含’.‘、’,'、‘e’,‘E’,并且其数值值在整形范围内,则该字符串会被当作int来取值,其他情况下都会被当作float来取值,该字符串的开头部分决定了它的值,若该字符串以合法的数值开始,则使用该数值,否则其值为0;即字符串admin1转换成int类型为0,字符串1admin转换成int类型为1
  2. ===:强类型比较,既比较值也比较类型,即在比较前会先判断两种字符类型是否相同再进行比较

构造访问key=123,得到flag{d269ad02-45d5-4cc7-b69d-7438d292b5b8}

在这里插入图片描述

总结:

  1. 使用ctf-scan工具进行扫描,能更加针对性的扫描备份文件
  2. php类型比较存在弱比较和强比较,弱比较会将不同的类型转换成相同的类型再进行比较,强比较会先比较类型

参考文章

  1. NSSCTF ez_unserialize. CSDN. Available at here. Accessed: 19 August 2023.
  2. PHP反序列化学习总结(新手入门). 知乎. Available at here. Accessed: 19 August 2023.
  3. [极客大挑战 2019]PHP. 知乎. Available at here. Accessed: 20 August 2023.
  4. CTF——Web网站备份源码泄露. CSDN. Available at here. Accessed: 20 August 2023.
  5. 一个为CTF而生的扫描器. 先知社区. Available at here. Accessed: 20 August 2023.
  6. PHP 类型比较. 菜鸟教程. Available at here. Accessed: 20 August 2023.
  7. php 弱类型总结. 博客园. Available at here. Accessed: 20 August 2023.
  8. BurpSuite抓本地包. CSDN. Available at here. Accessed: 27 August 2023.
回答: Vulhub靶场是一个用于漏洞学习和实践的平台,提供了各种常见漏洞的环境供用户进行实验和学习。在Vulhub靶场中,你可以学习和实践Apache换行解析漏洞(CVE-2017-15715)、Apache多后缀解析漏洞(apache_parsing_vulnerability)以及Apache ssl远程命令执行漏洞(ssi-rce)等漏洞。这些漏洞都有相应的漏洞描述、漏洞原理和漏洞利用方法。其中,Apache换行解析漏洞是指通过利用Apache服务器对换行符的解析不当,导致攻击者可以执行任意命令。Apache多后缀解析漏洞是指Apache服务器对文件后缀解析不当,导致攻击者可以执行任意代码。Apache ssl远程命令执行漏洞是指Apache服务器在处理SSI(Server Side Includes)时存在远程命令执行漏洞。在Vulhub靶场中,你可以通过写入webshell、写入cron或ssh key等文件以及写入jar或jetty.xml等库和配置文件等方法来利用这些漏洞。具体的操作方法可以参考相关的参考资料。 #### 引用[.reference_title] - *1* [vulhub靶场练习——Apache换行解析、多后缀解析、以及ssl远程命令执行漏洞分析](https://blog.csdn.net/qq_38632151/article/details/103287260)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [vulhub靶场练习 CVE-2016-3088 —— ActiveMQ任意文件写入漏洞](https://blog.csdn.net/qq_38632151/article/details/102975086)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值