session安全

p神写的:

在传统PHP开发中,$_SESSION变量的内容默认会被保存在服务端的一个文件中,通过一个叫“PHPSESSID”的Cookie来区分用户。这类session是“服务端session”,用户看到的只是session的名称(一个随机字符串),其内容保存在服务端。

然而,并不是所有语言都有默认的session存储机制,也不是任何情况下我们都可以向服务器写入文件。所以,很多Web框架都会另辟蹊径,比如Django默认将session存储在数据库中,而对于flask这里并不包含数据库操作的框架,就只能将session存储在cookie中。

所以这可能造成session的篡改,在 flask 中使用 session 很简单,只要使用 from flask import session 导入这个变量,在代码中就能直接通过读写它和 session 交互。

    val = self.get_signing_serializer(app).dumps(dict(session))
response.set_cookie(app.session_cookie_name, val,
expires=expires, httponly=httponly,
domain=domain, path=path, secure=secure)

倒数第二步,用它的dumps方法将类型为字典的session对象序列化成字符串 最后一步用response.set_cookie将最后的内容保存在cookie中。 详细参数:

key: cookie的name
value:cookie的值
expires:具体过期时间
path:cookie的访问路径,只有在某个路径下访问
domain:域名,只有在某个域名下访问
secure:安全
httpoly:如果为True那么js就不能获取cookie

伪造代码:

# coding:utf8

import uuid
from flask import Flask, request, make_response, session,render_template, url_for, redirect, render_template_string app = Flask(__name__)
app.config['SECRET_KEY']=str(uuid.uuid4()) @app.route('/')
def index():
app.logger.info(request.cookies) try:
username=session['username']
return render_template("index.html",username=username)
except Exception,e: return """<form action="%s" method='post'>
<input type="text" name="username" required>
<input type="password" name="password" required>
<input type="submit" value="登录">
</form>""" %url_for("login") @app.route("/login/", methods=['POST'])
def login():
username = request.form.get("username")
password = request.form.get("password")
app.logger.info(username)
if username.strip():
if username=="admin" and password!=str(uuid.uuid4()):
return "login failed"
app.logger.info(url_for('index'))
resp = make_response(redirect(url_for("index")))
session['username']=username
return resp
else:
return "login failed" @app.errorhandler(404)
def page_not_found(e):
template='''
{%% block body %%}
<div class="center-content error">
<h1>Oops! That page doesn't exist.</h1>
<h3>%s</h3>
</div>
{%% endblock %%}
'''%(request.url)
return render_template_string(template),404 @app.route("/logout")
def logout():
resp = make_response(redirect(url_for("index")))
session.pop('username')
return resp if __name__ == "__main__":
app.run(host="0.0.0.0", port=9999, debug=True)

知道秘钥之后我们利用工具就可以得到解密后的数据,也可以构造加密的数据。

C:\Users\Dell\Desktop\工具集\各种编码解密\flask-session-cookie-manager-master>python flask_session_cookie_manager2.py encode -s "a8bc2e85-d7a8-32f0-a56d-a86b19b42bb6" -t "{u'user': u'test' }"
eyJ1c2VyIjoidGVzdCJ9.XuRKWA.fs0nWIciQE_YTQ1hduVsrYWCoUg

利用hackerbar进行session的替换。

关于序列化session的主要过程:

json.dumps 将对象转换成json字符串,作为数据
如果数据压缩后长度更短,则用zlib库进行压缩
将数据用base64编码
通过hmac算法计算数据的签名,将签名附在数据后,用“.”分割

目标网站通过session来储存随机token并认证用户是否真的在邮箱收到了这个token。但因为flask的session是存储在cookie中且仅签名而未加密,所以我们就可以直接读取这个token了。

参考文章:https://www.leavesongs.com/PENETRATION/client-session-security.html

