从swpuctf里面的一道ctf题目来讲解secret_key伪造session来进行越权。

以前没有遇到过这种题目,这次遇到了之后查了一些资料把它做了出来,记录一下知识点。

参考资料

 http://northity.com/2018/11/12/HCTF-WEB%E9%83%A8%E5%88%86%E9%A2%98%E8%A7%A3/
https://xz.aliyun.com/t/2589
https://www.anquanke.com/post/id/163974
https://skysec.top/2018/11/12/2018-HCTF-Web-Writeup/

首先我们进行登录,这里没有注册按钮,所以我们随意输入账号密码即可以登录。

我们使用test/test进行登录

可以看到有一个upload模块,进行点击,返回权限不够的提示。

可以猜测这里我们是需要管理员的权限才可以进行文件上传

再查看一下源代码,里面有一个404 not found的提示

于是我们构造一个不存在的页面,使其服务器返回404页面,burpsuite抓包查看

可以看到404界面服务器返回了

swpuctf_csrf_token:U0VDUkVUX0tFWTprZXlxcXF3d3dlZWUhQCMkJV4mKg==

这里的base64编码我们进行解密之后得到是:

SECRET_KEY:keyqqqwwweee!@#$%^&*

解密之后我们得到了secret_key的值,这里验证了我们最开始的结论,正是要伪造管理员的 session 登录之后拥有upload的权限。

对于官方wp,这个地方的绕过是用的另一种方式

我们继续使用刚才的思路进行伪造。

关于session伪造的相关博客:

 https://www.leavesongs.com/PENETRATION/client-session-security.html
https://www.jianshu.com/p/f92311564ad0

python脚本地址:

https://github.com/noraj/flask-session-cookie-manager

这里需要提到的是:我们需要知道服务器后端使用的python版本是2或者是3,因为通过这两个版本进行加密的session解密出来的格式是不一样的。

这里经过测试我们可知后端的python的版本是3.x的

接着我们将自己加密后的session和screct_key放进python脚本里面跑出解密后的session

我们把id改成1,用户名改成admin,其余不变进行session加密

最终得到admin加密之后的session:

eyJpZCI6eyIgYiI6Ik1RPT0ifSwiaXNfbG9naW4iOnRydWUsInBhc3N3b3JkIjoidGVzdCIsInVzZXJuYW1lIjoiYWRtaW4ifQ.XfERxA.nrEW0S_sf4jtSfnfGmHbFnSv07w

点击upload使用burpsuite进行抓包,将Session更换成我们伪造的session,权限符合,进入

upload页面有后端的代码:

@app.route('/upload',methods=['GET','POST'])
def upload():
if session['id'] != b'1':
return render_template_string(temp)
if request.method=='POST':
m = hashlib.md5()
name = session['password']
name = name+'qweqweqwe'
name = name.encode(encoding='utf-8')
m.update(name)
md5_one= m.hexdigest()
n = hashlib.md5()
ip = request.remote_addr
ip = ip.encode(encoding='utf-8')
n.update(ip)
md5_ip = n.hexdigest()
f=request.files['file']
basepath=os.path.dirname(os.path.realpath(__file__))
path = basepath+'/upload/'+md5_ip+'/'+md5_one+'/'+session['username']+"/"
path_base = basepath+'/upload/'+md5_ip+'/'
filename = f.filename
pathname = path+filename
if "zip" != filename.split('.')[-1]:
return 'zip only allowed'
if not os.path.exists(path_base):
try:
os.makedirs(path_base)
except Exception as e:
return 'error'
if not os.path.exists(path):
try:
os.makedirs(path)
except Exception as e:
return 'error'
if not os.path.exists(pathname):
try:
f.save(pathname)
except Exception as e:
return 'error'
try:
cmd = "unzip -n -d "+path+" "+ pathname
if cmd.find('|') != -1 or cmd.find(';') != -1:
waf()
return 'error'
os.system(cmd)
except Exception as e:
return 'error'
unzip_file = zipfile.ZipFile(pathname,'r')
unzip_filename = unzip_file.namelist()[0]
if session['is_login'] != True:
return 'not login'
try:
if unzip_filename.find('/') != -1:
shutil.rmtree(path_base)
os.mkdir(path_base)
return 'error'
image = open(path+unzip_filename, "rb").read()
resp = make_response(image)
resp.headers['Content-Type'] = 'image/png'
return resp
except Exception as e:
shutil.rmtree(path_base)
os.mkdir(path_base)
return 'error'
return render_template('upload.html') @app.route('/showflag')
def showflag():
if True == False:
image = open(os.path.join('./flag/flag.jpg'), "rb").read()
resp = make_response(image)
resp.headers['Content-Type'] = 'image/png'
return resp
else:
return "can't give you"

一个是检测来到upload页面的权限,另外一个是flag所在的位置,即./flag/flag.jpg

所以接下来要做的事情很明确,我们需要将上传的压缩包能够读取服务器端的文件。

这里使用linux里面的软链接达到这个效果,不过我们需要先填入需要读取文件的路径。

我们先使用:

 ln -s /etc/passwd test
zip -y test.zip test

看看能不能读到东西

看出来我们可以使用这种方式读取文件,接下来我们可以看一下/proc/self/environ,能读到uwsgi配置文件

