点击read something,发现访问了百度
读到了源码
就是ssrf+flask
import re, random, uuid, urllib from flask import Flask, session, request app = Flask(__name__) random.seed(uuid.getnode()) app.config['SECRET_KEY'] = str(random.random() * 233) app.debug = True @ app.route('/') def index(): session['username'] = 'www-data' return 'Hello World! Read somethings' @ app.route('/read') def read(): try : url = request.args.get('url') m = re.findall('^file.*', url, re.IGNORECASE) n = re.findall('flag', url, re.IGNORECASE) if m or n: return 'No Hack' res = urllib.urlopen(url) return res.read() except Exception as ex: print str(ex) return 'no response' @ app.route('/flag') def flag(): if session and session['username'] == 'fuck': return open('/flag.txt').read() else: return 'Access denied' if __name__ == '__main__': app.run(debug=True, host="0.0.0.0")
session伪造
当session['username'] == 'fuck'
时可以得到flag。
知道了SECRET_KEY加密的方法是str(random.random() * 233)
而random.random()为Mac地址
注意:uuid.getnode()返回的值是Mac值的16进制形式,但是去掉了中间的冒号。
import random import uuid random.seed(0x0242ac029427) print(str(random.random()*233))
然后进行session解密
得到加密形式
开始加密
传参得到flag
第一次抓包的回显
这段代码是一个JavaScript代码块,它执行了以下操作:
- 注册一个按键事件监听器:当用户按下键盘上的键时,会触发该事件。如果按下的是键盘上的Esc键(键码为27),则阻止默认行为(防止页面跳转)并将窗口重定向到"/chase/"。
- 如果按下的不是Esc键,则调用die()函数。
- sleep(ms)函数定义了一个异步函数,它会暂停一段时间(以毫秒为单位)后再继续执行后续代码。这里的sleep函数会等待10秒钟(10000毫秒)。
- dietimer()函数是一个异步函数,它会异步地等待10秒钟后调用die()函数。
- die()函数将窗口重定向到"/die/"。
根据代码的逻辑,当用户按下Esc键时,会立即重定向到"/chase/",否则会等待10秒钟后重定向到"/die/"。
请注意,这段代码只是代码片段,并不能独立运行。它需要在适当的上下文中嵌入和调用才能正常工作。
后面就一直抓包,然后就有了一个flask.js然后进行拼接flag就ok
不知道考点到底是什么
访问一下
看到源码了,格式化一下
看到了源码
gpt的解释:
导入必要的模块和库:从Flask模块中导入Flask、request和make_response函数,以及其他一些必要的模块和库,如uuid和os。
创建Flask应用程序实例:通过实例化Flask类创建一个应用程序实例,将其赋值给变量"app"。
定义WAF函数:定义了一个名为"waf"的函数,用于实现一个基本的Web应用程序防火墙。在函数中,定义了一个黑名单字符串"black_list",用于过滤一些特定的字符。如果传入的参数"rce"中包含黑名单中的任何字符,则返回False,否则返回True。
定义路由和视图函数:通过使用"@app.route"装饰器来定义路由和视图函数。在"/"路径上定义了一个名为"index"的视图函数,用于处理GET请求。如果请求中包含名为"Ňśś"的参数,并且通过WAF检查,将执行"os.popen(nss)"来执行命令,并返回结果。否则,返回"waf"。
在"/source"路径上定义了一个名为"source"的视图函数,用于处理GET请求。该函数打开名为"app.py"的文件,并将其内容作为二进制数据返回。
启动应用程序:在代码的最后,通过调用"app.run"方法来启动应用程序,监听在0.0.0.0的主机上的8080端口。
逻辑很简单,传入一个参数,在os.popen()
处执行命令,这题的难点在于绕黑名单
black_list = '01233456789un/|{}*!;@#\n`~\'\"><=+-_ '
简单的flask框架,在./
的路由下存在GET参数,然后绕过waf过滤来命令执行
不难发现黑名单过滤了/
,这里用的是pwd构造出/
,然后结合存在app.py,我们用cp命令把/flag
复制到app.py里面
我们先看一下怎么利用pwd构造出/
首先pwd表示的是当前工作目录
那如果我们构造以下语句
cd ..&&cd ..&&pwd
我们要把flag复制到app.py,但是我们不知道当前目录是什么,所以多尝试看看需要几个cd ..
payload
?Ňśś=cp $(cd ..&&cd ..&&cd ..&&cd ..&&cd ..&&cd ..&&cd ..&&cd ..&&echo $(pwd)flag) app.py
被墙了
?Ňśś=cp%09%24(cd%09..%26%26cd%09..%26%26cd%09..%26%26cd%09..%26%26cd%09..%26%26cd%09..%26%26cd%09..%26%26cd%09..%26%26echo%09%24(pwd)flag)%09app.py
发现不是ssti注入
去查了一下csp
CSP绕过_script-src self unsafe-inline-CSDN博客
CSP的理解与绕过
Content Security Policy
(CSP)内容安全策略,是一个附加的安全层,有助于检测并缓解某些类型的攻击,包括跨站脚本(XSS)和数据注入攻击。它实质就是白名单制度,开发者明确告诉客户端,哪些外部资源可以加载和执行,哪些不可以。
CSP如何工作
通过响应包头(Response Header)实现:
Content-Security-policy: default-src 'self'; script-src 'self' allowed.com; img-src 'self' allowed.com; style-src 'self';
CSP指令
我们可以看出,有一部分是CSP中常用的配置参数指令,我们也是通过这些参数指令来控制引入源,下面列举说明:
script-src:外部脚本
style-src:样式表
img-src:图像
media-src:媒体文件(音频和视频)
font-src:字体文件
object-src:插件(比如 Flash)
child-src:框架
frame-ancestors:嵌入的外部资源(比如、
除了Content-Security-Policy,还有一个Content-Security-Policy-Report-Only字段,表示不执行限制选项,只是记录违反限制的行为。它必须与report-uri选项配合使用。
Content-Security-Policy-Report-Only: default-src 'self'; ...; report-uri /my_amazing_csp_report_parser;
CSP指令值
介绍完CSP的指令,下面介绍一下指令值,即允许或不允许的资源
*: 星号表示允许任何URL资源,没有限制;
self: 表示仅允许来自同源(相同协议、相同域名、相同端口)的资源被页面加载;
data:仅允许数据模式(如Base64编码的图片)方式加载资源;
none:不允许任何资源被加载;
unsafe-inline:允许使用内联资源,例如内联