签名使用hash函数而非hmac函数,导致利用hash长度扩展攻击来伪造session
任意文件读取导致密钥泄露,进一步造成身份伪造漏洞或反序列化漏洞( http://www.loner.fm/drops/#!/drops/227.Codeigniter%20%E5%88%A9%E7%94%A8%E5%8A%A0%E5%AF%86Key%EF%BC%88%E5%AF%86%E9%92%A5%EF%BC%89%E7%9A%84%E5%AF%B9%E8%B1%A1%E6%B3%A8%E5%85%A5%E6%BC%8F%E6%B4%9E )
如果客户端session仅加密未签名,利用CBC字节翻转攻击,我们可以修改加密session中某部分数据,来达到身份伪造的目的

CBC字节翻转攻击

cbc是AES加密的cbc模式 即密码分组链模式: 先将铭文切分成若干小段,然后每一小段与初始块或者上一段的密文段进行异或运算后,在于密钥进行加密。


明文以16个字节为一组进行分组,给出初始化向量iv于明文进行异或然后利用密钥key在进行加密得到密文a,密文a就相当于下一段明文的初始化向量,以此类推。

解密的具体步骤:

首先从最终的密文中提取出IV (IV为加密时指定的X位)
将密文分组
使用密钥对第一组密文解密得到密文A,然后用IV进行异或得到第一组明文
使用密钥对第二组密文解密得到密文B,然后用A与B进行异或得到第二组明文

怎么加密的,就怎么解密,我们可以控制解密时所生成的明文,从而产生攻击,因为在无参数rce的时候,p神就曾经介绍过一种弄利用异或来生成一句话木马的操作,我想这是有异曲同工之妙的,详细的可以去了解一下异或生成的过程,就是二进制的变换罢了,解密的过程就是利用两段加密的去推到出明文,因为你明文是跟一段密文的一起异或生成另一段密文的,即C与B 异或得到A, 即 C ^ B = A。

A=ciphertext(N-1),B=plaintext(N),C为第N块待异或且经过解密的字符,C'为我们经过翻转要得到的明文。

明文原文为C,要更改为C';上一组密文原文为A,要更改为A';密文解密后和上一组密文异或前的中间数据为M
可以得到:

A = B ^ C

C = A ^ B

A ^ B ^ C = 0

A ^ B ^ C ^ C' = C'

根据关系式可以得到 A' = A ^ C ^ C'

这就是我们进行CBC字节翻转的公式

此时我们已经将我们想要构造出的明文能够通过对上一段的密文的修改构造出来了,但是我们这前一段密文修改之后,很明显,之前的一段密文发生了改变,那么前一段明文会被全部变动掉,我们需要新生成一段密文,让他能够照常的经过解密生成原来的明文,这就是我们要干的第二件事。

这样我们以第一段为例,能够让第一段保持原来的密文,同时保证第二段能正确翻转,我们的可控汴梁旧事一概是直接设的vi明文,队名问津新修改就能完全的进行改变。

公式: C' = C ⊕ A ⊕ A'

C为原文明文,C'为要新生成的明文,A为改变后乱码的明文,A'为原来最初的明文。

参考链接:https://www.cnblogs.com/s1ye/p/9021202.html

先嫖个脚本:

#-*- coding:utf8 -*-
import base64
import urllib
# a:2:{s:8:"userna
# me";s:5:"admiN";
# s:8:"password";s
# :6:"123456";} def Module1():
ciphertext = raw_input("Please input the first round cipher:\n")
cipher = base64.b64decode(urllib.unquote(ciphertext))
new_cipher = cipher[:13] + chr(ord(cipher[13]) ^ ord('N') ^ ord('n')) + cipher[14:]
print urllib.unquote(base64.b64encode(new_cipher)) def Module2():
errorcipher = base64.b64decode(urllib.unquote(raw_input('Please input errorcipher: \n')))
ivtext = raw_input("Please input iv:\n")
iv = base64.b64decode(urllib.unquote(ivtext))
cleartext = 'a:2:{s:8:"userna'
newiv = ''
for i in range(16):
newiv += chr(ord(iv[i]) ^ ord(errorcipher[i]) ^ ord(cleartext[i]))
print urllib.unquote(base64.b64encode(newiv)) option = raw_input("Please input option [1 or 2]:")
if option == '1':
Module1()
elif option == '2':
Module2()
else:
pass

hash拓展攻击

关于md5:

1   MD5加密过程中512比特(64字节)为一组,属于分组加密,而且在运算的过程中,将512比特分为32bit*16块,分块运算
2 每一块加密得到的密文作为下一次加密的初始向量IV
3 MD5的填充:加密的字符串进行填充(比特第一位为1其余比特为0),使之(二进制)补到448模512同余,即长度为512的倍数减64,最后的64位在补充为原来字符串的长度,这样刚好补满512位的倍数,如果当前明文正好是512bit倍数则再加上一个512bit的一组。

先看一下补足的运算:

0x23478a696e**800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000**2800000000000000

这一段加粗的就是用来补足的,即二进制补位100000.... 第三部分就是全部要加密明文的长度,并不包含他自动填充的长度。

进行完补足之后,如果我们还有第二段的数据,那么接下来要进行的操作就是先将第一段构成为初始的IV为第二部分的操作做准备,因为第一部分算出来的ABCD是会被拿来算第二部分的值。:

A = 0x67542301;
B = 0xEFCDAB89;
C = 0x98BADCFE;
D = 0x10325476;

原理是:原理就是有ABCD四个初始渐变量,还有上面的信息,每次都拿512bit的信息去计算,然后多次计算以后变量不停被覆盖,最后计算出的变量接在一起,再高低位互换得到最终的加密结果。

此时我们在第一段后面进行手动的补足,然后添加我们新一段的数据,这样才可以添加第二段。

我们在第二段中填入自己想填入的字符进行操作。

关于md5存储的运算:

假设我们存储了有一块:0x12233445那么MD5运算时候存储的顺序是0x54433221这个样子的,另外一个字节的长度是8bit。

那么关于Hash长度扩展攻击有是如何操作的: 实验吧的一道题目,用来理解一下

在这里我们知道了第一部分的hex的值,知道了所有具体的长度,我们完全可以进行填充,,利用hashpump或者是extender计算出拓展的值,放入到getmein的cookie变量提交,进行对比从而绕过题目上的两个限制。

参考链接:

https://www.cnblogs.com/p0pl4r/p/10317593.html

https://blog.csdn.net/qq_35078631/article/details/70941204

session安全&&CBC字符反转攻击&&hash拓展攻击的更多相关文章

  1. CBC 字节反转攻击

    一.CBC 简介 现代密码体制 现代密码中的加密体制一般分为对称加密体制(Symmetric Key Encryption)和非对称加密体制(Asymmetric Key Encryption).对称 ...

  2. 实验吧之【简单的登录题(】CBC字节反转攻击)

    开始刷ctf题吧  慢慢来. 实验吧---简单的登录题 题目地址:http://ctf5.shiyanbar.com/web/jiandan/index.php 随便提交一个id,看到后台set了两个 ...

  3. 浅谈HASH长度拓展攻击

    前言 最近在做CTF题的时候遇到这个考点,想起来自己之前在做实验吧的入门CTF题的时候遇到过这个点,当时觉得难如看天书一般,现在回头望去,仔细琢磨一番感觉也不是那么难,这里就写篇文章记录一下自己的学习 ...

  4. MD5加密及Hash长度拓展攻击【通俗易懂】

    先放一个简单点的利用了Hash长度拓展攻击的题目 if($COOKIE["getmein"] === md5($secret . urldecode($username . $pa ...

  5. 实验吧_天下武功唯快不破&让我进去(哈希长度拓展攻击)

    天下武功唯快不破 第一反应就去抓包,看到返回包的header中有FLAG的值,base64解码后得到下图所示 这就要求我们在请求头中post相应key的值,我直接在burp中尝试了多次都没有用,想起来 ...

  6. 哈希长度拓展攻击之De1CTF - SSRF Me

    题目考查:python代码审计.hash长度拓展攻击 0x01 题目源码: #! /usr/bin/env python #encoding=utf-8 from flask import Flask ...

  7. HashMap出现Hash DOS攻击的问题

    随着RESTful风格的接口普及,程序员默认都会使用json作为数据传递的方式.json格式的数据冗余少,兼容性高,从提出到现在已被广泛的使用,可以说成为了Web的一种标准.无论我们服务端使用什么语言 ...

  8. PtH(hash传递攻击)原理探秘

    背景知识 Windows 横向渗透的两种方式 1.hash传递攻击,通过传递NTLM-Hash,登录机器,简称PtH: 2.ticket传递攻击,通过传递kerberos的ticket,登录机器,简称 ...

  9. hash扩展攻击本地实验

    记录一下自己对hash扩展攻击的一些理解,hash扩展攻击主要应用于身份认证,比如对于成功登录的用户可以赋予其一个采用hsah算法加密的cookie值,其中含有未知的密钥. 此后每次在服务器端验证此c ...

随机推荐

  1. Python的pyttsx3安装失败的解决方案

    尝试更新安装工具,然后重试安装: pip install -U setuptools pip install pyttsx3 如果仍不能解决您的问题,您也可以尝试指定pyttsx3的版本 pip in ...

  2. 算法-搜索(5)m路搜索树

    动态m路搜索树即系统运行时可以动态调整保持较高搜索效率的最多m路的搜索树.以3路搜索树为例说明其关键码排序关系:   const int MaxValue=; template <class T ...

  3. 四则运算生成命令行程序 (Python)

    Github项目地址:Github Pages 结对项目成员:张鹏 3118004985 郑靓 3118004988 一.项目需求分析 二.功能实现 三.代码实现or功能说明 ★ GUI功能扩展说明 ...

  4. springboot的常用注解

    1. @SpringBootApplication2. @Repository3. @Service4. @RestController5. @Controller6. @Component7. @R ...

  5. Java面试题(Java Web篇)

    Java Web 64.jsp 和 servlet 有什么区别? jsp经编译后就变成了Servlet.(JSP的本质就是Servlet,JVM只能识别java的类,不能识别JSP的代码,Web容器将 ...

  6. TCP/IP网络编程之socket交互流程

    一.概要 本篇文章主要讲解基于.net中tcp/ip网络通信编程.在自我进步的过程中记录这些内容,方便自己记忆的同时也希望可以帮助到大家.技术的进步源自于分享和不断的自我突破. 技术交流QQ群:580 ...

  7. python练习 - 文本的平均列数+CSV格式清洗与转换

    文本的平均列数 描述 打印输出附件文件的平均列数,计算方法如下:‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬ ...

  8. redis数据库基础篇

    一.Redis介绍 Redis 是一个高性能的key-value数据格式的内存缓存,NoSQL数据库.NOSQL:not only sql,泛指非关系型数据库.关系型数据库: (mysql, orac ...

  9. 滑动窗口(Sliding Window)技巧总结

    什么是滑动窗口(Sliding Window) The Sliding Problem contains a sliding window which is a sub – list that run ...

  10. ES6--let,解构赋值,promise && ES7--async

    ES-->IE10.Google.火狐 ES6 let 声明的关键字 不能重复声明 块级作用域 <input type="button" value="1&q ...