BUUCTF [De1CTF 2019] SSRF Me
BUUCTF [De1CTF 2019] SSRF Me
考点:
- Flask代码审计
- Python字符串拼接
Hint:
flag is in ./flag.txt
启动环境,给出了源码:
#! /usr/bin/env python
#encoding=utf-8from flask import Flask
from flask import request
import socket
import hashlib
import urllib
import sys
import os
import json
reload(sys)
sys.setdefaultencoding('latin1')app = Flask(__name__)secert_key = os.urandom(16)class Task:def __init__(self, action, param, sign, ip):#python得构造方法self.action = actionself.param = paramself.sign = signself.sandbox = md5(ip)if(not os.path.exists(self.sandbox)): #SandBox For Remote_Addros.mkdir(self.sandbox)def Exec(self):#定义的命令执行函数,此处调用了scan这个自定义的函数result = {}result['code'] = 500if (self.checkSign()):if "scan" in self.action:#action要写scantmpfile = open("./%s/result.txt" % self.sandbox, 'w')resp = scan(self.param) # 此处是文件读取得注入点if (resp == "Connection Timeout"):result['data'] = respelse:print resp #输出结果tmpfile.write(resp)tmpfile.close()result['code'] = 200if "read" in self.action:#action要加readf = open("./%s/result.txt" % self.sandbox, 'r')result['code'] = 200result['data'] = f.read()if result['code'] == 500:result['data'] = "Action Error"else:result['code'] = 500result['msg'] = "Sign Error"return resultdef checkSign(self):if (getSign(self.action, self.param) == self.sign): #!!!校验return Trueelse:return False#generate Sign For Action Scan.
@app.route("/geneSign", methods=['GET', 'POST']) # !!!这个路由用于测试
def geneSign():param = urllib.unquote(request.args.get("param", "")) action = "scan"return getSign(action, param)@app.route('/De1ta',methods=['GET','POST'])#这个路由是我萌得最终注入点
def challenge():action = urllib.unquote(request.cookies.get("action"))param = urllib.unquote(request.args.get("param", ""))sign = urllib.unquote(request.cookies.get("sign"))ip = request.remote_addrif(waf(param)):return "No Hacker!!!!"task = Task(action, param, sign, ip)return json.dumps(task.Exec())@app.route('/')#根目录路由,就是显示源代码得地方
def index():return open("code.txt","r").read()def scan(param):#这是用来扫目录得函数socket.setdefaulttimeout(1)try:return urllib.urlopen(param).read()[:50]except:return "Connection Timeout"def getSign(action, param):#!!!这个应该是本题关键点,此处注意顺序先是param后是actionreturn hashlib.md5(secert_key + param + action).hexdigest()def md5(content):return hashlib.md5(content).hexdigest()def waf(param):#这个waf比较没用好像check=param.strip().lower()if check.startswith("gopher") or check.startswith("file"):return Trueelse:return Falseif __name__ == '__main__':app.debug = Falseapp.run(host='0.0.0.0')
源码分析:
- 其为Flask中
route.py
文件的源码 - 其中
Task
类中,存在Exec()
函数
在/geneSign
路由中:
geneSign()
函数中:
urllib.unquote()
函数将传入的param
值进行URL解码- 调用
getSign()
函数
getSign()
函数中:
- 创建hash对象
- 将
secert_key
、param
、action
拼接后的内容进行md5加密
在/De1ta
路由中
challenge()
函数中:
- 通过GET方式传入参数
param
的值 - 在
cookie
中传入action
和sign
的值 - 获取
ip
的值 - 将参数
param
传入到waf()
函数中效验 - 创建
Task()
类 json.dumps()
转换为JSON
waf()
函数中:
- 先将
param
转换为小写 - 若以
gopher
作为开头,file
作为结尾,将返回为真
- 所以得使
waf()
函数返回为假
在/
路由中:
index()
函数返回code.txt
的内容,也就是当前源码
解题思路:
在/De1ta
页面通过GET方式传入参数param
的值,在cookie
中传入action
和sign
的值,在param
通过waf()
函数效验后,将创建Task
类。
创建Task
类后,执行Exec()
函数,首先进行getSign()
与传入sign
的效验,scan
将flag.txt
文件内容写入到result.txt
,在通过read
读取该文件。
为了满足传入的sign
值,我们可以根据路由/getSign
去得到正确的sign
值
def getSign(action, param):return hashlib.md5(secert_key + param + action).hexdigest()
其直接进行字符串拼接,由于action
的值在该函数中并不可控,我们又需要满足"read" in self.action
,所以将read
拼接在param
参数后,所以构造传参:
// GET
param=flag.txtread// Cookie
action=scan
传参后得到sign
的值:12af1d0a42ff2610495400c73b3cb79a
在/De1ta
页面构造最终payload:
// GET
?param=flag.txt// Cookie
action=readscan
sign=12af1d0a42ff2610495400c73b3cb79a
传参后得到flag:
BUUCTF [De1CTF 2019] SSRF Me相关推荐
- (Buuctf) [第五空间2019 决赛]PWN5 简单格式化字符串漏洞利用
这题是个基本格式化字符串漏洞利用; 满足if条件即可得到答案; 使 nptr 与 dword_804C044 相等即可; 可以使我们利用的是 第一次的输入输出; addr=0x804C044 payl ...
- web buuctf [SUCTF 2019]Pythonginx1
知识点:1.nignx 2.idna编码与utf-8编码的漏洞 1.开题 查看源码,整理代码: @app.route('/getUrl', methods=['GET', 'POST']) def g ...
- buuctf——[第五空间2019 决赛]PWN5 1
查看文件权限 设置了canary,无法栈溢出. F5查看源程序 源程序大意是把随机数放入到bss段的0x804c044处,用户输入用户名和密码,如果密码和随机数相等,则拿到权限. 解题思路 看到了pr ...
- buuctf GWCTF 2019 pyre
下载题目发现是一个pyc文件,关于pyc的详细解释,我看到了这篇文章(6条消息) .pyc是什么?_loveliuzz的博客-CSDN博客_.pyc pyc文件是PyCodeObject的一种持久化保 ...
- BUUCTF Web 第二页全部Write ups
更多笔记,可以关注yym68686.top 目录 [强网杯 2019]高明的黑客 [BUUCTF 2018]Online Tool [RoarCTF 2019]Easy Java [GXYCTF201 ...
- BUUCTF刷题记录(2)
文章目录 web [De1CTF 2019]SSRF Me(未完成) [极客大挑战 2019]PHP [极客大挑战 2019]Knife [极客大挑战 2019]LoveSQL [RoarCTF 20 ...
- BUUCTF持续更新中
目录 [HCTF 2018]WarmUp [强网杯 2019]随便注 [SUCTF 2019]EasySQL [GYCTF2020]Blacklist [GKCTF2020]cve版签到 GXYCTF ...
- buu(ssti模板注入、ssrf服务器请求伪造)
目录 目录 [CISCN2019 华东南赛区]Web11 [BJDCTF2020]EasySearch [De1CTF 2019]SSRF Me [CSCCTF 2019 Qual]FlaskLigh ...
- BUUCTF笔记之Web系列部分WriteUp(四)
1.[BJDCTF2020]Mark loves cat dirb扫描目录发现.git泄露. githack获取源码 <?php$flag = file_get_contents('/flag' ...
最新文章
- 兵团教师计算机水平考试免考条件,兵团职称计算机考试政策.doc
- 【安卓开发 】Android初级开发(十二)Android向系统日历中添加事件
- 信息学奥赛C++语言:的士收费
- Application Constants
- 红帽取代 Oracle,接管 OpenJDK 8 和 OpenJDK 11 | 极客头条
- 高斯正反算 java_高斯投影正反算的代码
- 直觉模糊集的基本要素
- BEC剑桥英语高级真题4 Test 2-Part 2-High fliers of the future head for specialist fairs
- 信息安全保障人员(CISAW)工控网络安全方向认证介绍
- Java 多线程学习(1)一些容易被遗忘的基础概念
- 与或非逻辑运算符用法详解
- C#基于开源地图GMap的开发示例
- python空间数据处理_基于Python的空间数据批量处理方法
- 记录一下http发起请求XHR状态显示(错误:已阻止)的原因
- 389-MySQL数据库代码封装
- 软件测试--MonkeyRunner(3)
- (一)、centos7系统搭建Ethereum
- 计算机毕业设计 校园二手书籍交易系统 基于SSM的校园二手图书交易平台 二手交易网站 校园二手交易网站 校园二手交易平台源码 闲置物品交易系统 网上跳蚤市场 二手图书交易系统 二手书籍交易网站
- opencv学习笔记(1) TermCriteria 和 光流法特征点
- MIT 6.S081 聊聊xv6中的文件系统(上)
热门文章
- 武器装备可视化分析决策系统
- 激战2服务器不稳定,轻松畅快玩游戏 解决激战2掉线方法汇总
- GCC:dereferencing type-punned pointer will break strict-aliasing rules
- R01 - 013、导致HBase挂掉的场景?
- matlab 数据白化,“matlab对Excel表格数据预处理“急求FastICA 的源程序 matlab,包括数据的预处理(中心化和白化),注释详细点,谢谢!...
- 华为首款搭载鸿蒙系统手机,继鸿蒙手机操作系统后,华为宣布将于6月2日同时发布首款鸿蒙平板...
- 动画:用动画给面试官解释 KMP 算法
- UILabel设置字体发光效果
- 敏捷管理(3)- 建立敏捷团队、常见的敏捷问题
- JavaScript动画性能优化