[NSSCTF Round #13]部分题目复现
[NSSCTF Round #13]部分题目复现
拖了n久的产物,还有一道TimeTrcer暂时没写没后续补上。
[NSSRound#13 Basic]flask?jwt?
每个功能点进去看下,发现重置密码这里有hint,
1 | |

Flask 通常指的是 Python 的一个轻量级 Web 框架,用来快速构建网站或接口。
在安全或 CTF 环境中,说“Flask题”“flask相关漏洞”一般是指:
- Jinja2 模板注入(SSTI)
Flask 默认使用 Jinja2 作为模板引擎,如果开发者写了诸如:
1 | |
就会导致用户可控输入被直接当成模板渲染,从而造成 Server-Side Template Injection(SSTI)。
攻击者可以利用它执行任意 Python 代码(比如 {{ config.__class__.__init__.__globals__['os'].popen('ls').read() }})。
- Flask Debug Pin 反序列化 / 控制台利用
如果应用启用了调试模式 app.run(debug=True),那么攻击者可以尝试通过 Debug PIN 获取交互式控制台,直接执行代码。
- Session 伪造
Flask 默认使用签名 cookie 存储 session 数据,如果开发者使用默认 app.secret_key 或者泄露了它,就可以伪造任意 session 内容。
- Pickle 反序列化
某些 Flask 题会在 session 或上传点中利用 pickle.loads() 反序列化对象,形成命令执行漏洞。
注册完账号登陆一下,有个getflag的按钮

点击提示用户权限不足,基本确定是session伪造,

现在的session:
1 | |
先解码jwt:
1 | |
解码后:
1 | |
修改一下_user_id属性,猜测admin的_user_id是1
1 | |
得到伪造好的session:
1 | |
修改session拿到flag:

[NSSRound#13 Basic]ez_factors
题目描述
原生 Linux 因数爆破工具。flag在根目录
容易看出,2 31 1847是114514的因数,

网址后面/factors/114514使用分号;来执行多个命令,
1 | |
记得进行url编码。

发现得到的内容只有数字,看来应该是对回显进行了限制,只能回显数字,
这种情况下,我们可以使用od命令来读取文件
od -t d1 /flag 是一个命令行指令,用于以十进制形式显示 /flag 文件的内容。
具体来说-t 参数用于指定展示的数据格式,d1 表示每个数值使用一个字节来显示,即按字节读取。
/flag 是文件的路径,这个指令会读取 /flag 文件的内容,并将其以十进制形式进行展示。

把这些十进制数字依次转成 ASCII 字符再拼起来,就是:
1 | |
[NSSRound#13 Basic]flask?jwt?(hard)
在拿flag这个界面有一个路由,我们访问一下,

给了上一次登录的时间。

我们用Flask-Unsign对cookie进行解密,
发现刚好cookie里有对应正确的时间,随意修改session查看报错,可以在这查到secret_key是hardgam3_C0u1d_u_f1ndM3????
1 | |
然后利用flask_session_cookie_manager3来伪造session,使_user_id的值变成1
1 | |
payload:
1 | |
得到flag:

[NSSRound#13 Basic]MyWeb
源代码:
1 | |
接受mode参数,参数值为save为保存模式:
- 从
/tmp/data.json文件读取原有内容(假设是一个数组格式,如['a', 'b'])。 - 获取 URL 参数
value,例如?mode=save&value=hello。 - 用
addslashes()处理(转义引号等),防止字符串破坏结构。 - 用
str_replace()在]前插入新值,形成新的“数组”。 - 再次写回文件。
例如,data,json的内容为:
1 | |
然后将value值为6666,执行代码后,data.json中的内容就变为:
1 | |
自然想到可以利用sql注入的思路,在json中注释符为//,所以将value的值变为]//,那么后面的代码就会被注释掉。
1 | |
再看后续read模式会把/tmp/data.json中内容读取然后带着php代码执行,所以我们可以利用这一点来进行RCE。
以下为read模式过程解释:
mode参数值为read为读取模式
- 从文件读取内容(如
['apple', 'banana'])。 - 使用
eval()把字符串当作 PHP 代码执行,相当于:
1 | |
- 然后输出数组内容。
我们还需要注意save模式中addslashes()函数的作用:
addslashes() 是 PHP 的内置函数,用来在字符串中为以下 4 个字符 自动添加反斜杠转义(backslash):
- 单引号
'->\' - 双引号
"->\" - 反斜杠
\->\\ - NUL 字符(ASCII 0,
"\0") ->\0
总结一下,我们需要先选择save模式,然后通过value传递payload,然后再选择read模式读取达到RCE。
接下来是编写payload的问题:为了能够使我们的payload能执行,我们先要闭合第一个]这里前面已经提到过,通过传递]//,之后\n换行在新的行中写要执行的php代码echo 'cat/flag'//
又因为addslashes()函数会把单引号转义,我们把'替换成反引号
1 | |
换行跟空格需要base64编码一下,最后得到的payload如下:
1 | |
最后?mode=read读取到flag

references
[NSSCTF Round #13]web专项赛wp_[nssround#13 basic]timetrcer-CSDN博客
Flask Session Cookie Manager 安装和配置指南-CSDN博客
[NSSRound#13 Basic]ez_factors - Magic水瓶 - 博客园
[NSSRound#13 Basic] 刷题记录_[nssround#13 basic]flask?jwt?(hard)-CSDN博客