这里跟题目环境不太一样,不懂开发的我确实找不到路径,第二种方法就是在linux中,/proc/self/cwd/会指向进程的当前目录,当我们不知道flask工作目录的时候,我们就使用/proc/self/cwd/flag/flag.jpg来访问flag.jpg

(因为代码里面已经显示了flag.jpg在当前目录下的/flag/flag.jpg这个位置)

上传之后即查询到了flag的值

secret_key伪造session来进行越权的更多相关文章

  1. BUUCTF-[HCTF 2018]admin(Unicode欺骗&伪造session)

    目录 方法一:Unicode欺骗 方法二:伪造session 参考文章 记一道flask下session伪造的题. 方法一:Unicode欺骗 拿到题目f12提示you are not admin,显 ...

  2. spring security防御会话伪造session攻击

    1. 攻击场景 session fixation会话伪造攻击是一个蛮婉转的过程. 比如,当我要是使用session fixation攻击你的时候,首先访问这个网站,网站会创建一个会话,这时我可以把附有 ...

  3. flask利用session身份伪造

    想研究很久了,这次终于初步了解了flask session伪造(得知道密钥). python2和python3 session解密不一样,而且不都是base64,脚本https://github.co ...

  4. [原题复现]2018HCTF WEB admin(session伪造、unicode漏洞、条件竞争)

    简介  原题复现:https://github.com/woadsl1234/HCTF2018_admin  考察知识点:session伪造.unicode漏洞.条件竞争  线上平台:https:// ...

  5. session安全&&CBC字符反转攻击&&hash拓展攻击

    session安全 p神写的: 在传统PHP开发中,$_SESSION变量的内容默认会被保存在服务端的一个文件中,通过一个叫"PHPSESSID"的Cookie来区分用户.这类se ...

  6. session的安全性

    提到session,大家肯定会联想到登录,登录成功后记录登录状态,同时标记当前登录用户是谁.功能大体上就是这个样子,但是今天要讲的不是功能,而是实现.通过探讨session的实现方式来发掘一些可能你之 ...

  7. Session 类

     Session 类 Session 类可以使用户在浏览您的网站时,维持他们的状态并跟踪他们的行为. Session 类将每个用户的 session 信息序列化(serialize)后存储到到 coo ...

  8. ASP.NET 之深入浅出Session和Cookie

    在做人事档案管理系统中,对于Session和Cookie的使用后理解更加深刻了,下面对本知识点总结学习. Session是什么? 简单来说就是服务器给客户端的一个编号.当一台WWW服务器运行时,可能有 ...

  9. 彻底理解cookie,session,token

    发展史 1.很久很久以前,Web 基本上就是文档的浏览而已, 既然是浏览,作为服务器, 不需要记录谁在某一段时间里都浏览了什么文档,每次请求都是一个新的HTTP协议, 就是请求加响应,  尤其是我不用 ...

随机推荐

  1. asp.net利用SmtpClient发送邮件

    using System; using System.Data; using System.Web.UI; using System.Data.OracleClient; using DBUtilit ...

  2. 这些C++基础知识的基础知识你都学会了吗?

    一.C++基础知识 新的数据类型 C语言中的数据类型  C++中新的数据类型 思考:新的数据类型有什么好处?请看下面的代码:  可以见得:新的类型使整个程序更加简洁,程序变得易读易懂!这个就是bool ...

  3. jquery实现回车键执行ajax

    $('#txtKey').bind('keypress',function(event){ if(event.keyCode == "13") { alert(1) }});

  4. MySQL全面瓦解11:子查询和组合查询

    概述 子查询是SQL查询中的重要一块,是我们基于多表之间进行数据聚合和判断的一种手段,使得我们的处理复杂数据更加的便捷,这一节我们主要来了解一下子查询. 先做一下数据准备,这边建立三张表:班级.学生. ...

  5. nginx&http 第五章 https non-fd 读写检测

    EPOLL的LT/ET 模式下的读写 从一个非阻塞的socket上调用recv/send函数, 返回EAGAIN或者EWOULDBLOCK(注: EAGAIN就是EWOULDBLOCK)从字面上看, ...

  6. binary hacks读数笔记(ld 链接讲解 一)

    首先我们先看两段代码: a.c extern int shared; int main(){ int a=100; swap(&a,&shared); } b.c int shared ...

  7. 再聊 Blazor,它是否值得你花时间学习

    之前写了一篇文章<快速了解 ASP.NET Core Blazor>,大家关心最多的问题是,我该不该花时间去学习 Blazor.今天聊聊这个话题,并表达一下我个人的看法. 在此之前,我还是 ...

  8. 'sortbitwise'是什么意思

    问题 flag sortbitwise 在ceph中是什么意思,在Jewel版本下可以看到多了这个flags [root@lab8106 current]# ceph -s cluster ffe7a ...

  9. Function(函数分享)第二节

    一.类型注解 1.1 类型注解 函数的类型注解分为两个部分:参数类型注解和返回值类型注解.其中返回值类型注解有时候我们可以直接省略,因为Typescript可以根据返回的语句来自动判断出返回值的类型. ...

  10. Caused by: java.lang.ClassNotFoundException: com.alibaba.druid.filter.logging.Log4j2Filter

    最开始遇到这个错误,百度,网上一堆的清一色解决方案,缺少log4j,引入log4j相关依赖,或者引入slf4j-over-log4j的依赖,但是好像都不行,最后还是谷歌靠谱,直接检索出github上的 ...